CSS 怎么画优惠券缺角卡片:这 3 种写法一次讲清

编程狮(w3cschool.cn) 2026-10-20 07:03:17 浏览数 (22)
反馈

缺角卡片(就是优惠券两侧各挖一个半圆缺口、中间一条虚线的那种)有三种主流写法:用 clip-path 直接把角切掉,用 radial-gradient 在背景上"挖"出透明圆孔,或者用 mask 遮罩把不需要的部分盖掉。三者的差别不在视觉效果,而在能不能保留阴影、能不能透光、以及兼容性。

优惠券缺角卡片用哪种写法最稳?

第一种最直观,但会把 box-shadow 一起裁掉;第二种能做出真正的透光缺口,是优惠券样式的标准答案;第三种最灵活,代价是要多写一层遮罩语法。

本文给出三种写法的完整代码、各自的适用边界和三个高频坑的修复办法,最后给一份可以直接照抄的验证清单。

先看结论

要"切除实体角"用 clip-path,写法最短;要"挖出透光的圆孔"用 radial-gradient 叠背景,这是缺角卡片最贴近设计稿的做法;要两者兼得又要兼容复杂形状,用 mask。

选择的核心判断只有一条:缺口后面要不要透出背景。需要透光就用渐变或遮罩,不需要就用 clip-path,后者还能少写一堆定位。

基础选择器还不熟的,可以先看 CSS 基础教程 把盒模型和定位过一遍。

一、方法一:clip-path 切角,写法最短

clip-path 的思路是直接裁剪元素的可见区域,超出多边形范围的都不显示。

.coupon {
  width: 320px;
  height: 120px;
  background: linear-gradient(135deg, #ff8a3d, #fe6a00);
  border-radius: 12px;
  clip-path: polygon(
    0 0, 100% 0, 100% 100%, 0 100%, 0 60%,
    12px 50%, 0 40%
  );
}

这段做的是:先画一个有渐变背景和圆角的卡片,再用多边形路径把左侧中间挖出一个尖角。坐标按顺序连成闭合路径,12px 50% 那个点就是缺角的尖端。

要注意三点:

  • 坐标可以用百分比也可以用像素,混写是允许的,但同一条路径里保持单位一致更好维护;
  • 尖角缺口和"半圆缺口"是两种效果,半圆需要很多个点近似,写起来很啰嗦;
  • 最大的坑:clip-path 会连同 box-shadow 一起裁掉,卡片加阴影后会发现阴影消失。

三种写法的取舍决策路径

二、方法二:radial-gradient 挖圆孔,最像优惠券

想要真正的半圆缺口,用径向渐变在背景上"抠"出透明区域,是缺角卡片的标准做法。

.coupon {
  position: relative;
  width: 320px;
  height: 120px;
  background:
    radial-gradient(circle at left center, transparent 10px, #fff 10px) left / 51% 100% no-repeat,
    radial-gradient(circle at right center, transparent 10px, #fff 10px) right / 51% 100% no-repeat;
}

.coupon::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  width: 0;
  height: 60px;
  border-left: 1px dashed #d9d9d9;
}

第一段做的是:用两个径向渐变各画半张卡片,渐变在圆心位置留出 10 像素的透明圆,其余部分填白,左右各占 51% 宽度;第二段用伪元素画中间那条虚线。

这个写法的关键在于 transparent 10px, #fff 10px ——两个色标落在同一位置,形成硬边界,圆内透明、圆外填充。半径改成变量就能适配不同尺寸。

它的局限也要说清楚:卡片背景必须是纯色,渐变背景不好做;而且两个半张卡片之间的接缝在缩放时可能出现 1 像素细线,需要把宽度设成 51% 让它互相重叠。

三、方法三:mask 遮罩,最灵活

mask 的思路是反过来:先画一个完整卡片,再用遮罩把不需要的部分"盖住"。

.coupon {
  width: 320px;
  height: 120px;
  background: linear-gradient(135deg, #fff7f0, #ffe9d6);
  border-radius: 12px;
  --r: 12px;
  mask:
    radial-gradient(circle var(--r) at left 0 50%, transparent 98%, #000) ,
    radial-gradient(circle var(--r) at right 0 50%, transparent 98%, #000);
  mask-composite: intersect;
}

这段做的是:定义缺口半径变量,用两个径向渐变作为遮罩层,透明部分被剔除,再用 mask-composite: intersect 取两层交集,两侧各留一个半圆缺口。

写法 能否透光 能不能留阴影 兼容性
clip-path 可以 阴影会被裁掉 最好
radial-gradient 可以 可以,但要另加元素 好
mask 可以 可以 中等,需注意前缀

三条路都能做出缺角卡片,缺角卡片的实际选型只取决于两件事:卡片背后是否有背景图(有就必须透光),以及是否需要阴影(需要就避开 clip-path)。

三种写法在透光性阴影保留与代码量上的对比

四、三个高频坑与验证清单

4.1 坑一:加了 clip-path 之后阴影消失

clip-path 裁剪的是整个元素的可视区域,阴影属于被裁范围。修复办法是把阴影挪到外层容器上,或者改用 filter: drop-shadow(),它按裁剪后的实际形状生成阴影。

.card-wrap {
  filter: drop-shadow(0 4px 12px rgba(254, 106, 0, 0.18));
}
.coupon {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 0 60%, 12px 50%, 0 40%);
}

这段做的是:外层容器负责投影,内层负责裁剪。预期结果(未在本机执行,依据 drop-shadow 的定义)是阴影沿着裁剪后的轮廓生成,而不是被裁掉。

4.2 坑二:两个半张卡片接缝处有细线

缩放时浏览器会把 50% 宽度算出小数,两张卡片之间露出一条缝。修复办法是把宽度设成 51% 让它们略微重叠。

4.3 坑三:mask 遮罩在部分浏览器无效

旧版浏览器需要 -webkit-mask 前缀,且 mask-composite 的属性名曾是 -webkit-mask-composite,取值也不同。修复办法是两条都写,或者退回第二种方案。

4.4 验证清单

  • 检查:缺口是否真的透光(把卡片放到带背景图的容器上试)
  • 运行:改一次缺口半径变量,看两侧是否同步变化
  • 预期:三种写法都能得到两侧半圆缺口
  • 失败:缺口是方角 → 检查 radial-gradient 的圆心位置
  • 失败:整块卡片消失 → mask-composite 写错,遮罩把全部内容剔除了
  • 修复:调整圆心坐标或补浏览器前缀
  • 验证:在缩放 110% 与 90% 下各看一次,确认接缝无细线

总结

缺角卡片有三种写法:clip-path 最短但会裁掉阴影,radial-gradient 是优惠券样式的标准答案,mask 最灵活但要处理前缀。选型只看两件事——缺口要不要透光、卡片要不要阴影。

三条要点带走:

  • 需要阴影就别用 clip-path,改用外层的 drop-shadow;
  • 半圆缺口靠渐变硬边界实现,两个色标要落在同一位置;
  • 两个半张卡片之间留 1% 重叠,避免缩放出现接缝。

下一步建议把缺口半径和颜色抽成 CSS 变量,一张卡片就能适配全站。属性细节记不住时,翻 CSS 属性参考手册 最快。

常见问题

Q:为什么用了 clip-path 之后卡片阴影不见了?

A:clip-path 会裁剪整个元素的可视区域,阴影也在其中。改用外层的 filter: drop-shadow,阴影会按裁剪后的轮廓生成。

Q:怎么让缺角后面透出背景图?

A:用 radial-gradient 或 mask 这两种方案,它们挖出的是真正的透明区域。clip-path 裁剪后同样是透光的,但它会连阴影一起裁掉。

Q:优惠券样式中间那条虚线怎么画?

A:用伪元素画一条高度为卡片一半、左边框为 dashed 的竖线,再用 margin: auto 垂直居中即可。

Q:mask 属性写了没效果是怎么回事?

A:多半是缺浏览器前缀,或者 mask-composite 取值不对。旧版用 -webkit-mask-composite,取值与标准写法并不一致。

延伸学习

想把卡片与遮罩这块补齐,可以按这个顺序来:

  1. 读一篇相关笔记 卡片溢出排错笔记,把最小宽度与换行规则理清;
  2. 想系统学,前端实战配套课程 是从基础到项目的完整路线;
  3. 想调投影细节,用 阴影生成器工具 直接出代码。

0 人点赞