CSS 边框阴影最核心的属性是 box-shadow。它可以在元素边框外部生成一层或多层阴影效果,让原本平面的界面元素产生悬浮感、凹槽感或边界提示。与 border 不同,阴影不会改变元素的布局尺寸,也不会触发文档回流,是实现视觉层级的重要工具。本文将围绕基础参数、多阴影叠加、内阴影以及性能选择展开,确保你在实际项目中能快速写出符合预期的阴影代码。

一、box-shadow 基础语法:每个数值到底控制什么
先看一个最常用的声明:
.box {
box-shadow: 10px 10px 20px 0 rgba(0, 0, 0, 0.3);
}
这里共有四个长度参数和一个颜色。第一个 10px 是水平偏移,正值向右,负值向左;第二个 10px 是垂直偏移,正值向下,负值向上。第三个 20px 是模糊半径,它决定阴影边缘的柔化程度,值越大阴影越模糊、过渡越自然。第四个 0 是扩展半径,它会整体放大或缩小阴影范围,正值向外扩展,负值向内收缩。颜色部分通常使用 rgba() 或十六进制写法,带上透明度能让阴影更贴近真实光源。
如果不写模糊半径和扩展半径,只写两个偏移量和颜色,浏览器也会正常解析,例如 box-shadow: 4px 4px #ccc;。不过这种写法生成的阴影没有柔化,边缘与元素轮廓完全一致,视觉上类似一层错位的底色。实际项目中建议至少保留模糊半径,因为模糊是阴影产生空间感的关键。扩展半径看似使用较少,但在需要精确控制阴影面积、模拟描边或做多层扩散效果时非常实用。例如把扩展半径设置成负值,可以让阴影向内收缩。
另一个容易忽略的细节是,box-shadow 默认绘制在元素边框外部,并且不会占据任何布局空间。你可以把它理解为元素外观上的一层附着效果,虽然视觉上扩大了元素范围,但不会影响相邻元素的排列。也正因为它不参与布局,阴影无法触发元素尺寸变化,只能通过视觉强化边界。对于需要精确对齐的布局,记得不要把阴影宽度计入实际尺寸。
二、多阴影叠加与内阴影:实现复杂层次
单个阴影往往难以模拟真实物体的多层光影。CSS 允许在同一个 box-shadow 属性中用英文逗号分隔多组阴影,浏览器会按照书写顺序从后向前绘制。也就是说,先写的阴影显示在最上层。借助这一点,可以用几个小而清晰的阴影叠加出更自然的投影效果,而不是单纯调大模糊半径。
.card {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.08),
0 4px 12px rgba(0, 0, 0, 0.12),
0 12px 32px rgba(0, 0, 0, 0.16);
}
上面的卡片阴影由三层组成:第一层模拟紧贴表面的接触阴影,偏移和模糊都很小;第二层加强中间过渡;第三层提供大范围的环境投影。这种分层写法比单个 0 12px 32px rgba(0, 0, 0, 0.2) 更自然,因为真实环境中物体与背景的距离会产生不同强度的阴影。代码虽然长了一点,但可读性强,后续调整某一层也不会影响其他层。
内阴影使用 inset 关键字,写在任何一组阴影参数的最前面或最后面都可以,但建议统一放在最前面。内阴影从元素边框向内绘制,适合模拟凹陷、内嵌边框或输入框焦点状态。例如给输入框加一圈蓝色内阴影,可以在不改变 border 宽度的情况下增强视觉反馈。
.input {
border: 1px solid #d1d5db;
outline: none;
}
.input:focus {
box-shadow: inset 0 0 0 1px #2563eb;
}
这里 inset 0 0 0 1px 表示偏移和模糊都为 0,扩展半径 1px,颜色为蓝色,形成一圈清晰的内部描边。因为 box-shadow 不参与布局,所以 border 宽度保持 1px,元素尺寸不会变化,避免了加入 border 后可能引起的挤压或跳动。多个内阴影也可以与外部阴影混合使用,只需要用逗号分隔即可,注意书写顺序会直接影响叠加效果。
三、box-shadow 与 filter: drop-shadow 的区别及选型
CSS 中还有一个经常被拿来和 box-shadow 比较的属性:filter: drop-shadow()。虽然两者都能生成阴影,但作用机制不同。box-shadow 只围绕元素的矩形边框盒绘制,即使元素内部是透明背景或形状不规则,阴影也仍然是矩形的。而 drop-shadow 是滤镜,它会根据元素实际渲染出来的像素轮廓生成阴影,包括透明区域和不规则形状。
.icon {
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3));
}
比如给一张透明背景的 PNG 图标加阴影,使用 box-shadow 会出现一个矩形阴影块,完全不符合预期;而 drop-shadow 会沿着图标的形状生成投影。对于 <img>、<svg> 或带 clip-path 的容器,想要获得贴合形状的阴影时,应该选择 drop-shadow。但它作为滤镜恢复成本更高,在动画中大量使用可能造成性能下降,不建议在移动端对大面积元素频繁执行。
box-shadow 在静态元素上的性能通常较好,但如果给滚动容器中的大量子元素添加高模糊半径阴影,也可能导致滚动时重绘开销上升。优化方式包括减少阴影层数、降低模糊半径、使用 CSS 变量统一管理阴影,以及避免在滚动区域内的每个元素上都使用大范围阴影。如果阴影只用于装饰,可以优先考虑用 background 渐变或边框模拟,而不是真实阴影。
现代浏览器对 box-shadow 的支持已经非常完整,使用时不需要添加厂商前缀。项目中建议将常用阴影抽成 CSS 变量,统一维护设计系统中的层级关系。例如:
:root {
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.16);
}
.btn {
box-shadow: var(--shadow-sm);
transition: box-shadow 0.2s ease;
}
.btn:hover {
box-shadow: var(--shadow-md);
}
.modal {
box-shadow: var(--shadow-lg);
}
这些变量可以把阴影从零散的样式声明中抽离出来,方便后续统一调整。像按钮悬停时从 --shadow-sm 切换到 --shadow-md,再配合 transition 就能形成平滑的悬浮反馈。掌握 box-shadow 的偏移、模糊、扩展、颜色以及多阴影和内阴影用法后,绝大多数界面层级需求都可以快速实现,也能在选择 drop-shadow 时做出更合理的性能判断。
CSS边框阴影box-shadow属性阴影效果修改时间:2026-10-06 09:28:03