CSS三角形如何工作?



8 Answers

边界使用相交的角度边缘(45°角和等宽边界,但改变边界宽度会使角度偏斜)。

jsFiddle

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

Question

CSS技巧中有很多不同的CSS形状- CSS的形状,我特别困惑于三角形:

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

它如何以及为什么起作用?




不同的方法。 线性渐变(对于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 */;
}
<div class="triangle"></div>

这里是jsfiddle




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

用例示例:

span {
  @include triangle(bottom, red, 10px);
}

游乐场页面

重要的提示:
如果三角形在某些浏览器中看起来像素化 ,请尝试下面介绍的其中一种方法。




这里是另一个小提琴:

.container:after {
    position: absolute;
    right: 0;
    content: "";
    margin-right:-50px;
    margin-bottom: -8px;
    border-width: 25px;
    border-style: solid;
    border-color: transparent transparent transparent #000;
    width: 0;
    height: 0;
    z-index: 10;
    -webkit-transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
    transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
    bottom: 21px;
}
.container {
    float: left;
    margin-top: 100px;
    position: relative;
    width: 150px;
    height: 80px;
    background-color: #000;
}

.containerRed {
    float: left;
    margin-top: 100px;
    position: relative;
    width: 100px;
    height: 80px;
    background-color: red;
}

https://jsfiddle.net/qdhvdb17/




几乎所有的答案都集中在使用边框构建的三角形上,因此我将详细说明线性梯度方法(从@lima_fil的答案开始)。

使用像45°这样的度数值会迫使我们尊重特定的尺寸比例,以获得我们想要的三角形,并且这不会响应:

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

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

1)矩形三角形

为了获得这样的三角形,我们需要一个线性梯度和一个对角线方向,像to bottom rightto top leftto bottom left

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

@keyframes change {
  from {
    width:100px;
    height:100px;
  }
  to {
    height:50px;
    width:180px;
  }
}
<div class="tri-1"></div>
<div class="tri-2"></div>

2)等腰三角形

对于这一个,我们将需要2个像上面那样的线性渐变,每个将占用一半的宽度(或高度)。 这就像我们创建了第一个三角形的镜像。

.tri {
  display:inline-block;
  width:100px;
  height:100px;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);
  background-size:50.9% 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;
  }
}
<div class="tri"></div>

3)等边三角形

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

为了简单起见,我们会考虑我们div的宽度是已知的,并且高度足够大以能够绘制我们的三角形( height >= width )。

我们有两个渐变g1g2 ,蓝线是div的宽度w ,每个渐变将有50%的宽度( w/2 ),并且三角形的每一侧都应该等于w 。 绿线是两个梯度hg的高度,我们可以很容易地获得以下公式:

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

所以我们需要依靠cacl()来完成我们的计算并获得所需的结果:

.tri {
  --w:100px;
  width:var(--w);
  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:calc(var(--w)/2 + 0.5%)  calc(0.866 * var(--w));
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>

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;
  
 
}
<div class="tri-1"></div>

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

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

wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)

现在我们已经达到了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 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);

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

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

奖金

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

.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 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);

  background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
<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>

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

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

polygon {
  fill:red;
}
<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>




不同的方法:

带变换旋转的CSS3三角形

使用这种技术很容易制作三角形。 对于喜欢看动画的人来解释这种技术在这里的工作原理是:

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

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

第1制作一个div

很简单,只要确保width = 1.41 x height 。 您可以使用任何techinque( 请参阅此处 ),包括使用百分比和填充底以保持纵横比并制作响应三角形 。 在下面的图片中,div有一个金黄色的边框。

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

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

现在我们可以通过transform : rotate(45deg);

在这一点上,我们有这个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; 在容器上。 删除黄色边框后,你会得到...... 三角形 ! :

DEMO

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

第4步:继续...

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

  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. 你不需要任何响应,一个简单的三角形对你来说很好,那么你应该去看看这里解释的边界技术:更好的浏览器兼容性和更容易理解,这要归功于这里的精彩帖子。



可以说我们有以下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像素。 附图:

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

现在我只是改变了所有四面的边框颜色。 图像被附上。

STEP: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像素更改为零。 图像被附上

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

现在我已经把所有的边界都从底部边界透明化了。 图片附在下面。

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

现在我只是将背景颜色更改为白色。 图像被附上。

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




好的,这个三角形会因为元素的边界在HTML和CSS中一起工作而被创建...

由于我们通常使用1或2像素边框,所以我们从不会注意到边框与相同宽度的45度角彼此相交 ,并且如果宽度发生变化,角度也会发生变化,请运行我在下面创建的CSS代码:

.triangle {
  width: 100px;
  height: 100px;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

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

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

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

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div class="triangle"></div>

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




考虑下面的三角形

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

这就是我们所得到的:

为什么它以这种形式出现? 下图解释了尺寸,注意15px用于下边框,10px用于左右。

通过去除右边框也可以很容易地制作直角三角形。






Related