SVG 是首选方案,因其贝塞尔曲线平滑、响应式缩放不失真、CSS 可控性强;clip-path 适合静态原型但难调细节;mask-image 支持渐变动画但兼容性差;Canvas 性能好但需手动处理 DPR 与缩放。
直接说结论:用 SVG 是最稳、最可控、最易维护的方案;clip-path 适合快速原型但难调细节;mask-image 可做渐变动画但兼容性有坑;Canvas 动态波浪性能好但必须手动处理缩放逻辑。
SVG 的 <path> 能精准描述贝塞尔曲线,波峰波谷平滑无锯齿,且天然支持 viewBox 和 preserveAspectRatio="none",拉伸时不会失真。更重要的是:它是个独立 DOM 元素,可直接用 CSS 控制颜色、尺寸、位置,还能加 animation 或 transform 做流动效果。
常见错误是把 SVG 写成固定像素宽高(如 width="1440" height="320"),结果在小屏上溢出或被裁剪。正确做法是只设 width: 100%,靠 viewBox 定义坐标系,再用 preserveAspectRatio="none" 允许非等比缩放。
background-color 设底色,SVG 内部 <path> 的 fill 设波浪色(通常与下方背景一致)height,不是 SVG 的 height 属性bottom: -1px 或 margin-bottom: -1px
clip-path: polygon() 快速实现但限制多适合静态、简单波浪,比如一页式官网顶部/底部装饰。它的核心是用一系列顶点连成折线轮廓,视觉上“模拟”波浪,但本质是多边形,弧度靠点密+坐标微调硬凑。
立即学习“前端免费学习笔记(深入)”;
典型问题:波浪在不同屏幕宽度下变形严重;动画时 Chrome/Firefox 表现不一致;无法填充渐变色(clip-path 只裁剪,不绘图)。
25% 50%),避免固定像素导致响应失效div + 不同 clip-path,不能靠伪元素复用mask-image 实现渐变动效的兼容性陷阱这个方案用 base64 编码的 SVG 作为遮罩,配合 mask-repeat: repeat-x 和 animation 平移遮罩位置,做出“水流”感。优点是能轻松叠加线性渐变背景、层级轻量。
但 iOS Safari 15.4 之前不支持 mask-image,Android WebView 也有降级风险;更隐蔽的坑是:mask-size 单位写成 120px 30px(无空格)会直接失效,必须写成 120px 30px(有空格)——很多复制粘贴的代码就栽在这儿。
% 符号要 URL encode 成 %25,否则解析失败-webkit-mask-position 和 mask-position,否则旧版 Safari 不动overflow: hidden,它会截断遮罩效果本身Canvas 绘制波浪适合需要实时交互(如随鼠标起伏)或复杂物理模拟的场景,但最大陷阱是:用 CSS 设置 canvas 宽高(width: 100%; height: 200px)会导致画布像素被浏览器插值拉伸,波浪立刻糊成一片。
正确路径是:HTML 中用 width 和 height 属性定义绘图表面真实分辨率(如 <canvas width="1440" height="320"></canvas>),再用 CSS 控制布局尺寸,并在 JS 中监听 resize 事件,按比例重绘路径。
ctx !== null,老版 IE 或禁用 JS 时会返回 nullctx.clearRect(0, 0, canvas.width, canvas.height) 清屏,否则波浪拖影ctx.bezierCurveTo(),控制点坐标需根据 canvas 实际 width/height 动态计算,不能写死真正难的不是画出第一道波浪,而是让波浪在 iPhone SE 和 4K 显示器上看起来一样顺滑——这意味着你得在 SVG 的 viewBox 精度、Canvas 的 DPR 适配、CSS mask 的 fallback 方案之间反复校验。别省那几行 media query 或一个 @supports 检测。