新人求关注?,博主天天日更,全年无休,您的关注是我的更新的功力~ 感谢
在编写前端页面的时候,我们会经常遇到编写一些异形的容器元素,例如实现下面这种图形
如果从来没有做过这种案例的同学来说,可能一上来有点蒙,不知道如何下手,今天我们就手摸手帮你实现这种效果,欢迎点赞、关注、收藏,等下次遇到的这些需求的时候,可以直接拷贝代码到项目中,直接亮瞎客户的双眼。 哈哈哈,话不多说,直接 show code
实现这种效果其实也很简单,通过 mask 遮罩实现的,具体代码如下:
关键 CSS
.box {
--r: 20px; /* control the rounded part*/
--s: 40px; /* control the size of the cut */
--a: 40deg; /* control the depth of the curvature*/
--_m:0/calc(2*var(--r)) var(--r) no-repeat
radial-gradient(50% 100% at bottom,#000 calc(100% - 1px),#0000);
--_d:(var(--s) + var(--r))*cos(var(--a));
mask:
calc(50% + var(--_d)) var(--_m),calc(50% - var(--_d)) var(--_m),
radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)),
#0000 100%,#000 calc(100% + 1px)) 0 calc(var(--r)*(1 - sin(var(--a)))) no-repeat,
linear-gradient(90deg,#000 calc(50% - var(--_d)),#0000 0 calc(50% + var(--_d)),#000 0);
}
代码解释:
1. 定义 CSS 变量
--r: 20px; /* control the rounded part */
--s: 40px; /* control the size of the cut */
--a: 40deg; /* control the depth of the curvature */
- --r: 20px; 控制圆角部分的半径大小。
- --s: 40px; 控制切割的尺寸,即凹口的宽度。
- --a: 40deg; 控制曲线的深度,即凹口的角度。
2. 定义遮罩(mask)的基本单位 --_m
--_m: 0/calc(2*var(--r)) var(--r) no-repeat radial-gradient(50% 100% at bottom,#000 calc(100% - 1px),#0000);
--_m 定义一个基本遮罩图形,使用径向渐变 (radial-gradient) 来创建半圆形的遮罩效果:
- 0/: 设置背景位置为 (0, 0)。
- calc(2*var(--r)) var(--r): 设置背景大小为 (2 * 圆角半径) 宽度和 (圆角半径) 高度。
- no-repeat: 禁止背景图像重复。
- radial-gradient(...): 使用径向渐变创建一个从底部开始的渐变,其中 50% 100% at bottom 定义了圆心位置在底部中间,#000 calc(100% - 1px) 定义了渐变的颜色,从黑色变为透明。
3. 计算 _d 变量
--_d: (var(--s) + var(--r)) * cos(var(--a));
--_d 变量计算的是凹口宽度一半加上圆角部分的水平偏移量,它用来确定遮罩中曲线的深度。
- (var(--s) + var(--r)): 计算切割宽度加上圆角半径。
- cos(var(--a)): 使用 cos 函数计算角度 --a 对应的余弦值,从而调整凹口的宽度。
4. 定义 mask 属性
mask: calc(50% + var(--_d)) var(--_m), calc(50% - var(--_d)) var(--_m),
radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)), #0000 100%, #000 calc(100% + 1px)) 0 calc(var(--r)*(1 - sin(var(--a)))) no-repeat,
linear-gradient(90deg, #000 calc(50% - var(--_d)), #0000 0 calc(50% + var(--_d)), #000 0);
这个 mask 属性结合了四个部分的遮罩图形来实现整体效果:
- calc(50% + var(--_d)) var(--_m):
定位第一个半圆遮罩图形。通过 calc(50% + var(--_d)) 计算出其中心位置在元素宽度的一半加上偏移量的地方,应用 --_m 作为遮罩图形。
- calc(50% - var(--_d)) var(--_m):
定位第二个半圆遮罩图形。通过 calc(50% - var(--_d)) 计算出其中心位置在元素宽度的一半减去偏移量的地方,应用 --_m 作为遮罩图形。
- radial-gradient(...) 0 calc(var(--r)*(1 - sin(var(--a)))) no-repeat:
使用径向渐变创建一个凹口的中间部分:
- var(--s) 定义了径向渐变的尺寸。
50% calc(-1*sin(var(--a))*var(--s)): 定义圆心位置,垂直方向上调整其位置以实现内凹效果。
#0000 100%, #000 calc(100% + 1px): 定义颜色,从透明到黑色。
- 0 calc(var(--r)*(1 - sin(var(--a)))) no-repeat: 调整垂直偏移,确保凹口与边缘对齐,不重复。
- linear-gradient(...):
使用线性渐变填充凹口之间的区域:
90deg: 线性渐变方向为水平。
#000 calc(50% - var(--_d)), #0000 0 calc(50% + var(--_d)), #000 0: 定义了从黑色到透明再回到黑色的渐变。
完整 demo 代码
<div class="box"></div>
<div class="box" style="--a: 20deg"></div>
<div class="box bottom" style="--a: 30deg;--r:30px;--s:20px"></div>
<style>
.box {
--r: 20px; /* control the rounded part*/
--s: 40px; /* control the size of the cut */
--a: 40deg; /* control the depth of the curvature*/
height: 120px;
margin-block: 20px;
background: linear-gradient(45deg,#FF4E50,#40C0CB);
--_m:0/calc(2*var(--r)) var(--r) no-repeat
radial-gradient(50% 100% at bottom,#000 calc(100% - 1px),#0000);
--_d:(var(--s) + var(--r))*cos(var(--a));
mask:
calc(50% + var(--_d)) var(--_m),calc(50% - var(--_d)) var(--_m),
radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)),
#0000 100%,#000 calc(100% + 1px)) 0 calc(var(--r)*(1 - sin(var(--a)))) no-repeat,
linear-gradient(90deg,#000 calc(50% - var(--_d)),#0000 0 calc(50% + var(--_d)),#000 0);
}
.bottom {
--_m:100%/calc(2*var(--r)) var(--r) no-repeat
radial-gradient(50% 100% at top,#000 calc(100% - 1px),#0000);
mask:
calc(50% + var(--_d)) var(--_m),calc(50% - var(--_d)) var(--_m),
radial-gradient(var(--s) at 50% calc(100% + sin(var(--a))*var(--s)),
#0000 100%,#000 calc(100% + 1px)) 0 calc(var(--r)*(sin(var(--a)) - 1)) no-repeat,
linear-gradient(90deg,#000 calc(50% - var(--_d)),#0000 0 calc(50% + var(--_d)),#000 0);
}
body {
margin: 0;
}
</style>
完整效果:
小结
如果您有疑问或者其他问题,欢迎留言评论,大家一起探讨,一起进步~ 欢迎点赞、关注?、转发~
求关注~