纯 CSS 图形的三种实现方式
这是本系列的第 22 集,探讨了现代 CSS 解决方案如何解决我过去 13 年多前端开发经验中遇到的问题。访问ModernCSS.dev即可查看完整系列及其他资源。
现代 CSS 和现代浏览器支持为我们提供了三种创建纯粹、基础 CSS 图形的绝佳方法。在本教程中,我们将探讨如何使用以下方法创建 CSS 三角形:
- 边界
- 线性梯度
clip-path
方法一:边框
这是我学到的第一个创建 CSS 三角形的技巧,至今仍然是一个可靠的备用方法。
对于宽度和高度均为零的元素,任何给定的值都会border直接相交,并且这是元素存在的唯一可见标志。我们可以利用这种交点来创建三角形形状。
为了说明其工作原理,我们将为每一边设置不同的边框颜色:
.triangle {
border: 10px solid blue;
border-right-color: red;
border-bottom-color: black;
border-left-color: green;
}
由此得出以下结果,从中可以看出我们实际上已经得到了 4 个三角形:
为了将其创建为一个单独的三角形,我们首先要确定三角形的指向。例如,如果我们希望它指向右侧,类似于“播放”图标,则需要保持左侧边框可见。然后,我们将其他边框的颜色设置为transparent,如下所示:
.triangle {
border: 10px solid transparent;
border-left-color: blue;
}
在下面的演示图片中,我添加了红色区域outline以显示边界框,这样我们就可以讨论一些改进方案。
我们可以做的一项改进是移除右边框的宽度,以避免将其计入元素的总宽度。我们还可以设置不同的顶部和底部值来拉长三角形的视觉效果。以下是一种简洁的实现方法:
.triangle {
border-style: solid;
border-color: transparent;
/* top | right | bottom | left */
border-width: 7px 0 7px 10px;
border-left-color: blue;
}
如下图所示,我们首先添加一个实心透明边框。然后,我们调整边框宽度,使上下边框小于左侧边框,从而调整宽高比,渲染出一个细长的三角形。
因此,要使三角形指向不同的方向,例如向上,我们只需重新排列这些值,使底部边框获得颜色值,顶部边框设置为零:
.triangle {
border-style: solid;
border-color: transparent;
/* top | right | bottom | left */
border-width: 0 7px 10px 7px;
border-bottom-color: blue;
}
导致:
边框对于三角形非常有效,但如果不引入更多元素,就很难扩展到其他形状。这时,我们接下来要介绍的两种方法就派上用场了。
方法二:linear-gradient
CSS渐变是以background-image值的形式创建的。
首先,让我们来设定一下背景,定义盒子尺寸并防止background-repeat:
.triangle {
width: 8em;
height: 10em;
background-repeat: no-repeat;
/* Optional - helping us see the bounding box */
outline: 1px solid red;
}
接下来,我们将添加第一个渐变。这将使元素的一半看起来像是被涂成了蓝色,因为我们在蓝色和透明值之间创建了一个 50% 的硬分界线。
background-image: linear-gradient(45deg, blue 50%, rgba(255,255,255,0) 50%);
现在,如果我们的元素是正方形的,这看起来就像是从对角切开一样,但我们最终想要的是一个与之前略有不同的宽高比。
我们的目标是创建一个与使用边框方法时外观相同的三角形。为此,我们需要调整 `and`background-size和 ` background-positionvalues` 的值。
首先需要修改的是background-size。简写中,第一个值代表宽度,第二个值代表高度。我们希望三角形的宽度为 100%,高度为 50%,因此需要添加以下代码:
background-size: 100% 50%;
在之前linear-gradient设置不变的情况下,结果如下:
由于45deg渐变角度的问题,形状看起来有点奇怪。我们需要调整角度,使三角形的顶边看起来像是从左上角切到边界框右侧的中间位置。
我数学不太好,所以用开发者工具做了一些实验才找到正确的值 😉
将值更新linear-gradient为以下内容:
linear-gradient(32deg, blue 50%, rgba(255,255,255,0) 50%);
这就是我们目前的进展——虽然从技术上讲它是一个三角形,但还不是我们想要的完整形状:
虽然对于边框技巧,我们必须依靠交点来创建形状,但对于linear-gradient我们需要利用添加多个背景的功能来叠加效果并实现完整三角形的功能,我们必须利用这些功能。
因此,我们将复制该图像linear-gradient,并更新其角度值,使其成为第一个图像的镜像,因为它将位于第一个图像的下方。完整的定义如下background-image:
background-image:
linear-gradient(32deg, blue 50%, rgba(255,255,255,0) 50%),
linear-gradient(148deg, blue 50%, rgba(255,255,255,0) 50%);
但是——我们还没有完全完成这个效果,从进度图中可以看出:
重叠的原因在于两个渐变的默认位置相同0 0——也就是所谓的“重叠” top left。这对于我们最初的渐变来说没问题,但我们需要调整第二个渐变。
为此,我们需要设置多个值background-position。这些值的顺序与以下顺序相同background-image:
background-position: top left, bottom left;
现在我们得到了想要的结果:
这种方法的缺点是,如果不重新计算角度,就很难更改纵横比。
然而,CSS渐变可以用来创建更多形状,尤其因为它们可以分层以创造效果。
想要学习如何使用 CSS 渐变来创建形状和完整的插图,请查看Lynn Fisher 的《A Single Div》一书。
方法三:clip-path
最后一种方法最为精简且最具可扩展性。目前其支持力度稍显不足,因此请务必查看我们的分析数据,以确定这是否是一个可接受的解决方案。
这是我们元素的起点,即盒子尺寸和一个background-color:
.triangle {
width: 16px;
height: 20px;
background-color: blue;
}
其概念clip-path是,您可以使用它来绘制多边形(或圆形、椭圆形)并将其放置在元素内。元素外部的任何区域clip-path实际上都不会被浏览器绘制,从而将外观“裁剪”到元素的边界内clip-path。
为了更清楚地说明这一点,并生成您想要的
clip-path定义,请查看在线生成器:Clippy
这种语法可能比较难掌握,所以我强烈建议使用上面提到的生成器来创建路径。
就我们的目的而言,这里有一个指向右侧的三角形:
clip-path: polygon(0 0, 0% 100%, 100% 50%);
使用clip-path,您可以为沿路径放置的每个点定义坐标。因此,在本例中,我们有一个位于左上角 ( 0 0)、左下角 ( 0% 100%) 和右中心 ( 100% 50%) 的点。
以下是我们的结果:
虽然clip-path它对多种形状都非常灵活,而且由于可以适应任何边界框或宽高比,因此也是最具可扩展性的,但也有一些需要注意的地方。
我之前提到过浏览器不会在边界框之外绘制任何内容,这包括边框、box-shadow元素和样式outline。这些元素不会重新绘制以适应裁剪后的形状。这可能是一个陷阱,需要添加额外的元素或将效果移至父元素才能弥补丢失的效果。
这里有一段 Colby Fayock 制作的专家级视频,可以帮助你更好地理解
clip-path以及如何恢复类似效果。box-shadow
演示
此演示展示了我们创建 CSS 三角形的三种方法,该三角形使用视口单位添加到每个元素中::after,从而实现响应式设计。









