题 CSS三角形如何工作?


有很多不同的CSS形状 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;
}
<div id="triangle-up"></div>

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


1637
2017-08-16 03:54


起源


好问题!如果有可能绘制一个等边三角形,那就更令人印象深刻;) - Abel
您可以: jsfiddle.net/wbZet - mskfisher
那个不在的广场怎么样? jsfiddle.net/minitech/sZgaa - Ry-♦
这很简单,将“红色”改为“蓝色”,三角形将为蓝色:-) - Ofer Zelig
我的朋友有一个带解释的页面和一个用它来构建3d对象的应用程序: uselesspickles.com/triangles - Juan Mendes


答案:


CSS三角形:五幕中的悲剧

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

borders meet at 45 degree angles, content in middle

如果没有顶部边框,它看起来像这样:

no top border

那你给它宽度为0 ......

no width

...和0的高度......

no height either

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

transparent side borders

这导致了一个三角形。


2057
2017-08-16 04:11



@Jauzsika,您可以将这些三角形添加到页面中,而无需简单地使用添加其他元素 :before 要么 :after 伪类。 - zzzzBov
@zzzzBov:伪元素。 - BoltClock♦
stackoverflow.com/questions/5623072/... 我认为BoltClock先生指的是什么。 - thirtydot
很好的插图。现在可以用CSS做到吗? - ikdc
用动画做法: jsfiddle.net/pimvdb/mA4Cu/104。只为我们这些需要更多视觉证据的人... - pimvdb


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

Border example

的jsfiddle

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


486
2017-08-16 03:58





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

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 200px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

给你的 这个

square with four borders

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

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

我们会得到的 这个

bottom half of square with four borders

然后隐藏两个边三角形,将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;
}

最后我们得到了 这个

triangular bottom border


437
2017-08-17 11:16



很酷,但不是这个 一样 办法? :-) - Stanislav Shabalin
There's another way to draw ..,结果是相同的方式:)虽然很好的解释 - Hammad Khan
-1用于使用具有大量工件的JPEG。但是+1用于创建一个很好的例子,说明何时不使用JPEG,我可以在将来链接到它以获得威慑。 ;) - Henrik Heimbuerger
为什么不是这里使用的gif? - prusswan
对不起@hheimbuerger,我通过修复图片搞砸了你的例子。你必须链接到 这个答案的第2版 在将来。 - Rory O'Kane


不同的方法:

CSS3三角形 用变换旋转

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

gif animation : how to make a triangle with transform rotate

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

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

步骤1 : 做一个div

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

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

Making a CSS triangle with transform roate step 1

在这一点上,我们有这个 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;
}

第2步 : 让我们轮流吧

首先,最重要的是: 定义变换原点。该 默认来源 在伪元素的中心,我们需要它在左下角。通过添加这个 CSS 到伪元素:

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

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

Creating a triangle with CSS3 step 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);
}

第3步:隐藏它

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

DEMO

CSS triangle

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);
}

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

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

  1. 通过玩它们使它们更薄或更扁平 skewX()
  2. 通过使用变换对准和旋转方向使它们指向左,右或任何其他方向。
  3. 使 一些反思 具有3D变换属性。
  4. 三角形边界
  5. 放一张图片 在三角形内
  6. 更多......释放权力 CSS3

为什么要用这种技术?

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

为什么不使用这种技术?

  1. 主要缺点是 浏览器兼容性,IE9 +支持2d转换属性,因此如果您计划支持IE8,则不能使用此技术。看到 我可以用吗 了解更多信息。对于一些使用3d变换的奇特效果 反思 浏览器支持是IE10 +(参见 我可以用吗 了解更多信息)。
  2. 你不需要任何响应,一个简单的三角形对你来说很好,那么你应该去寻找这里解释的边框技术:更好的浏览器兼容性和更容易理解由于这里的惊人的帖子。

215
2017-07-17 16:30



值得一提的是1.41是√2的近似值和你创建的三角形的斜边长度,这就是你需要(至少)宽度的原因。 - KRyan
我想保持答案简单,但你是对的,应该提到@KRyan - web-tiki
实际上,在尝试使用它时,提一下如何使用不同的宽度 skewX 衍生出来会很有用。 - KRyan
当您需要三角形的1px实线边框时,此方法更有效。 - Roman Losev
哇,那个动画图形。图片的真实例子可以说1000个单词! - Gaurav Ramanan


这是一个 JSFiddle中的动画 我创建了示范。

另请参阅下面的代码段。

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

Animated Gif of Triangle

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))
.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
}
<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>


随机版

/**
 * 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))
.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
}
<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>


一次性版本

$('#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))
.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
}
<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>


157
2017-11-29 11:21





让我们说我们有以下div:

<div id="triangle" />

现在逐步编辑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;
    }

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

enter image description here

第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;
}

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

enter image description here

步骤:3  JSfiddle链接:

#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;
}

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

enter image description here

步骤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;
}

现在我已将所有边框与底部边框分开。图像附在下面。

enter image description here

第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;
}

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

enter image description here

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


40
2018-06-17 06:09





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

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

&#9650;

结果:

看到: 上下三角形的HTML实体是什么?


35
2017-12-01 12:40



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


考虑下面的三角形

.triangle {
    border-bottom:15px solid #000;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    width:0;
    height:0;
}

这就是我们给出的:

Small triangle output

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

Large triangle

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

Right angle triangle


29
2018-03-21 11:20





更进一步,使用基于此的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;

}
<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>


27
2017-12-30 16:56



这怎么不跨浏览器?三角形应该回到IE6。 - chriscauley
使用:before和:after不是100%支持。 - PseudoNinja
不支持Psuedo元素<IE8。 - alex