使用CSS创建具有曲边的等腰锐角三角形

6

我试图使用纯CSS创建一个具有曲线边缘的三角形。

是否可能实现这一点而不会太过头呢?

我在下面添加了一个示例,说明我想要实现的效果(曲线 - 而不是直线)。

acute isosceles triangle with curved edges

到目前为止,我一直在使用以下代码,但它并不完全符合我的要求。

    #inner {
      transform: rotate(45deg);
      -ms-transform: rotate(45deg);
      -webkit-transform: rotate(45deg);
      -o-transform: rotate(45deg);
      -moz-transform: rotate(45deg);
      background-color: silver;
      width: 100px;
      height: 100px;
      top: 20px;
      left: -50px;
      position: relative;
      -moz-border-radius: 20px;
      border-radius: 20px;
    }
    #outer {
      position: absolute;
      width: 70px;
      height: 140px;
      top: 20px;
      left: 50px;
      overflow: hidden;
      border: 1px solid red;
    }
<div id="outer">
  <div id="inner">&nbsp;</div>
</div>


3
朋友,我不是说这是不可能的,但对于像这样复杂的形状,CSS 不是最佳选择。SVG 或图像可能更适合(但尝试一下也没有错:))。 - Harry
1
@Harry:我同意,SVG 似乎非常适合这个。由于某种原因,“边框半径”似乎不太适合这个:L - jbutler483
1
@Ruddy:我并不是说这是不可能的,伙计。即使更复杂的形状也可以通过努力实现,但代价是什么?创建如此复杂的形状需要相当大的努力,将它们定位在所有浏览器、所有缩放级别等位置上看起来相同,而其他方法可以相对较快地实现相同的效果。这就是我想说的全部内容。 - Harry
1
@Harry 哦,我并不是说你所说的不可能。我只是想说这个形状可以很容易地制作出来,只需要对一个相当简单的CSS形状进行大量微调即可。SVG对于这种类型的事情会更好,我同意这一点。 - Ruddy
@Tom 这个需要有中间的三角形吗?还是应该省略掉? - bostero2
显示剩余2条评论
6个回答

4
如何考虑使用 svg 解决方案?

<svg width="200" height="200" viewBox="-2 0 252 212">
  <path fill="rosybrown" d="M125 0 c-81.6 60 -113.3 130 -125 200 c83.3 40 166.6 40 250 0 c-11.7 -70 -43.4 -140 -125 -200" fill="none" stroke-width="2" stroke="black" />
</svg>


1
我知道你迟早会来看看的 :) 我知道 SVG 会是“答案”,只是不知道怎么做 :P - jbutler483

3

这是另一种可能性,不需要使用任何旋转,只需剪切不同的圆形。

.triangle {
    position: relative;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background-color: lightblue;
    overflow: hidden;
}

.triangle div {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 31%;
    left: 16%;
    background-color: lightyellow;
    border-radius: 50%;
    overflow: hidden;
}

.triangle div:after {
    content: "";
    position: absolute;
    width: 100%;
    height: 100%;
    right: 30%;
    background-color: red;
    border-radius: 50%;
}
<div class="triangle">
<div></div>
</div>

浅色只是为了使三角形的构造更加清晰可见。


不错的解决方案!顺便说一下,每个顶点都是相对弧线的中心。 - The Pragmatick

2

解决方案1:使用两个元素

第一个例子不是完美的,但确实回答了你的问题:

.wrapper{
  /*overflow:hidden;*/
  width:0;
  border-top:100px solid transparent;
  border-left:100px solid red;
  position:relative;
  margin:50px;
  transform:rotate(135deg);
  }

.triangle{
  width:20px;
  height:100px;
  background:red;
  border-radius:50%;
  transform:translate(-110px);
  position:absolute;
  top:-100px;
  left:0;
  }
.triangle:after{
  content:"";
  width:100px;
  height:20px;
  background:red;
  border-radius:50%;
  transform:translate(0px);
  position:absolute;
  top:90px;
  left:10px;
  }
.triangle:before{
  content:"";
  width:140px;
  height:20px;
  background:red;
  border-radius:50%;
  transform:rotate(225deg);
  position:absolute;
  top:40px;
  left:-10px;
  }
<div class="wrapper">
   <div class="triangle"></div>
</div>

请注意:这不是等边三角形,更像是等腰三角形,可以进行编辑以得到更好的效果!


解决方案2:使用单个元素

我试图使用单个 div 元素创建此形状,但只能生成三角形的两条边。因此,我推断只使用css需要两个元素

显示三角形的两条边:

div {
  border-left: 100px solid transparent;
  border-bottom: 126px solid blue;
  border-right: 100px solid transparent;
  width: 0;
  border-radius:50%;
  position: relative;
}
div:after,
div:before {
  content: "";
  position: absolute;
  height: 130px;
  width: 20px;
  border-radius: 50%;
  top: -15px;
    background: blue;
}
div:after {  
  left: -50px;
  transform: rotate(40deg);
}
div:before {
  left: 30px;
  transform: rotate(-40deg);
}
<div></div>


我猜测SVG可能是一个更好的选择(注:我不懂SVG,这似乎是@chipChocolate.pys的专业领域)。所以如果只使用“伪效果”,我认为您要使用两个元素(但我希望被证明是错误的!)。使用“单个元素”似乎并不完全正确,但这可能或可能不适合您。


看看我的答案,同样的想法,只是更接近最终的外观。 - Ruddy

2

纯CSS

使用不同的变换方式。

我使用transform: rotate(30deg);transform-origin: 0% 100%;创建了三个扇区,然后对它们的父容器进行变换(scaleX: -1;用于左侧)。完成。

这可以只使用一对#cont#circ元素完成,但我使用不同的标签只是为了更好地演示。

#cont {
    height: 300px;
    width: 300px;
    overflow: hidden;
    position:relative;
}
#circ {
    height: 300px;
    width: 300px;
    background: black;
    border-radius: 0 300px 0 0;
    transform: rotate(30deg);
    transform-origin: 0% 100%;
}
#cont:nth-of-type(2){
    top: -300px;
    transform: scaleX(-1);
}
#cont:nth-of-type(3){
    top: -600px;
    transform: rotate(30deg);
    transform-origin: 0% 100%;
}
#cont:nth-of-type(3) > #circ {
    border-radius: 0 0 300px 0;
    transform-origin: 0% 0%;
}
<div id="cont">
    <div id="circ">
    </div>
</div>
<div id="cont">
    <div id="circ">
    </div>
</div>
<div id="cont">
    <div id="circ">
    </div>
</div>

注意:对于真实的网站,几乎总是使用SVG。但使用CSS创建形状是一门不应该被淘汰的艺术。


1

这是我的尝试。我认为这是最好的方法,使用1个元素和:before:after

使用div作为基本元素(底部),我们可以将另外两个元素与之对齐,保持大小和形状相等。

div {
  width: 120px;
  height: 60px;
  background: red;
  border-radius: 50%;
  position: relative;
  margin: 100px;
}
div:before, div:after {
  content: "";
  display: block;
  background: red;
  border-radius: 50%;
  position: absolute;
  width: 60px;
  height: 120px;
  top: -70px;
}
div:before {
  transform: rotate(30deg);
  left: 8px;
}
div:after {
  transform: rotate(-30deg);
  right: 8px;
}
<div></div>


编辑:

第二次尝试,在第一次的基础上稍作调整。

div {
  width: 100px;
  height: 50px;
  background: red;
  border-radius: 50%;
  position: absolute;
  top: 10px;
  left: 70px;
  margin: 100px;
}
div:before,
div:after {
  content: "";
  display: block;
  background: red;
  border-radius: 50%;
  position: absolute;
  width: 36px;
  height: 106px;
  top: -65px;
}
div:before {
  transform: rotate(28deg);
  left: 8px;
  border-right: 10px solid red;
}
div:after {
  transform: rotate(-28deg);
  right: 8px;
  border-left: 9px solid red;
}
<div></div>


感谢您的努力,尽管它还不完全符合 OP 的需求。 - Harry

0

我喜欢挑战 :)

最近我开始喜欢更复杂的边框半径变化。我相信通过一些更多的调整和合理的数学计算,你可以消除不同边缘相遇处的粗糙边缘。可惜现在没有时间。

.triangle {
  position: absolute;
  top: 100px;
  left: 100px;
  border-left: 25px solid transparent;
  border-bottom: 40px solid blue;
  border-right: 25px solid transparent;
  width: 0;
  border-bottom-right-radius: 80px 70px;
  border-bottom-left-radius: 0 0;
  transform: rotate(160deg);
}
.triangle:after {
  content: '';
  position: absolute;
  border-left: 25px solid transparent;
  border-bottom: 40px solid CornflowerBlue;
  border-right: 25px solid transparent;
  width: 0;
  left: -54px;
  top: -12px;
  border-bottom-right-radius: 80px 70px;
  border-bottom-left-radius: 0 0;
  transform: rotate(120deg);
}
.triangle:before {
  content: '';
  position: absolute;
  border-left: 25px solid transparent;
  border-bottom: 40px solid darkblue;
  border-right: 25px solid transparent;
  width: 0;
  top: -30px;
  left: -29px;
  border-bottom-right-radius: 80px 70px;
  border-bottom-left-radius: 0 0;
  transform: rotate(240deg);
}
<div class="triangle"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接