【译】纯CSS形状的三种实现方式

854 阅读6分钟

现代CSS和现代浏览器为我们提供了三种出色的方式来使用纯CSS创建基本形状。本文,我们将研究如何使用下面三种的方法创建CSS三角形。

  • border

  • linear-gradients

  • clip-path

方法1:borders

这是我学会的第一个创建CSS三角形的技巧。目前,它仍然是一个可靠的方法。

创建一个高度和宽度均为0的元素,提供值任意的border,让他们相交,并且保证元素没有其他可见指示(译者注:例如阴影),然后利用相交来创建一个三角形。

为了更好地说明实现原理,我们将每一侧都设置不同的边框颜色。


.triangle {

  border: 10px solid blue;

  border-right-color: red;

  border-bottom-color: black;

  border-left-color: green;

}

现在可以看到实现了四个三角形。

为了创建一个单独的三角形,需要先决定保留指向那个方向的三角形。如果我们希望的是指向右侧的三角形,类似播放图标的那个三角形,那我们就保持左边边框可见。其他边框的颜色设置为transparent,如下所示:

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

下图中,我添加了一个红色的outline来查看边框(译者注:outline不占宽高),以便进一步改进。

我们可以做的第一项改进是移除右边框的宽度,防止总宽度包含它。我们还可以为顶部和底部设置唯一值来展示拉伸三角形视觉效果。


.triangle {

  border-style: solid;

  border-color: transparent;

  /* top | right | bottom | left */

  border-width: 7px 0 7px 10px;

  border-left-color: blue;

}

改进后的图片如下,我们首先指定了一个实心透明的边框。然后定义宽度,使顶部和底部的值小于右侧的值,最终渲染出一个细长的三角形。

因此,要获取不同指向的三角形。例如指向为上,我们只需要改变宽度,同时使得底部获得颜色值,顶部宽度为0:


.triangle {

  border-style: solid;

  border-color: transparent;

  /* top | right | bottom | left */

  border-width: 0 7px 10px 7px;

  border-bottom-color: blue;

}

border对于制作三角形十分有效,但是如果不涉及更多属性的话,border不能很好地扩展形状。下面的这两个属性就是来解决这个问题。

方法2: linear-gradient

linear-gradients是background-image的值。

首先创建一个元素,如果可以的话,设置边框并且设置background-repeat为prevent。


.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%);

如果我们的元素是方形的,三角形看上去就是从一个角到另一个角,但是我们最终想要的是一个稍微不同的比例的三角形,就跟border做出来的效果一样,三角形是拉伸的。

如果制作跟order一样效果的三角形。我们必须调整background-size和background-position值。

首先是background-size:width height,我们希望我们的三角形可以有 100% 的宽度,但只有 50% 的高度,所以添加以下内容:


background-size: 100% 50%;

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

由于45deg的渐变,形状比较奇怪。我们需要调整角度,使三角形的顶边看起来从左上角切到边界框右侧的中间。

我不是数学高手,所以这需要使用 DevTools 进行一些实验来找到正确的值 😉

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


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

经过调整之后,我们得到了一个三角形,但是并不是我们预期的。

对于border来说,我们依赖它们之间的相交来创建形状,对于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-position:

background-position: top left, bottom left;

使用 CSS 渐变创建的最终效果:

这种方法如果不更新角度的话是无法改变纵横比的。但是,CSS 渐变可用于创建更多形状,特别是由于它们能够分层以创建效果。

方法3:clip-path

clip-path 是最简单的最容易扩展的方法。但是兼容性差强人意。随意你要确定你是否可以接受这种方案。

首先创建一个元素,设置宽高和background-color。

.triangle {
  width: 16px;
  height: 20px;
  background-color: blue;
}

clip-path的原理是您可以使用它创建多边形并且放置在元素内部。元素外部clip-path是无法生效的。因为裁剪的范围最多到边界。

语法可能不太习惯去使用,所以我绝对建议使用生成器来创建你的路径。

同样的为了创建三角形,这是一个指向右侧的三角形:


clip-path: polygon(0 0, 0% 100%, 100% 50%);

使用clip-path,您可以沿路径放置坐标点。因此,在本例中,我们在左上角 ( 0 0)、左下角 ( 0% 100%) 和右中心 ( 100% 50%)处有一个点。

最终的效果:

虽然clip-path对于创建各种形状都很灵活并且也能适应任何边界框和纵横比。但是要注意:

边界之外无法绘制任何内容,这包括border、box-shadow、和outline。这些东西不会重新绘制以适应剪裁的形状。这可能是一个陷阱,如果我们想要将框外的效果显示出来,可能需要新增额外的元素或者把它移动到父元素内部。

演示

这个演示展示了我们创建 CSS 三角形的三种方法。我们在::after中进行了三角形的制作。并且使用视口单位vw来做成响应式三角形,

codepen.io/5t3ph/pen/o…