基于CSS mask和clip-path实现切角的技巧1

简介: 基于CSS mask和clip-path实现切角的技巧

本文翻译自 Tricks to Cut Corners Using CSS Mask and Clip-Path Properties,略有删改

原作者:Temani Afif

我们最近使用CSS mask属性创建花哨的边框,本文将使用CSS maskclip-path来切元素的四个角!使用多种技术可以从任何元素的角切割不同的形状。在本文中,我们将考虑创建独特角落形状的现代技术,同时尝试使用可重用代码,该代码允许我们仅通过调整变量即可产生不同的结果。

查看此在线工具,了解我们正在构建的内容。这是一个CSS生成器,你可以选择不同的形状、角落和大小,可实时获得CSS代码!

34fd3a59064a9b54fb3714f3d914a86.png

我们主要有两种类型的切割:一种是圆形的,一种是倾斜的。对于每个类型,我们可以选择获取完整的形状或纯边框的形状,以及可以选择要切哪个方向的角。

与上一篇文章一样,我们将大量使用CSS mask属性。如果你不熟悉它,建议在继续之前阅读我写的快速入门书

圆形切角

对于圆形切割,我们使用radial-gradient()。切割四个角落时,逻辑解决方案则是创建四个渐变,每个角落一个:

8ff3f7a541404a765d58fbab8851859.png

每个圆形切割部分占整个元素尺寸的四分之一。如上图所示,左上角切割代码如下:

radial-gradient(circle 30px at top left, #0000 98%, red) top left;

以上代码的翻译后,即在左上角呈现一个半径为30px圆圈。主要颜色是透明的(#0000),其余是red。其他三个渐变的逻辑相同。这里的关键字circle可以省略,因为已经明确的指定了一个半径值。

就像我在上一篇文章中所做的那样,这次我将使用略大或更小的值,以避免糟糕的视觉效果。在这里,我使用98%而不是100%来避免锯齿状的边缘,51%而不是50%来创建渐变之间的重叠并避免空白。本文继续遵循这一逻辑。在实际开发中,你会发现添加或删除1%或1deg通常会带来良好的视觉效果。

接下来将此逻辑应用于CSS mask属性,效果如下:

b74b07c10fa8ed43328498777cc95da.png

核心CSS代码如下:

.mask {
  -webkit-mask:
    radial-gradient(circle 30px at top    left ,#0000 98%,#000) top    left,
    radial-gradient(circle 30px at top    right,#0000 98%,#000) top    right,
    radial-gradient(circle 30px at bottom left ,#0000 98%,#000) bottom left,
    radial-gradient(circle 30px at bottom right,#0000 98%,#000) bottom right;
  -webkit-mask-size:51% 51%;
  -webkit-mask-repeat:no-repeat;
}

上面的代码有很多数值是重复的,我们可以稍微优化一下该代码:

--g: #0000 98%,#000;
--r: 30px;
mask:
  radial-gradient(var(--r) at 0    0   ,var(--g)) 0    0,
  radial-gradient(var(--r) at 100% 0   ,var(--g)) 100% 0,
  radial-gradient(var(--r) at 0    100%,var(--g)) 0    100%,
  radial-gradient(var(--r) at 100% 100%,var(--g)) 100% 100%;
mask-size: 51% 51%;
mask-repeat: no-repeat;

这样我们可以对冗余值使用自定义属性,作为个人偏好,我使用位置的数字值而不是关键字。

在生成器中,将使用以下语法,省去mask-sizemask-repeat,使用简写方式:

--g: #0000 98%,#000;
--r: 30px;
mask:
  radial-gradient(var(--r) at 0    0   ,var(--g)) 0    0   /51% 51% no-repeat,
  radial-gradient(var(--r) at 100% 0   ,var(--g)) 100% 0   /51% 51% no-repeat,
  radial-gradient(var(--r) at 0    100%,var(--g)) 0    100%/51% 51% no-repeat,
  radial-gradient(var(--r) at 100% 100%,var(--g)) 100% 100%/51% 51% no-repeat;

我们可以使用更少的渐变吗?

当然!一个渐变也可以完成这个效果。以下动图hover效果就是基于一个渐变实现:

fa658e7d9529f181c878ca3d3897c02.png

在这里,我们定义了一个没有尺寸的radial-gradient(),默认情况下它是100%的高度和100%宽度。这让我们在中间有一个洞。我们将渐变平移到图像宽度和高度的一半,将孔移动到一个角落。由于默认情况下,CSS mask重复,因此我们在每个角落都得到相同的效果。我们有四个切角,只使用了一个渐变!

这种方法的唯一缺点是,我们需要提前知道元素的宽度和高度。

我们能用 -50% 而不是一半的宽度和高度吗?

不幸的是,在这里无法做到这一点,因为当与CSS mask-position属性一起使用时,百分比的行为与像素值不同,比较难处理。

我有一个详细的堆栈溢出答案来解释差异。它涉及background-position,但相同的逻辑适用于CSS mask-position属性。

然而,我们可以使用一些技巧来使其与百分比值一起工作,无需知道宽度或高度。当渐变(或背景图层)的宽度和高度等于元素时,我们无法使用百分比值移动它。所以我们需要改变它的尺寸!

定义一个等于99.5% 99.5%的尺寸。将宽度和高度降低了0.5%,此时基本保持相同的视觉结果,因为我们不会注意到100%和99.5%之间的巨大差异。现在我们的渐变尺寸与100%不同,我们可以使用百分比值移动它。

要将其移动一半的宽度和高度,我们需要使用这个方程:

100% * (50/(100 - 99.5)) = 100% * 100 = 10000%

看着是一个比较奇怪的值,但是是可以正常运行的。

mask: radial-gradient(30px,#0000 98%,#000) 10000% 10000%/99.5% 99.5%

这个技巧用的很好。无论元素的大小是多少,我们只能用一个渐变切割四个角落。但是当元素的宽度或高度是小数值时,这种方法有一个很小的缺点。以下是一个宽度等于150.5px的图像示例:

bd806cafb197cb11547fe76477a1db7.png

使用99.5%和150.5px将产生四舍五入问题,从而破坏计算,导致mask有一定的错位。因此,请谨慎使用这种方法。

有一个只有一个渐变的解决方案,没有四舍五入问题。使用以下代码:

mask: radial-gradient(30px at 30px 30px,#0000 98%,#000) -30px -30px

技巧是在左上角创建一个圆,通过用负偏移量移动它,我们覆盖了四个角落。将下方悬停在下方,看看这个技巧。


这个方法很完美,因为它使用一种渐变,且没有四舍五入的问题。但它有一个缺点,半径的值被使用5次。但是我们可以使用自定义属性进行简化:

--r: 30px;
mask: radial-gradient(var(--r) at var(--r) var(--r),#0000 98%,#000) calc(-1*var(--r)) calc(-1*var(--r))

让我们快速回顾一下我们刚刚介绍的三种方法:

  • 第一种方法使用四个渐变,在使用方面没有缺点,它适用于任何类型的元素和尺寸。但它的代码量很冗长。
  • 第二种方法使用一种渐变,但在某些情况下可能会有偏移不准确的情况。它适用于固定尺寸的元素。
  • 第三种方法使用一种渐变,没有四舍五入问题。这是其中的完美方法,但它需要在渐变值内多次使用半径。

只切割部分角落

现在我们已经看到了所有角落的案例,接下来让我们禁用其中一些。使用第一种方法,任何我们想保持未切割的角落,我们只需删除其渐变并调整剩余内容的大小。

04f7ff92ce6dcd0609b166f08a85646.png

要禁用右上角的时候:

  • 移除了右上角的渐变(蓝色渐变)。
  • 此时有一个空角落,所以增加了红色渐变(或紫色渐变)的大小,以覆盖剩余的空间。

在这里可以做多少可能性和组合。如果需要切割N个角(其中N范围从1到4),则使用N个渐变。我们只需要正确设置每个的大小,以便填满整个空间。

只有一个渐变的其他方法呢?我们需要使用另一个渐变!这两种方法只使用一个radial-gradient()来切割角落,因此我们将依靠另一个渐变来“隐藏”切割。我们可以使用带有四个部分的conic-gradient()来完成此效果:

conic-gradient(red 25%, blue 0 50%, green 0 75%, purple 0)

conic-gradient()会覆盖radial-gradient(),这样就不会有切角。让我们将conic-gradient()中的一种颜色更改为透明。例如,将右上角改为透明,就是下面的效果:

c8633e7f343117a2ba1810ff8921390.png

核心代码如下:

conic-gradient(#0000 25%,blue 0 50%,green 0 75%,purple 0)

通过将conic-gradient()的颜色从不透明更改为透明,可以实现我们想要切割的角落,并获得各种可能的组合。

  • 要切割四个角落,第一种方法需要四个渐变,而第三个方法只需要一个渐变,所以我们使用后者。
  • 要切割一个角落,第一种方法需要一个渐变,而第三个方法需要两个渐变,因此您可以使用第一个渐变。
  • 要切割两个角落,两者都使用两个渐变。
  • 要切割三个角落,一个方法将使用三个渐变,另一个方法仅使用两个渐变。

以上介绍了每个案例选择适当的方法,我们总共不需要超过两个渐变。但在实际应用中,您应该选择更优化简洁的代码。



目录
相关文章
|
3月前
|
前端开发
CSS - 使用 clip-path 轻松实现正六边形块状元素
如何使用CSS的`clip-path`属性来创建正六边形的块状元素。文章提供了详细的HTML和CSS代码示例,展示了如何实现六边形的布局和样式,并通过CSS动画增强了视觉效果。最终效果是一个包含文本的可交互的正六边形元素,当鼠标悬停时会改变颜色。
142 0
CSS - 使用 clip-path 轻松实现正六边形块状元素
|
4月前
|
前端开发
学习css的clip-path属性
【7月更文挑战第1天】了解CSS `clip-path`属性,用于定义元素显示区域的裁剪形状,如圆形、椭圆、多边形、矩形及SVG路径。通过配合过渡和动画,可创建动态交互效果。例如,`clip-path: circle(radius at center);`用于创建圆形裁剪,`polygon`用于自定义多边形。还可以使用`path()`引用SVG路径数据。[资源推荐:bennettfeely.com/clippy/](https://bennettfeely.com/clippy/),提供交互式工具测试不同形状。
67 0
学习css的clip-path属性
|
4月前
|
前端开发
前端 CSS 经典:clip-path 裁剪
前端 CSS 经典:clip-path 裁剪
35 0
|
5月前
|
前端开发 UED
CSS clip-path 属性
CSS clip-path 属性
83 0
|
6月前
|
前端开发
前端 CSS 经典:clip、clip-path
前端 CSS 经典:clip、clip-path
62 0
|
前端开发
基于CSS mask和clip-path实现切角的技巧2
基于CSS mask和clip-path实现切角的技巧
219 0
|
前端开发 JavaScript
CSS奇思妙想之-利用CSS裁剪(clip-path)完成各种图形
CSS奇思妙想之-利用CSS裁剪(clip-path)完成各种图形
260 1
CSS奇思妙想之-利用CSS裁剪(clip-path)完成各种图形
|
前端开发 容器
奇妙的 CSS MASK
奇妙的 CSS MASK
143 0
奇妙的 CSS MASK
|
Web App开发 前端开发 JavaScript
CSS mask 实现鼠标跟随镂空效果
CSS mask 实现鼠标跟随镂空效果
CSS mask 实现鼠标跟随镂空效果
|
Web App开发 前端开发

热门文章

最新文章