Skip to content

✂️ 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✅ 是⚠️ 视浏览器/版本而定❌ 中偏低⭐⭐某些场景有效,但 maskdrop-shadowpolygon 三者叠加兼容性差,不适合通用方案

📌 开发建议

  • 最推荐方式:使用父元素添加 filter: drop-shadow,子元素使用 clip-path 实现形状。该方式稳定、通用,且易维护。
  • ⚠️ SVG 方案存在兼容性问题
    • 在 Chrome、Edge、Safari 等浏览器中,对于 SVG 的 clipPathmask 配合 CSS 滤镜(如 drop-shadow)时经常不生效,尤其当这些定义是通过 <svg> 标签放置于页面 DOM 中,而非内联嵌入 style 时。
    • 实际测试中,大多数现代浏览器并不会为 clip-path 生成后的形状应用阴影滤镜,这使得 SVG 的裁剪 + 阴影方案理论正确但实际失败

🔚 结论

想让不规则图形有阴影,稳定、跨浏览器的唯一推荐方式还是 —— filter: drop-shadow(...) 放到未裁剪的父元素上。

如无特殊场景,不建议尝试 SVG + 滤镜组合方案用于线上 UI,除非对兼容性影响已充分测试并可控。

Released under the MIT License.