在网页视觉设计中,波浪形边框常被用来弱化生硬的直线轮廓,营造柔和或活泼的氛围。传统做法多依赖图片或SVG,但维护成本高且不易响应尺寸变化。利用CSS的mask-image属性,我们可以纯代码生成遮罩,将矩形元素的边缘“裁剪”成波浪状,无需额外资源请求。

一、mask-image遮罩的基本原理
mask-image的作用是为元素指定一张遮罩图像,图像的Alpha通道决定元素哪些部分可见、哪些部分透明。简单来说,遮罩图中不透明的区域会保留元素原本内容,完全透明的区域会把元素对应位置“挖空”。当我们把遮罩图设计成上下边缘为波浪、中间为实色的图形时,元素上下边界就会呈现波浪轮廓。
与clip-path不同,mask-image可以使用位图、渐变甚至SVG作为遮罩源,并且支持平铺(repeat),非常适合做连续性边框装饰。另外,mask不会触发重排,仅影响绘制层,性能上比嵌套伪元素模拟波浪更优。理解这一点后,我们便能利用CSS渐变函数现场“画”出波浪遮罩。
1.1 为什么选择渐变而非图片
使用linear-gradient或radial-gradient生成遮罩,好处是零外部依赖、可随CSS变量动态调整波峰大小和密度。如果用图片,遇到容器宽度变化就要重新切图;而渐变遮罩通过mask-size与mask-repeat就能自适应。
以下示例用radial-gradient在水平方向重复绘制半圆,组合成波浪。每个径向渐变画一个深色圆,圆外透明,排布后形成连续弧形边缘。这种方式比手绘SVG路径更轻量,也更容易让团队通过改参数来微调视觉。
/* 基础波浪遮罩:上下边缘为半圆起伏 */
.wave-box {
width: 300px;
height: 160px;
background: linear-gradient(135deg, #6ad, #39c);
-webkit-mask-image: radial-gradient(circle 20px at 20px 0, transparent 20px, #000 21px);
mask-image: radial-gradient(circle 20px at 20px 0, transparent 20px, #000 21px);
-webkit-mask-size: 40px 100%;
mask-size: 40px 100%;
-webkit-mask-repeat: repeat-x;
mask-repeat: repeat-x;
}
二、构建上下双边波浪边框
上面例子只在顶部挖出了波浪,若需要上下都呈波浪,就要让遮罩在垂直方向也定义透明区。我们可以利用两个radial-gradient叠加:一个定位在顶部,一个定位在底部,中间用实色填充,从而保证元素中部完整显示。
实现时通过逗号分隔多个渐变,mask-image会按层合成。注意透明与实色的半径差值要小,避免边缘锯齿。同时mask-size的高度应设为100%,让波浪紧贴上下边;宽度控制单个波周期。下面代码展示了完整上下波浪边框。
/* 上下双边波浪遮罩 */
.bi-wave {
width: 100%;
height: 120px;
background: #f76c6c;
-webkit-mask-image:
radial-gradient(circle 15px at 15px 0, transparent 15px, #000 16px),
radial-gradient(circle 15px at 15px 100%, transparent 15px, #000 16px);
mask-image:
radial-gradient(circle 15px at 15px 0, transparent 15px, #000 16px),
radial-gradient(circle 15px at 15px 100%, transparent 15px, #000 16px);
-webkit-mask-size: 30px 100%;
mask-size: 30px 100%;
-webkit-mask-repeat: repeat-x;
mask-repeat: repeat-x;
}
2.1 调整波峰密度与高度
波峰密度由mask-size的水平值决定:值越小波越密。波峰高度则由radial-gradient里的半径(如上例15px)控制。若希望波浪更平缓,可增大半径并相应增大mask-size,使相邻圆重叠更多,弧线更浅。
建议使用CSS自定义属性统一管理这些数值,方便后期修改。例如定义--r为半径、--gap为周期,在mask中引用,能显著提升可维护性,也利于响应式适配不同屏幕。
:root {
--r: 12px;
--gap: 24px;
}
.easy-wave {
background: #5c8;
-webkit-mask-image: radial-gradient(circle var(--r) at var(--r) 0, transparent var(--r), #000 calc(var(--r) + 1px));
mask-image: radial-gradient(circle var(--r) at var(--r) 0, transparent var(--r), #000 calc(var(--r) + 1px));
-webkit-mask-size: var(--gap) 100%;
mask-size: var(--gap) 100%;
-webkit-mask-repeat: repeat-x;
mask-repeat: repeat-x;
}
三、兼容性与常见坑
WebKit内核浏览器(如旧版Safari)必须写-webkit-mask-image等前缀属性,否则遮罩失效。另外,mask-image引用的渐变中,透明区域必须用transparent或rgba中alpha为0,实色只需alpha为1,颜色本身无关紧要,通常写#000即可。
一个常见误区是给元素设了mask却看不到波浪,多半是因为背景色和遮罩实色区重合度不够,或mask-size过大导致只有一个波峰被截断。可用浏览器开发者工具检查mask层渲染,逐步缩小mask-size来验证平铺效果。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 波浪只显示一侧 | 仅写了顶部渐变 | 补充底部radial-gradient层 |
| 整体元素消失 | 遮罩全透明或尺寸为0 | 确认#000实色区存在且mask-size合理 |
| Safari无效果 | 缺少-webkit-前缀 | 补全-webkit-mask-*属性 |
3.1 与border-image的对比
border-image也能做波浪边,但需要将波浪存为九宫格图片,且border宽度固定,内容区会被压缩。mask-image直接作用于整个盒子背景,不占布局空间,更适合做背景层装饰。若元素内部还有文字,mask方式不会裁剪文字,只会裁剪背景,灵活性更高。
综合来看,纯CSS遮罩方案在轻量化和动态调整上优势明显,建议在新项目中优先采用,只对必须兼容非常老版本浏览器的场景保留图片方案。
CSSmask-image波浪形边框修改时间:2026-08-04 20:51:33