web design uiNovember 5, 20267 min read

UI 阴影:为什么 25% 黑色投影看起来不对,以及该用的分层阴影

25% 的黑色阴影看起来就像卡片下面的一团污渍。柔和阴影为什么只用约 8% 的不透明度、两层叠加和一点染色,层级高度该如何递增,以及四个可直接用的 CSS 阴影 token。

By Boone
XLinkedIn
UI Shadows: Why the 25% Black Drop Shadow Looks Wrong and the Layered Shadows to Use

大多数设计师伸手就拿的阴影是 25% 的黑色。在这个强度下,它不像光,而像卡片下面的一团污渍。

好阴影几乎是隐形的:你先感到卡片被托起,然后才看到阴影。下面讲怎么做到,并附四个可以直接复制的 token。

为什么默认值看起来像污渍

Figma 默认的投影是 25% 不透明度的黑色,向下偏移 4。两个常见教程都照搬了它,于是它到处传播:工具的默认值就这样变成了没人做过的设计决策。

真实的阴影是柔和的。光会绕着物体弯折,所以阴影的边缘是逐渐淡出的,离物体越远越淡。单独一层生硬的深色阴影完全没有这些特征。它只有一条边和一种强度,眼睛会把它读成脏东西,一块灰色污渍,而不是一个被抬起的表面。

修正 1:用 8%,不是 25%

25% 黑色

Mia Chen(产品设计师)的个人资料卡片,下方有一道深色、紧凑的阴影

8% 黑色,更大的模糊

同一张卡片,阴影非常柔和、宽大,几乎看不见
同一张卡片,同一个底色。左边的阴影是卡片上最吵的东西。右边是一层柔和的抬升,你看的是内容。降低不透明度只是一半的修正,让模糊变大是另一半。

模糊变大后,同样多的阴影被摊到更大的面积上,自然就变淡了。这就是为什么 8% 的宽阴影比 8% 的紧阴影看起来更自然。从 8% 开始,只有当卡片在你的背景上消失时才往上调。

修正 2:叠两层阴影

浅灰底上的三张白色卡片,标注为紧凑、宽大和两者。紧凑的卡片有一道细线阴影,宽大的卡片有一圈柔和光晕,第三张两者兼有
左:紧凑(0 1px 2px,6%)。中:宽大(0 8px 24px,8%)。右:两者叠加。

一层阴影要同时干两份活,结果两份都干不好。两层阴影把活分开。

紧凑的那层贴在边缘下面,说的是“它贴着表面”。宽大的那层是柔和的光晕,说的是“它被抬离了表面”。合在一起,它们就像一层自然的阴影,因为真实的光就是这样:一条深色的接触线,加上一片宽阔而淡的衰减。

在 CSS 里,两层只是一条声明,用逗号隔开:

css
box-shadow: 0 1px 2px rgba(27, 21, 48, 0.06), 0 8px 24px rgba(27, 21, 48, 0.08);

修正 3:给它染色,别把它灰掉

纯黑

浅紫色背景上的白色卡片,带灰色阴影

用墨色染色

同一张卡片,带紫色阴影,与背景融为一体
纯黑混进彩色背景,会让它变灰变脏。用背景自身色相的深色做阴影,则保持干净。这里两个阴影都是 16%,所以唯一的差别就是颜色。

规则是:用你的墨色,也就是调色板里最深的颜色,作为阴影颜色,并保持低不透明度。在我们自己的 token 里,墨色是 #1B1530,一种很深的紫色。在白色页面上,这层染色很难看出来。在彩色页面上,比如品牌面板或有底色的区块,它就是“阴影属于这里”和“阴影像是贴上去的”之间的差别。

修正 4:越高,越大

四张白色卡片,标注为 XS、SM、MD 和 LG,每张都比前一张抬得更高,阴影越来越大、越来越柔和
四个层级。阴影随高度变大,强度始终保持很低。

当一个东西位置更高,比如卡片上方的菜单、页面上方的弹窗,它的阴影会更大更柔和,因为光有更多空间扩散。它不会变得更深。要是设计师把更高元素的阴影做得更深,最后又回到了那团污渍。

这就得出一组小而封闭的 token:

Token第 1 层第 2 层用于
XS0 1px 2px, 6%无输入框、小标签
SM0 1px 2px, 6%0 2px 6px, 8%静止状态的卡片
MD0 1px 2px, 6%0 8px 24px, 8%抬起的卡片、弹出层
LG0 2px 4px, 6%0 16px 40px, 12%弹窗、位于最上层的菜单

每一层都使用 X 为 0、扩展为 0,颜色为墨色 #1B1530。Figma 的 X、Y、模糊和扩展字段,直接对应 CSS box-shadow 里的四个数字。

作为 CSS 的 token

css
:root { --shadow-xs: 0 1px 2px rgba(27, 21, 48, 0.06); --shadow-sm: 0 1px 2px rgba(27, 21, 48, 0.06), 0 2px 6px rgba(27, 21, 48, 0.08); --shadow-md: 0 1px 2px rgba(27, 21, 48, 0.06), 0 8px 24px rgba(27, 21, 48, 0.08); --shadow-lg: 0 2px 4px rgba(27, 21, 48, 0.06), 0 16px 40px rgba(27, 21, 48, 0.12); } .card { box-shadow: var(--shadow-md); }

这四个是我们的推荐值,不是平台标准值。把墨色换成你自己最深的品牌色,结构保持不变。

阴影失效的地方:深色模式

深色上的阴影

深色背景上的深色卡片,带一大片阴影,几乎看不见

更浅的表面

深色背景上的同一张卡片,靠更浅的表面颜色而非阴影变得可见
阴影会把它后面的东西变暗,而深色背景已经没多少可以变暗的了。左边的大阴影看不见,卡片融进了页面。右边的卡片只是一个更浅的表面,而这才是把它抬起来的东西。

所以在深色主题里,要抬高一个层级,就把它变浅,而不是给它加阴影。我们那篇关于深色模式配色系统的文章讲了表面色阶,而浅色模式背景色则讲了另一侧的灰色。

眯眼测试

眯起眼睛看屏幕,或者退后几步。如果你还能把每道阴影看成一块深色形状,那就太强了。如果在你最差的显示器上卡片边缘消失了,就把不透明度往上调一档。对的阴影,直视时消失,拿掉时才显现。

FAQ

UI 里最好的投影是什么?

用你自己墨色的深色调叠两层:一层紧凑的,比如 0 1px 2px、6%;一层宽大的,比如 0 8px 24px、8%。它读起来是自然的光,而不是污渍。

UI 阴影的不透明度应该是多少?

我们的四个 token 在 6% 到 12% 之间。卡片从 8% 开始,只有边缘消失时才往上调。25% 的黑色是常见默认值,但在干净的界面上很少合适。

Figma 默认的投影是什么?

黑色(#000000),25% 不透明度,向下偏移 4。这只是工具的起点,不是设计决策,所以大多数设计改掉它都会更好。

阴影应该是纯黑吗?

不。用品牌色或墨色的极深版本。在彩色背景上,纯黑会让阴影发灰发脏,而染色阴影能保持颜色干净。

怎么用阴影表现层级高度?

让更高元素的阴影更大更柔和,而不是更深。使用一小组 token,比如 XS、SM、MD 和 LG,让界面的每一层都只用这四种阴影之一。

阴影在深色模式里有用吗?

效果很差。能被变暗的浅色背景所剩无几,所以大阴影会消失。改为给该层一个更浅的表面颜色来抬高它。

怎么在 CSS 里写分层的 box-shadow?

在一条 box-shadow 声明里列出各层,用逗号分隔:box-shadow: 0 1px 2px rgba(27,21,48,.06), 0 8px 24px rgba(27,21,48,.08);。

来源

  • Figma 默认的投影是 #000000、25% 不透明度、X 0、Y 4。各教程在 25% 黑色上一致,但对默认模糊值说法不一,所以本文从不提它。
  • #00000040 是 8 位十六进制下 25% 的 #000000(0x40 即 255 中的 64,约 25%)。
  • 四个 token 和墨色 #1B1530(violet 900)来自我们的 UX Brainy 效果样式。它们是推荐值,不是平台标准值。
  • 上面的卡片是我们自己的示例。染色演示用的是 16% 的 #4E2FB3,对比 16% 的黑色。
  • 更多像这样的一条规则帖子,见 UX Brainy。

Want a design system where shadows, spacing and color are decided once and used everywhere? Our team designs and builds product UI on tokens.

Get Started

More from Brainy Papers

Keep reading