多层box-shadow为何变方形?如何用单属性完成CSS Battle挑战
我在做CSS Battle第94题,原本打算用带边框的圆形div,通过多层box-shadow绘制中心圆周围的所有同心圆,但第5层box-shadow(0 0 0 51px #F3AC3C)不再是规则圆形,开始呈现方形。
我已经通过添加另一个带边框的圆形元素,结合两组box-shadow完成了挑战,但希望仅使用单个box-shadow属性实现效果,不用多个元素或radial-gradient。想找出问题原因并得到修复方案。
原代码示例
body { height: 200px; width: 400px; background: #0E2E2C; display: grid; place-items: center; } div { width: 40px; height: 40px; background: #F3AC3C; border: 8px solid #0E2E2C; border-radius: 100%; box-shadow: 0 0 0 12px #F3AC3C, 0 0 0 22px #0E2E2C, 0 0 0 32px #998235, 0 0 0 44px #0E2E2C, 0 0 0 51px #F3AC3C, /* 这一层开始变方 */ 0 0 0 63px #0E2E2C, 0 0 0 68px #F3AC3C; }
<div></div>
问题原因
box-shadow的扩展半径基于元素盒模型尺寸计算,阴影会直接继承原元素的border-radius值。原元素总尺寸是40px + 2×8px = 56px,border-radius:100%对应的圆角半径仅为28px。当box-shadow扩展半径增大到51px时,阴影总尺寸变为56px + 2×51px = 158px,此时28px的圆角半径相对于158px的尺寸过小,圆角曲率被拉伸,视觉上就趋近于方形了。
修复方法
只要让原元素的border-radius足够大,确保所有扩展后的阴影边缘都能保持圆形即可,有两种简单方案:
方案1:设置超大圆角半径
直接将div的border-radius设为9999px,不管扩展半径多大,阴影都会保持圆形:
div { width: 40px; height: 40px; background: #F3AC3C; border: 8px solid #0E2E2C; border-radius: 9999px; /* 替换原100% */ box-shadow: 0 0 0 12px #F3AC3C, 0 0 0 22px #0E2E2C, 0 0 0 32px #998235, 0 0 0 44px #0E2E2C, 0 0 0 51px #F3AC3C, 0 0 0 63px #0E2E2C, 0 0 0 68px #F3AC3C; }
方案2:精确计算圆角半径
所需最小圆角半径 = 原元素半宽 + 边框宽度 + 最大box-shadow扩展半径,即20px + 8px + 68px = 96px,设置border-radius:96px也能达到效果:
border-radius: 96px;
这样修改后,所有层级的box-shadow都会保持完美圆形,无需额外添加元素。
内容的提问来源于stack exchange,提问作者j-0-n-e-z

