径向渐变做圆角缺口的本质是用 mask“抠掉”区域,而非画缺口;核心是 radial-gradient 生成透明圆形作为遮罩,配合 mask-composite: exclude 实现精准挖空,需严格对齐、硬边控制与像素级适配。

径向渐变做圆角缺口的本质是什么
不是“画一个缺口”,而是用 mask 把不需要显示的区域“抠掉”。CSS 中最稳定、可控的方式是用 radial-gradient() 生成一个透明圆形,再叠加在元素上——这个圆形就是缺口位置。关键在于:透明部分 = 被遮盖区域,不透明部分 = 保留内容。
- 缺口必须是纯透明(alpha=0),不能靠背景色“模拟”,否则换背景就露馅
-
mask的尺寸和定位要和优惠券内容层严格对齐,否则缺口偏移 - 不要用
mask-image: radial-gradient(circle at 20px 20px, transparent 10px, black 10px)这种写法直接控制边缘硬度,容易因渲染差异出现半像素模糊
mask 实现圆角缺口的最小可行代码
核心是两层:一层是优惠券主体(带 border-radius),另一层是 mask 叠加缺口。注意 mask 必须用 mask-composite: exclude(或旧版 -webkit-mask-composite: xor)来实现“挖空”效果:
.coupon {
position: relative;
width: 300px;
height: 120px;
background: linear-gradient(135deg, #ff9a9e, #fad0c4);
border-radius: 12px;
}
<p>.coupon::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
-webkit-mask:
radial-gradient(circle at 280px 20px, transparent 12px, black 12px);
mask:
radial-gradient(circle at 280px 20px, transparent 12px, black 12px);
-webkit-mask-composite: xor;
mask-composite: exclude;
}</p>-
circle at 280px 20px表示缺口圆心在右上角附近,单位必须是 px/em 等绝对值,% 容易随容器缩放错位 -
transparent 12px, black 12px是硬边写法:半径内全透明,边界无过渡,避免毛边 - 如果用
mask-composite: exclude不生效,先确认浏览器支持(Chrome 113+ / Safari 16.4+),降级可改用-webkit-mask-composite: xor
为什么不用 clip-path?
clip-path: circle() 或 inset() 看似更简单,但问题明显:
-
clip-path是裁剪整个元素轮廓,无法单独“挖空”局部区域(比如只在右上角切个缺口,其余圆角保持) - 多缺口时,
clip-path: path()写法复杂、不易维护,且 Firefox 对path()支持不稳定 -
clip-path不支持抗锯齿微调,缺口边缘容易发虚;而mask+ 径向渐变能精确控制 alpha 边界
如果只是做单一切口且兼容性要求极低(仅现代 Chrome),clip-path 可行;但真实项目中,mask 是更可控的选择。
立即学习“前端免费学习笔记(深入)”;
移动端适配和高倍屏下的坑
缺口位置在 iPhone 上偏移?很可能是视口缩放或 DPR 导致的像素对齐问题:
- 不要用
rem或%定义缺口坐标,一律用px(配合device-pixel-ratio媒体查询可选配) - 高倍屏下,12px 半径可能看起来太小,可按
@media (-webkit-min-device-pixel-ratio: 2)加一层放大逻辑 - Safari 对
mask的 layer blending 有缓存 bug,偶发缺口不更新,可在 JS 中触发重绘:el.style.mask = el.style.mask
圆角缺口本身不难,难的是在不同缩放、不同 DPR、不同 mask 实现层级下保持像素级一致——这恰恰是上线前最容易被忽略的验证点。


















