✂️ CSS 绘制自定义多边形及其阴影效果
🧩 使用 clip-path 绘制自定义多边形
CSS 提供的 clip-path
属性可以将任意 HTML 元素裁剪成不规则形状,非常适合做标签、气泡、对话框等视觉样式。最常用的方式是使用 polygon()
。
✅ 示例:绘制两个自定义多边形(在线预览)
完整代码:
- polygon(...) 接收一组顶点坐标,每个点都是百分比,基于元素自身宽高。
- 裁剪后,只有多边形内的区域会被显示,其余部分会被隐藏。
你可以使用在线工具快速生成形状: 🔗 Clippy — CSS clip-path maker
🌑 给多边形添加阴影效果
常规做法:使用 box-shadow
很多初学者会尝试用 box-shadow 添加阴影:
css
.label {
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.3);
}
完整代码:
🔸 问题:box-shadow 与 clip-path 无法配合使用。
- 因为 box-shadow 的阴影是基于元素的标准盒模型区域(即未裁剪前的矩形)来计算结果来渲染的,而不是多边形形状。
- 但由于 clip-path 是在阴影渲染完成后处理裁剪,它不仅裁剪了内容,还裁剪了阴影。
- 所以即使 box-shadow 生成了阴影,也会一起被裁剪。
- 所以最终你会发现根本看不到任何阴影效果。
改用 filter: drop-shadow
为了让阴影更贴合图形轮廓,可以尝试 filter: drop-shadow:
css
.label {
filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.4));
}
这个方法对带透明区域的 PNG 图像或 border-radius 形状效果很好。
完整代码:
🔸 问题:如果你用了 clip-path 裁剪图形,drop-shadow 生成的阴影也会被裁掉,导致阴影失效。
🤯 为什么 drop-shadow 在 clip-path 上无效?
这是因为 CSS 渲染顺序如下:
css
元素内容渲染 → 应用 filter(阴影)→ 应用 clip-path(裁剪)
渲染流程说明:
- 1️⃣ 元素绘制:元素整体渲染(无 clip)。
- 2️⃣ 应用 filter:应用 drop-shadow 等滤镜,阴影生成。
- 3️⃣ 应用 clip-path:最后执行裁剪,阴影也被裁掉!
也就是说:阴影先是渲染出来了,但之后又被 clip-path 给裁掉了!
✅ 正确方式:父元素包裹 + 添加 drop-shadow
解决方法非常简单 —— 将阴影应用在父元素上,裁剪留给子元素。
示例结构:
html
<div class="parent-box">
<div class="label">不良数量</div>
<div class="text02">SMT1产线</div>
</div>
css
/*
将阴影应用在父元素上,裁剪留给子元素,
阴影不会被裁剪,显示效果和多边形贴合。
*/
.parent-box {
filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.4));
}
完整代码:
✅ 阴影不会被裁剪,显示效果和多边形贴合
filter: drop-shadow() 放在 clip-path 元素的父级容器上,这样阴影会应用在整体轮廓上,而不会被裁掉。
🔬 进阶方式:使用 SVG clipPath + filter
若你需要更精细控制阴影(如模糊渐变、羽化边缘),可以使用 SVG 实现裁剪和阴影。
不推荐,有兼容性问题,需要根据实际情况选择。
🧾 各种多边形阴影实现方式对比总结(含兼容性分析)
方法 | 阴影贴合形状 | 阴影可见性 | 浏览器兼容性 | 推荐程度 | 备注说明 |
---|---|---|---|---|---|
✅ 父元素添加 filter: drop-shadow | ✅ 是 | ✅ 可见 | ✅ 高 | ⭐⭐⭐⭐⭐ | 最稳妥方案,阴影不会被裁剪,适用于所有主流浏览器 |
❌ 直接在 clip-path 元素上使用 drop-shadow | ✅ 是 | ❌ 阴影被裁剪 | ✅ 高 | ⭐ | 阴影渲染后再被裁剪掉,视觉上无效 |
❌ 使用 box-shadow | ❌ 否(按矩形边) | ❌ 阴影被裁剪 | ✅ 高 | ⭐ | 阴影不贴合形状,且也被 clip-path 裁剪掉 |
⚠️ SVG clipPath + drop-shadow | ✅ 是 | ⚠️ 大多数浏览器中不显示阴影 | ❌ 中(存在渲染 bug) | ⭐⭐ | 理论可行,但在实际 Chrome/Edge 中 drop-shadow 失效,不推荐线上使用 |
⚠️ SVG mask + drop-shadow | ✅ 是 | ⚠️ 视浏览器/版本而定 | ❌ 中偏低 | ⭐⭐ | 某些场景有效,但 mask 、drop-shadow 、polygon 三者叠加兼容性差,不适合通用方案 |
📌 开发建议:
- ✅ 最推荐方式:使用父元素添加
filter: drop-shadow
,子元素使用clip-path
实现形状。该方式稳定、通用,且易维护。 - ⚠️ SVG 方案存在兼容性问题:
- 在 Chrome、Edge、Safari 等浏览器中,对于 SVG 的
clipPath
或mask
配合 CSS 滤镜(如 drop-shadow)时经常不生效,尤其当这些定义是通过<svg>
标签放置于页面 DOM 中,而非内联嵌入 style 时。 - 实际测试中,大多数现代浏览器并不会为
clip-path
生成后的形状应用阴影滤镜,这使得 SVG 的裁剪 + 阴影方案理论正确但实际失败。
- 在 Chrome、Edge、Safari 等浏览器中,对于 SVG 的
🔚 结论:
想让不规则图形有阴影,稳定、跨浏览器的唯一推荐方式还是 —— 将
filter: drop-shadow(...)
放到未裁剪的父元素上。
如无特殊场景,不建议尝试 SVG + 滤镜组合方案用于线上 UI,除非对兼容性影响已充分测试并可控。