纯粹的CSS形状的3种方式(附代码示例)

166 阅读7分钟

现代CSS--以及现代浏览器的支持--为我们提供了三种优秀的方法来创建纯粹的、基本的CSS形状。在本教程中,我们将研究如何使用以下方法来创建CSS三角形:

  • 边界
  • 线性渐变
  • clip-path

方法1:边框#

这是我学会的第一个创建CSS三角形的技巧,现在仍然是一个可靠的备用方法。

给定一个零宽度和零高度的元素,提供的任何数值border ,直接相交,是元素的唯一可见指示。这个相交点是我们可以利用的,以创建一个三角形的形状。

为了说明这一点,我们将为每条边提供一个不同的边框颜色:

.triangle {
  border: 10px solid blue;
  border-right-color: red;
  border-bottom-color: black;
  border-left-color: green;
}

这就产生了下面的结果,你可以看到我们基本上已经实现了4个三角形的形状:

result of the previously defined CSS rule showing 4 triangles due to the border colors

为了创建一个单一的三角形,我们首先决定我们希望三角形指向哪个方向。所以,如果我们想让它指向右边,类似于 "播放 "图标,我们要保持左边的边界可见。然后,我们将其他边框的颜色设置为transparent ,像这样:

.triangle {
  border: 10px solid transparent;
  border-left-color: blue;
}

在下面的演示图中,我添加了一个红色的outline ,以看到边界框,这样我们可以讨论一些改进。

a blue triangle shape pointing to the right with a red outline to show the bounding box

我们可以做的一个改进是删除右边界的宽度,以防止它被包含在元素的总宽度中。我们还可以为顶部和底部设置唯一的值,以拉长三角形的视觉。这里有一个紧凑的方法来实现这些结果:

.triangle {
  border-style: solid;
  border-color: transparent;
  /* top | right | bottom | left */
  border-width: 7px 0 7px 10px;
  border-left-color: blue;
}

如下面的更新图片所示,我们首先指定一个实心的、透明的边框。然后,我们定义宽度,使顶部和底部的数值小于左侧的数值,以调整长宽比并呈现一个拉长的三角形。

final triangle

因此,如果要将三角形指向不同的方向,比如向上,我们只需将这些值洗一下,使底部边框获得颜色值,而顶部边框被设置为零:

.triangle {
  border-style: solid;
  border-color: transparent;
  /* top | right | bottom | left */
  border-width: 0 7px 10px 7px;
  border-bottom-color: blue;
}

结果是:

demo of the CSS triangle pointing upwards

边框对三角形来说非常有效,但在不涉及更多元素的情况下,边框在这个形状之外就不太容易扩展。这就是我们接下来的两种方法所要解决的问题。

方法二: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%);

现在,如果我们的元素是正方形的,这将会出现角对角的切割,但我们最终想要一个稍微不同的长宽比,就像我们之前做的那样。

progress of adding the first gradient showing a partly blue element but not yet a triangle

我们的目标是创建一个三角形,其外观与使用我们的边框方法时相同。要做到这一点,我们将不得不调整background-sizebackground-position 的值。

第一个调整是改变background-size 。用速记法,第一个值是宽度,第二个是高度。我们希望我们的三角形被允许100%的宽度,但只有50%的高度,所以添加以下内容:

background-size: 100% 50%;

在我们之前的linear-gradient 不变的情况下,这就是结果:

updated triangle resized with background-size showing an odd shape in the upper left of the bounding box

由于45deg 梯度的角度,这个形状显得有点奇怪。我们需要调整角度,使三角形的顶面看起来从左上角切到界线盒右侧的中间。

我不是一个数学向导,所以这需要用DevTools做一些实验来找到正确的值😉。

linear-gradient 值更新为以下内容:

linear-gradient(32deg, blue 50%, rgba(255,255,255,0) 50%);

这是我们的进展--虽然技术上是一个三角形,但还没有达到我们想要的完整外观。

progress of completing one side of the triangle

虽然对于边界技巧,我们必须依靠相交来创建形状,但对于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%);

但是--我们仍然没有完全完成这个效果,从进度图中可以看出。

the second linear-gradient triangle is overlapping the first

重叠的原因是两个渐变的默认位置都是0 0 - 也就是top left 。这对我们的原始渐变来说很好,但我们需要调整第二个渐变。

要做到这一点,我们需要在background-position 上设置多个值。这些值的顺序与background-image 相同:

background-position: top left, bottom left;

现在我们得到了我们想要的结果:

final triangle created with CSS gradients

这种方法的缺点是,它对改变长宽比而不重新计算度数相当不灵活。

然而,CSS渐变可以用来创建更多的形状,特别是由于它们可以分层来创建效果。

方法三: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%)都有一个点。

这就是我们的结果:

completed triangle using clip-path

虽然clip-path 对于许多形状来说是非常灵活的,而且由于适应任何边界框或长宽比,也是最可扩展的,但也有一些注意事项。

当我提到浏览器不会绘制边界框外的任何东西时,这包括边框、box-shadow 、和outline 。这些东西不会被重新绘制以适应被剪切的形状。这可能是一个问题,可能需要额外的元素或将效果移至父级来取代失去的效果。