CSS三角形如何工作?

Sta*_*lin 1791 css geometry polygon css3 css-shapes

CSS Tricks上有很多不同的CSS形状- CSS的形状,我特别对三角形感到困惑:

CSS Triangle

#triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div id="triangle-up"></div>
Run Code Online (Sandbox Code Playgroud)

它是如何以及为什么有效?

sdl*_*rhc 2200

CSS三角形:五幕中的悲剧

正如亚历克斯所说,相等宽度的边界以45度角相互对接:

边界以45度角相交,内容在中间

当您没有顶部边框时,它看起来像这样:

没有顶部边界

然后你给它宽度为0 ......

没有宽度

......高度为0 ......

没有高度

......最后,你让两个边框透明:

透明的边框

这导致了一个三角形.

  • 使用动画:http://jsfiddle.net/pimvdb/mA4Cu/104/.只为我们这些需要更多视觉证据的人... (92认同)
  • @Jauzsika,您可以将这些三角形添加到页面中,而无需使用`:before`或`:after`伪类添加其他元素. (9认同)
  • @zzzzBov:伪元素. (3认同)
  • 在2018年,有没有比CSS更好的方法用CSS制作三角形? (2认同)
  • @Scribblemacher 内联 SVG 可以做到。 (2认同)

ale*_*lex 508

边框使用相交的倾斜边缘(45°角,宽度相等的边框,但更改边框宽度可能会使角度倾斜).

边界的例子

jsFiddle.

通过隐藏某些边框,您可以获得三角效果(如上所示,通过使不同部分的颜色不同).transparent通常用作边缘颜色来实现三角形.


Mou*_*hna 478

从基本方块和边框开始.每个边框都会有不同的颜色,所以我们可以区分它们:

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 200px 200px 200px 200px;
    height: 0px;
    width: 0px;
}
Run Code Online (Sandbox Code Playgroud)

这给你这个:

有四个边框的正方形

但是不需要顶部边框,所以将其宽度设置为0px.现在我们的边界底部200px将使我们的三角形高200px.

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}
Run Code Online (Sandbox Code Playgroud)

我们会得到这个:

正方形的下半部分有四个边框

然后隐藏两个边三角形,将border-color设置为透明.由于顶部边框已被有效删除,我们也可以将border-top-color设置为透明.

.triangle {
    border-color: transparent transparent red transparent;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}
Run Code Online (Sandbox Code Playgroud)

最后我们得到了这个:

三角形底边

  • 很酷,但不是这个_同样的方式?:-) (21认同)
  • -1用于使用具有大量伪像的JPEG.但是+1用于创建一个很好的例子,说明何时不使用我可以链接到未来的JPEG以获得威慑.;) (16认同)
  • "还有另一种方式来绘制..",结果是相同的方式:)但是很好的解释 (5认同)
  • 对不起@hheimbuerger,我通过修复图片搞砸了你的例子.您将来必须链接到[此答案的第2版](http://stackoverflow.com/revisions/7091927/2). (4认同)
  • 为什么不是这里使用的gif? (3认同)

web*_*iki 257

不同的方法:

CSS3三角形与变换旋转

使用这种技术很容易制作三角形.对于那些喜欢看动画解释这种技术如何在这里工作的人来说:

gif动画:如何用变换旋转制作三角形

否则,这里是如何用一个元素制作等腰直角三角形的4个动作(这不是悲剧)的详细解释.

  • 注1:对于非等腰三角形和花哨的东西,你可以看到第4步.
  • 注意2:在以下代码段中,不包括供应商前缀.它们包含在codepen演示中.
  • 注3:以下解释的HTML总是: <div class="tr"></div>

第1:做一个div

简单,只需确保width = 1.41 x height.您可以使用任何技术(参见此处),包括使用百分比和填充底部来保持纵横比并制作响应三角形.在下图中,div具有金黄色边框.

在该div中,插入一个伪元素,并给它100%的父级宽度和高度.伪元素在下图中具有蓝色背景.

用变换roate步骤1制作一个CSS三角形

此时,我们有这个CSS:

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
}

.tr: before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #0079C6;
}
Run Code Online (Sandbox Code Playgroud)

第2步:让我们旋转

首先,最重要的是:定义转换起源.该默认原点是在伪元素的中心,我们需要它的左下角.通过将此CSS添加到伪元素:

transform-origin:0 100%; 要么 transform-origin: left bottom;

现在我们可以将伪元素顺时针旋转45度 transform : rotate(45deg);

使用CSS3创建三角形第2步

此时,我们有这个CSS:

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
}

.tr:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #0079C6;
    transform-origin: 0 100%;        
    transform: rotate(45deg);
}
Run Code Online (Sandbox Code Playgroud)

第3步:隐藏它

要隐藏伪元素的不需要的部分(使用黄色边框溢出div的所有部分),您只需要overflow:hidden;在容器上设置.去掉黄色边框后,你会得到一个三角形!:

DEMO

CSS三角形

CSS:

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
    overflow: hidden;
}

.tr:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0079C6;
    transform-origin: 0 100%;
    transform: rotate(45deg);
}
Run Code Online (Sandbox Code Playgroud)

第四步:进一步......

演示所示,您可以自定义三角形:

  1. 通过玩耍让它们更瘦或更扁平skewX().
  2. 通过使用变换对准和旋转方向使它们指向左,右或任何其他方向.
  3. 一些反思与3D转换属性.
  4. 三角形边框
  5. 将图像放在三角形内
  6. 更多......释放CSS3的力量!

为什么要用这种技术?

  1. 三角形可以很容易地响应.
  2. 你可以制作带边框三角形.
  3. 您可以保持三角形的边界.这意味着只有当光标位于三角形内时,才能触发悬停状态或单击事件.这可以成为像某些情况下非常方便的这一个,每个三角形不能覆盖它的邻国所以每个三角形有它自己的悬停状态.
  4. 你可以做一些像反射一样的奇特效果.
  5. 它将帮助您理解2d和3d变换属性.

为什么不使用这种技术?

  1. 主要缺点是浏览器兼容性,IE9 +支持2d转换属性,因此如果您计划支持IE8,则无法使用此技术.有关详细信息,请参阅CanIuse.对于使用3d变换的一些奇特效果,如反射浏览器支持是IE10 +(有关详细信息,请参阅canIuse).
  2. 你不需要任何响应,一个普通的三角形对你来说很好,那么你应该去寻找这里解释的边框技术:更好的浏览器兼容性和更容易理解感谢这里的惊人的帖子.

  • 值得一提的是,1.41是√2的近似值和你创建的三角形的斜边长度,这就是你需要(至少)宽度的原因. (16认同)
  • 当三角形需要 1px 实心边框时,此方法效果更好。 (2认同)

yun*_*zen 180

这是我为JSFiddle创建的用于演示的动画.

另请参阅下面的代码段.

这是一个由Screencast制作的动画GIF

三角动画GIF

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0', 'margin-top': '120'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];


$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
Run Code Online (Sandbox Code Playgroud)
.border {
    margin: 20px 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)


随机版

/**
 * Randomize array element order in-place.
 * Using Durstenfeld shuffle algorithm.
 */
function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];
transforms = shuffleArray(transforms)



$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
Run Code Online (Sandbox Code Playgroud)
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)


一次性版本

$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
        $(this)
         .animate({'border-top-width': 0            ,
         					 'border-left-width': 30          ,
         					 'border-right-width': 30         ,
         					 'border-bottom-width': 80        ,
         					 'width': 0                       ,
         					 'height': 0                      ,
                   'margin-left': 100,
                   'margin-top': 150,
         					 'borderTopColor': 'transparent',
         					 'borderRightColor': 'transparent',
         					 'borderLeftColor':  'transparent'}, duration)
    }).end()
}(jQuery))
Run Code Online (Sandbox Code Playgroud)
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)


Rai*_*han 49

让我们说我们有以下div:

<div id="triangle" />
Run Code Online (Sandbox Code Playgroud)

现在逐步编辑CSS,这样您就可以清楚地了解周围发生的事情

第1 :JSfiddle链接:

 #triangle {
        background: purple;
        width :150px;
        height:150PX;
        border-left: 50px solid black ;
        border-right: 50px solid black;
        border-bottom: 50px solid black;
        border-top: 50px solid black;
    }
Run Code Online (Sandbox Code Playgroud)

这是一个简单的div.用一个非常简单的CSS.所以外行人可以理解.Div的尺寸为150 x 150像素,边框为50像素.附图:

在此输入图像描述

第2 :JSfiddle链接:

#triangle {
    background: purple;
    width :150px;
    height:150PX;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}
Run Code Online (Sandbox Code Playgroud)

现在我只改变了所有4个边的边框颜色.图像已附加.

在此输入图像描述

STEP:3 JSfiddle Link:

#triangle {
    background: purple;
    width :0;
    height:0;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}
Run Code Online (Sandbox Code Playgroud)

现在我只是将div的高度和宽度从150像素更改为零.图像已附加

在此输入图像描述

第4 步:JSfiddle:

#triangle {
    background: purple;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}
Run Code Online (Sandbox Code Playgroud)

现在我已经使所有边框与底部边框分开.图像附在下面.

在此输入图像描述

第5 :JSfiddle链接:

#triangle {
    background: white;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}
Run Code Online (Sandbox Code Playgroud)

现在我只是将背景颜色更改为白色.图像已附加.

在此输入图像描述

因此我们得到了我们需要的三角形.

  • 为什么第一步要使用Nether Portal? (2认同)

小智 39

而现在完全不同的东西......

不要使用css技巧,不要忘记像html实体一样简单的解决方案:

&#9650;
Run Code Online (Sandbox Code Playgroud)

结果:

请参阅:上下三角形的HTML实体是什么?

  • 我不认为"殴打"在这里是一个恰当的词.该解决方案依赖于字体指标,因此精确定位相当可疑,更不用说您无法控制形状. (2认同)

Dan*_*mms 31

考虑下面的三角形

.triangle {
    border-bottom:15px solid #000;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    width:0;
    height:0;
}
Run Code Online (Sandbox Code Playgroud)

这就是我们给出的:

小三角输出

为什么它出现在这种形状?下图解释了尺寸,请注意15px用于底部边框,10px用于左侧和右侧.

大三角形

通过删除右边界也很容易制作一个直角三角形.

直角三角形


Pse*_*nja 29

更进一步,使用基于此的CSS,我在后面和下一个按钮添加了箭头(是的,我知道它不是100%跨浏览器,但光滑一点也不少).

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
  margin:20px auto;
}

.triangle-down {
  border-bottom:none;
  border-top: 100px solid red;
}

.triangle-left {
  border-left:none;
  border-right: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-right {
  border-right:none;
  border-left: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-after:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid red;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-after-right:after {
  border-right:none;
  border-left: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}

.triangle-before:before {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid blue;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-before-left:before {
  border-left:none;
  border-right: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}
Run Code Online (Sandbox Code Playgroud)
<div class="triangle"></div>
<div class="triangle triangle-down"></div>
<div class="triangle triangle-left"></div>
<div class="triangle triangle-right"></div>

<a class="triangle-before triangle-before-left" href="#">Back</a>
<a class="triangle-after triangle-after-right" href="#">Next</a>
Run Code Online (Sandbox Code Playgroud)

  • 使用:before和:after不是100%支持. (4认同)
  • 不支持Psuedo元素<IE8. (2认同)

lim*_*fil 18

不同的方法.使用线性渐变(对于IE,只有IE 10+).你可以使用任何角度:

.triangle {
    margin: 50px auto;
    width: 100px;
    height: 100px;
/* linear gradient */
    background: -moz-linear-gradient(-45deg,  rgba(255,0,0,0) 0%, rgba(255,0,0,0) 50%, rgba(255,0,0,1) 50%, rgba(255,0,0,1) 100%);
 /* FF3.6+ */
    background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,1)), color-stop(100%,rgba(255,0,0,1)));
 /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Opera 11.10+ */
    background: -ms-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* IE10+ */
    background: linear-gradient(135deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* W3C */;
}
Run Code Online (Sandbox Code Playgroud)
<div class="triangle"></div>
Run Code Online (Sandbox Code Playgroud)

这是jsfiddle


Ali*_*eza 18

好的,这个三角形将被创建,因为元素的边框在HTML和CSS中一起工作的方式...

由于我们通常使用1或2px边框,我们从未注意到边框与相同宽度相互成45°角,如果宽度发生变化,角度程度也会发生变化,运行我在下面创建的CSS代码:

.triangle {
  width: 100px;
  height: 100px;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="triangle">
</div>
Run Code Online (Sandbox Code Playgroud)

然后在下一步中,我们没有任何宽度或高度,如下所示:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="triangle">
</div>
Run Code Online (Sandbox Code Playgroud)

现在我们使左右边框不可见,使我们想要的三角形如下:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="triangle"></div>
Run Code Online (Sandbox Code Playgroud)

如果您不愿意运行代码段来查看步骤,我已经创建了一个图像序列来查看一个图像中的所有步骤:

在此输入图像描述


Ste*_*ide 13

CSS clip-path

这是我觉得这个问题遗漏的事情; clip-path

clip-path 简而言之

具有该clip-path属性的剪切类似于从矩形纸上切割形状(如圆形或五边形).该属性属于" CSS Masking Module Level 1 "规范.该规范指出,"CSS掩蔽为部分或完全隐藏视觉元素的部分提供了两种方法:掩蔽和剪裁".


clip-path将使用元素本身而不是其边框来剪切您在其参数中指定的形状.它使用一个超级简单的基于百分比的坐标系统,这使得编辑非常容易,这意味着你可以在几分钟内拾取并创建奇怪和美妙的形状.


三角形状示例

div {
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  background: red;
  width: 100px;
  height: 100px;
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
Run Code Online (Sandbox Code Playgroud)


下行

它确实有一个主要的缺点,一个是它主要缺乏支持,只是真正被-webkit-浏览器覆盖,并且没有IE支持,只有非常偏见的FireFox.


资源

这里有一些有用的资源和材料,可以帮助您更好地理解clip-path并开始创建自己的资源.


Tom*_*duy 11

这是一个老问题,但我认为值得分享如何使用这种三角形技术创建箭头.

步骤1:

让我们创建2个三角形,对于第二个,我们将使用:after伪类并将其放置在另一个下面:

2个三角形

.arrow{
    width: 0;
    height: 0;
    border-radius: 50px;
    display: inline-block;
    position: relative;
}

    .arrow:after{
        content: "";
        width: 0;
        height: 0;
        position: absolute;
    }


.arrow-up{
     border-left: 50px solid transparent;
     border-right: 50px solid transparent;
     border-bottom: 50px solid #333;
}
    .arrow-up:after{
         top: 5px;
         border-left: 50px solid transparent;
         border-right: 50px solid transparent;
         border-bottom: 50px solid #ccc;
         right: -50px;
    }
Run Code Online (Sandbox Code Playgroud)
<div class="arrow arrow-up"> </div>
Run Code Online (Sandbox Code Playgroud)

第2步

现在我们只需要将第二个三角形的主要边框颜色设置为背景的相同颜色:

在此输入图像描述

.arrow{
    width: 0;
    height: 0;
    border-radius: 50px;
    display: inline-block;
    position: relative;
}

    .arrow:after{
        content: "";
        width: 0;
        height: 0;
        position: absolute;
    }


.arrow-up{
     border-left: 50px solid transparent;
     border-right: 50px solid transparent;
     border-bottom: 50px solid #333;
}
    .arrow-up:after{
         top: 5px;
         border-left: 50px solid transparent;
         border-right: 50px solid transparent;
         border-bottom: 50px solid #fff;
         right: -50px;
    }
Run Code Online (Sandbox Code Playgroud)
<div class="arrow arrow-up"> </div>
Run Code Online (Sandbox Code Playgroud)

摆弄所有箭头:http:
//jsfiddle.net/tomsarduy/r0zksgeu/


vsy*_*ync 9

SASS(SCSS)三角混合

我写这个是为了让它更容易(和DRY)自动生成一个CSS三角形:

// Triangle helper mixin (by Yair Even-Or)
// @param {Direction} $direction - either `top`, `right`, `bottom` or `left`
// @param {Color} $color [currentcolor] - Triangle color
// @param {Length} $size [1em] - Triangle size
@mixin triangle($direction, $color: currentcolor, $size: 1em) {
  $size: $size/2;
  $transparent: rgba($color, 0);
  $opposite: (top:bottom, right:left, left:right, bottom:top);

  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  border: $size solid $transparent;
  border-#{map-get($opposite, $direction)}-color: $color;
  margin-#{$direction}: -$size;
}
Run Code Online (Sandbox Code Playgroud)

用例示例:

span {
  @include triangle(bottom, red, 10px);
}
Run Code Online (Sandbox Code Playgroud)

游乐场页面


重要提示:
如果某些浏览器中的三角形看起来像素化,请尝试使用此处描述的方法之一.


Tem*_*fif 8

几乎所有答案都集中在使用border构建的三角形上,所以我将详细说明该linear-gradient方法(在@lima_fil的答案中开始).

使用像这样的度数值45°将迫使我们尊重特定的比率height/width以获得我们想要的三角形,这将不会响应:

.tri {
  width:100px;
  height:100px;
  background:linear-gradient(45deg, transparent 49.5%,red 50%);
  
  /*To illustrate*/
  border:1px solid;
}
Run Code Online (Sandbox Code Playgroud)
Good one
<div class="tri"></div>
bad one
<div class="tri" style="width:150px"></div>
bad one
<div class="tri" style="height:30px"></div>
Run Code Online (Sandbox Code Playgroud)

而不是这样做,我们应该考虑预定义的方向值,如to bottom,to top等.在这种情况下,我们可以获得任何类型的三角形形状,同时保持其响应.

1)矩形三角形

为了获得这种三角形,我们需要一个线性梯度和对角线方向等to bottom right,to top left,to bottom left

.tri-1,.tri-2 {
  display:inline-block;
  width:100px;
  height:100px;
  background:linear-gradient(to bottom left, transparent 49.5%,red 50%);
  border:1px solid;
  animation:change 2s linear infinite alternate;
}
.tri-2 {
  background:linear-gradient(to top right, transparent 49.5%,red 50%);
  border:none;
}

@keyframes change {
  from {
    width:100px;
    height:100px;
  }
  to {
    height:50px;
    width:180px;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri-1"></div>
<div class="tri-2"></div>
Run Code Online (Sandbox Code Playgroud)

2)等腰三角形

对于这个,我们将需要2个线性渐变,如上所述,每个将采用宽度(或高度)的一半.这就像我们创建第一个三角形的镜像.

.tri {
  display:inline-block;
  width:100px;
  height:100px;
  background-image:
  linear-gradient(to bottom right, transparent 49.5%,red 50%),
  linear-gradient(to bottom left,  transparent 49.5%,red 50%);
  background-size:50.3% 100%; /* I use a value slightly bigger than 50% to avoid having a small gap between both gradient*/
  background-position:left,right;
  background-repeat:no-repeat;
  
  animation:change 2s linear infinite alternate;
}


@keyframes change {
  from {
    width:100px;
    height:100px;
  }
  to {
    height:50px;
    width:180px;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri"></div>
Run Code Online (Sandbox Code Playgroud)

3)等边三角形

这个有点棘手,因为我们需要保持渐变的高度和宽度之间的关系.我们将具有与上面相同的三角形,但是为了将等腰三角形变换为等边三角形,我们将使计算更复杂.

为了方便起见,我们将考虑div的宽度是已知的,并且高度足够大,以便能够在内部绘制三角形(height >= width).

在此输入图像描述

我们有两个梯度g1g2,蓝线的宽度div w,并且每个梯度将具有它(50% w/2)和三角形的各边是前人的精力等于w.绿线是两个梯度的高度,hg我们可以很容易地得到下面的公式:

(w/2)² + hg² = w²---> hg = (sqrt(3)/2) * w--->hg = 0.866 * w

我们可以依靠它calc()来进行计算并获得所需的结果:

.tri {
  --w:100px;
  width:var(--w);
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 49.5%,red 50%),
  linear-gradient(to bottom left,  transparent 49.5%,red 50%);
  background-size:calc(var(--w)/2 + 0.5px)  calc(0.866 * var(--w));
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
Run Code Online (Sandbox Code Playgroud)

另一种方法是控制div的高度并保持渐变的语法:

.tri {
  --w:100px;
  width:var(--w);
  height:calc(0.866 * var(--w));
  display:inline-block;
  background:
   linear-gradient(to bottom right, transparent 49.8%,red 50%) left,
   linear-gradient(to bottom left,  transparent 49.8%,red 50%) right;
  background-size:50.2% 100%;
  background-repeat:no-repeat;
  
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
Run Code Online (Sandbox Code Playgroud)

4)随机三角形

为了获得一个随机三角形,它很容易,因为我们只需要去除每个的50%的条件但是我们应该保持两个条件(两者都应该具有相同的高度,并且两个宽度的总和应该是100%).

.tri-1 {
  width:100px;
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);
  background-size:20% 60%,80% 60%;
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
 
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri-1"></div>
Run Code Online (Sandbox Code Playgroud)

但是如果我们想为每一方定义一个值呢?我们只需要再做一次计算!

在此输入图像描述

让我们定义hg1hg2作为我们的渐变的高度(两者都等于红线)然后wg1wg2我们的渐变(wg1 + wg2 = a)的宽度.我不打算详细说明计算,但最后我们将:

wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)
Run Code Online (Sandbox Code Playgroud)

现在我们已经达到了CSS的极限,即使calc()我们无法实现这一点,所以我们只需要手动收集最终结果并将它们用作固定大小:

.tri {
  --wg1: 20px; 
  --wg2: 60px;
  --hg:30px; 
  width:calc(var(--wg1) + var(--wg2));
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 49.5%,red 50%),
  linear-gradient(to bottom left,  transparent 49.5%,red 50%);

  background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri" ></div>

<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
Run Code Online (Sandbox Code Playgroud)

奖金

我们不应该忘记我们也可以应用旋转和/或倾斜,我们有更多的选择来获得更多的三角形:

.tri {
  --wg1: 20px; 
  --wg2: 60px;
  --hg:30px; 
  width:calc(var(--wg1) + var(--wg2) - 0.5px);
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 49%,red 50%),
  linear-gradient(to bottom left,  transparent 49%,red 50%);

  background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
Run Code Online (Sandbox Code Playgroud)
<div class="tri" ></div>

<div class="tri" style="transform:skewY(25deg)"></div>

<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>


<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;transform:rotate(20deg)" ></div>
Run Code Online (Sandbox Code Playgroud)

当然,我们应该记住SVG解决方案,它在某些情况下更合适:

svg {
 width:100px;
 height:100px;
}

polygon {
  fill:red;
}
Run Code Online (Sandbox Code Playgroud)
<svg viewBox="0 0 100 100"><polygon points="0,100 0,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,23 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="20,60 50,43 80,100" /></svg>
Run Code Online (Sandbox Code Playgroud)


Dan*_*ger 5

如果您想尝试使用border-size,widthheight查看它们如何创建不同的形状,请尝试以下操作:

const sizes = [32, 32, 32, 32];
const triangle = document.getElementById('triangle');

function update({ target }) {
  let index = null;
  
  if (target) {
    index = parseInt(target.id);

    if (!isNaN(index)) {
      sizes[index] = target.value;
    }
  }
  
  window.requestAnimationFrame(() => {
    triangle.style.borderWidth = sizes.map(size => `${ size }px`).join(' ');
    
    if (isNaN(index)) {
      triangle.style[target.id] = `${ target.value }px`;
    }
  });
}

document.querySelectorAll('input').forEach(input => {
  input.oninput = update;
});

update({});
Run Code Online (Sandbox Code Playgroud)
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

#triangle {
    border-style: solid;
    border-color: yellow magenta blue black;
    background: cyan;
    height: 0px;
    width: 0px;
}

#controls {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: white;
  display: flex;
  box-shadow: 0 0 32px rgba(0, 0, 0, .125);
}

#controls > div {
  position: relative;
  width: 25%;
  padding: 8px;
  box-sizing: border-box;
  display: flex;
}

input {
  margin: 0;
  width: 100%;
  position: relative;
}
Run Code Online (Sandbox Code Playgroud)
<div id="triangle" style="border-width: 32px 32px 32px 32px;"></div>

<div id="controls">
  <div><input type="range" min="0" max="128" value="32" id="0" /></div>
  <div><input type="range" min="0" max="128" value="32" id="1" /></div>
  <div><input type="range" min="0" max="128" value="32" id="2" /></div>
  <div><input type="range" min="0" max="128" value="32" id="3" /></div>
  <div><input type="range" min="0" max="128" value="0" id="width" /></div>
  <div><input type="range" min="0" max="128" value="0" id="height" /></div>
</div>
Run Code Online (Sandbox Code Playgroud)