box-shadow 完全不计入盒模型,仅是渲染层的视觉叠加,不影响布局流、不触发重排、不改变元素实际尺寸;常见“占位”错觉源于 overflow: hidden、border-radius 配合不当、视觉膨胀或 border 与 box-sizing 混用。
直接回答:box-shadow 完全不计入盒模型(content + padding + border + margin),它只是渲染层的视觉叠加,不影响布局流、不触发重排(reflow)、也不会撑开父容器或挤压兄弟元素。
这意味着:
width: 200px; height: 100px; 的 div 加上 box-shadow: 0 0 30px rgba(0,0,0,0.3);,它的实际占用空间仍是 200×100,滚动条不会出现,相邻元素位置丝毫不动;box-shadow: 0 0 0 50px #000; 模拟粗边框),元素的 getBoundingClientRect() 返回的宽高也完全不含阴影;offsetWidth、clientWidth 或用 getComputedStyle(el).width 都拿不到阴影信息——它压根不在盒模型里。所谓“box-shadow 占位”,其实是其他 CSS 行为造成的视觉干扰,和 box-shadow 本身无关:
overflow: hidden:内阴影(inset)可能被裁剪,误以为“被挡住”,其实是容器主动截断;border-radius 但没配好 overflow:圆角+外阴影本该自然延伸,但如果父级有 overflow: hidden,阴影会被硬切,显得“不完整”;box-shadow: 0 0 10px #fff 在暗背景下会“发虚”,让人误判边界;border 混用时未重置 box-sizing:如果同时写了 border: 2px solid 和 box-shadow,而没设 box-sizing: border-box,那 border 本身就会额外增加尺寸——这时“变大”的是 bor
der,不是 shadow。当想避免 border 占据布局空间(比如卡片需要精确 300px 宽,又想要“边框感”),box-shadow 是更干净的选择:
.card {
width: 300px;
height: 200px;
background: white;
/* ✅ 用 shadow 模拟 1px 边框,不占空间 */
box-shadow: 0 0 0 1px #ddd;
/* ❌ 不要再写 border: 1px solid #ddd —— 它会让实际宽度变成 302px */
}进阶技巧:
box-shadow: 0 0 0 1px #ccc, 0 0 4px rgba(0,0,0,0.08);
border-radius,box-shadow 会自动贴合形状,无需额外处理;rem 或 em 控制 spread 值(第四个参数),比固定 px 更灵活。box-shadow: inset ... 虽然也不影响尺寸,但容易因容器限制失效:
overflow: hidden 会直接吃掉内阴影——哪怕阴影本应在内容区内;padding 不足时,inset 阴影可能紧贴文字,显得拥挤;建议至少留 padding: 8px 再加 inset 0 1px 2px rgba(0,0,0,0.1);inset 阴影能“穿透”子元素:它只作用于当前元素的背景层,子元素会盖在它上面。真正容易被忽略的,是「阴影的渲染时机」——它发生在绘制阶段(paint),晚于布局(layout)和合成(composite)。所以哪怕你用 JS 动态改 shadow,只要不触发 layout,性能就极轻。但若同时改了 width 或 margin,那就另当别论了。