跳到主要内容

新拟物 (Neumorphism) 双阴影原理与对比度避坑指南

新拟物靠同色系背景加一明一暗两道阴影在表面上雕出立体感, 本文讲清双 box-shadow 亮暗各一的算法, 直面它对比度天生不达标的无障碍争议, 并给出可直接复制的 CSS。

发布于 作者 李雷
#新拟物 #neumorphism #css #软ui #无障碍

新拟物 (Neumorphism) 双阴影原理与对比度避坑指南

新拟物这个词 2020 年从 Dribbble 火起来, 那种按钮看上去像是从背景里"鼓"出来的, 又软又有触感。我第一次照着 Dribbble 图往 CSS 里搬的时候, 做出来的东西像一块灰糊糊的矩形, 完全没有那股软劲。后来才搞明白, 它的核心根本不是某个神奇属性, 而是两件事配合: 同色系, 加一明一暗两道方向相反的阴影。这篇就把原理拆开讲清楚, 顺带聊一下它那个绕不开的对比度争议。

同色系: 形状和背景共用一个颜色

新拟物第一条铁律是: 形状本身没有自己的填充, 它的颜色就等于所在背景的颜色。听起来反直觉, 但这正是"从表面里抠出来"这个错觉的命根子。一旦你给形状换一个明显不同的填充色, 两道阴影立刻就不再像是"雕"出来的, 而变成"围着一块染色板的两个无关阴影"。

实践里允许微调, 但幅度很小。把形状色相对背景色拨 ±5% 加一点点色温是安全的, 有些马卡龙配色的 kit 会刻意暖那么一点点。可一旦偏到 ±10%, 软 UI 的错觉就崩了。所以你看到的所有靠谱新拟物组件, 形状色和背景色都贴得极近。

双阴影: 亮暗各一, 方向相反

这是整套风格最核心的算法。真实世界里一个凸起的物体在定向光下, 朝光那一侧有高光, 背光那一侧有阴影, 两边同时存在。只放一道阴影, 视觉上就只是"一块带投影的平板"; 必须两道, 一明一暗, 偏移方向相反, 眼睛才会读出圆润的体积。

假设光源在左上, 那么左上角应该放一道亮阴影 (高光), 右下角放一道暗阴影 (凹陷)。写成 CSS 就是一个 box-shadow 里塞两组值, 用逗号隔开:

.neumorphic-button {
  background: #e0e5ec;
  border-radius: 16px;
  box-shadow:
    -6px -6px 12px rgba(255, 255, 255, 0.7),  /* 左上, 亮高光 */
     6px  6px 12px rgba(163, 177, 198, 0.6);  /* 右下, 暗凹陷 */
}

注意两道阴影的偏移是镜像的: 一个 -6px -6px, 另一个 6px 6px; 颜色一个偏白, 一个偏深灰。这两点必须同步, 否则就会出现"一道在右下、另一道也在右下"这种自相矛盾的结果, 立体感直接消失。这也是手写时最常翻车的地方: 复制的时候只贴了两行里的一行。用 新拟物生成器 把光源、偏移、alpha 绑在同一个方向上算好, 就不会出现两道阴影打架的情况。

凸 (outset) 和凹 (inset) 的区别也在这里。凸是上面这种, 按钮从表面凸出来; 凹是给两道阴影都加上 inset 关键字, 把光照反过来, 左上变暗右下变亮, 整个区域看上去像被往下按出一个浅凹槽。凸用于按钮和卡片, 凹用于输入框, 或者按钮的"按下"态。

绕不开的争议: 对比度天生不达标

讲完好看的部分, 必须直面新拟物最大的硬伤: 无障碍。

这不是某个工具的 bug, 是风格本身的结构性问题。新拟物要求表面、背景、文字都落在同一个明度区间附近, 才能出那种软按下的感觉。可这恰恰意味着, 文字和背景的对比度天然会塌到接近 1:1。WCAG AA 对正文的要求是 4.5:1, 大字是 3:1, 而一颗典型的浅灰新拟物按钮上放浅灰文字, 实测往往连 2:1 都摸不到。

我自己踩过这个坑: 一套做得挺漂亮的 Soft UI 主题, 装饰卡片和图标都没问题, 一上正文和输入框文字就全挂, 上线前做无障碍审计被整批打回。所以这套风格不能闭眼用。务实的做法有三条:

  • 把文字色单独加深, 不跟着表面走同色系;
  • 换成带 3:1 描边的纯图标按钮, 避开文字对比度;
  • 把新拟物只留给装饰性表面, 正文区另用高对比度文案。

生成器里有一条实时的 WCAG 红字警告, 预览文字一旦跌破 4.5:1 立刻提醒。别等审计才发现。如果你想更系统地比对各种阴影方案的可读性, 也可以配合 CSS 阴影生成器 一起调, 把高对比方案和软 UI 方案放在一起看。

一段可直接用的输入输出例

给个完整可跑的例子。输入: 背景色 #e0e5ec, 圆角 16px, 光源左上, 凸模式, 距离 6, 模糊 12。输出的就是上面那段 CSS, 直接贴进组件文件即可。要做配套的凹输入框, 只需把两道阴影都加 inset, 并把亮暗对调:

.neumorphic-input {
  background: #e0e5ec;
  border-radius: 12px;
  box-shadow:
    inset  6px  6px 12px rgba(163, 177, 198, 0.6),
    inset -6px -6px 12px rgba(255, 255, 255, 0.7);
}

凸按钮配凹输入框, 就是经典的"凸按钮 + 凹输入框"对比, 整个表单的物理触感一下就出来了。

新拟物不是适合所有场景的风格, 它好看, 但代价是无障碍。把双阴影的算法和对比度的红线都想清楚再用, 它就是个很有质感的工具; 闭眼套, 它就是个审计黑洞。


Made by Toolora · Updated 2026-06-13