跳转到主内容
◆ 文章 · Article

Strata 设计系统改造记录

把一套扁到没有区分度的界面,重做成「五级表面 + 八条色相轨道」的分层语言:样式仍然是一份 CSS,但每一块内容都重新有了位置。

Astro CSS 设计系统
[ 00 ]

目录

按章节顺序排列,点击直接跳转。

  • 4 个章节
  • 约 6 分钟

建议先浏览组件库 demo 页,再对照本文的分层与拆分思路阅读。

[ 01 ]

分层与色相

层次不是装饰,是结构:五级表面 + 一条独立凹槽层

改造的起点是一个很具体的不满:页面上的每一块内容看起来都一样重。 卡片、表格、引用、注释全是同一个灰底加一条边框,滚动时找不到断点, 读者只能靠标题字号勉强分辨段落。这是扁平化最常见的副作用 —— 层次被删掉之后,没有东西替它说话。

Strata 的答案是把层次做成可读的信息,而不是用装饰去补。 两件事:一是给表面分级,二是给区块上色。

表面分成五级 —— void / base / surface-1 / surface-2 / surface-3,再外挂一个比页面更暗的 inset 凹槽层。所有结构都由明暗和 1px 发丝线承担, 静态面板一律不加投影 —— 边框和阴影同时出现,边界就糊了。

区块则各自拥有一条色相轨道,色相只出现在三个地方:等宽序号徽标、分区顶部的发丝线、 底色的柔和染色。相邻分区永不共享底色,所以滚动时每一段都有明确的入口和出口。

css strata.css

      /* 语义 token —— 组件不直接引用原始色值 */html.strata-root {  --base:      #060b14;  --surface-1: #0b111f;  --surface-3: #161f33;  --line:        rgba(255,255,255,.09);  --line-strong: rgba(255,255,255,.17);  --accent:    #3b82f6;   /* 主色:蓝 */} /* 所有组件规则作用域在 .strata 内,0,1,1 稳压站点全局的 0,1,0 */.strata .btn { background: var(--accent); color: var(--accent-ink); }
  
  • [*]band treatments6
  • [*]section hues8
  • [*]surface levels5 + inset
  • [*]hairline weights3
  • [*]hovercolour swap, no tween

“扁平不是把层次删掉,而是把层次画得更准确。发丝线就够了,不必再加一道阴影。”

[ 02 ]

组件拆分

30 个组件,四层职责,同一套类名契约

按区块边界拆成 30 个组件:基础组件负责视觉,交互组件负责行为, 全部通过 props 暴露配置项,并沿用同一套类名契约,避免正文样式塌陷。

  • 表面层:Panel / Card / StatCard / GlassTable / ListGroup
  • 结构层:Band / SectionHeading / SpecList / Divider / KeyCap
  • 交互层:Modal / Toast / Tooltip / Dropdown / Tabs / SearchBox
  • 反馈层:Alert / Progress / Spinner / Skeleton / Empty / StatusIndicator
  • 骨架层:ArticleShell / ArticlePart / Sidebar / EdgeRail
Band Panel CodeBlock Terminal
[ 03 ]

交互运行时

一次事件委托,全部由属性声明驱动

页面上不需要手写任何 JS:打开弹窗、弹 toast、切换下拉、复制代码、排序表格, 全部靠 data-strata-* 属性声明,运行时在 document 上做一次事件委托。 键盘语义是完整的 —— 弹窗焦点圈闭、Esc 关闭并还焦、tablist 方向键漫游、命令面板 ↑↓ 选择。

html usage.astro

      <!-- 交互靠 data-strata-* 属性声明,页面不写一行 JS --><Button data-strata-open="confirmModal">打开弹窗</Button><Button data-strata-toast="已保存">保存</Button><CodeBlock code="npm i" />   <!-- 复制按钮自动就位 --> <!-- 打字机 / 数字滚动 / 滚动揭示同样是属性驱动 --><span data-strata-type data-words='["A","B"]'>A</span><span data-strata-count="128">0</span><div class="pg-reveal">进入视口时淡入</div>
  
命令面板⌘K
关闭浮层ESC
[ 04 ]

明暗主题

只换一组语义 token,组件里没有 dark: 变体

主题只改一组语义 token,组件内部一个 dark: 变体都没有。 暗色是默认,选择写入 localStorage, 并由一段放在样式表之前的内联脚本恢复 —— 所以刷新时不会闪白。 想直接分享某个主题,加一个 ?mode=light 就行。

切换的瞬间会挂上 260ms 的整体淡变:只过渡颜色类属性, 位移动画与「悬停不补间颜色」的规则都不受影响。

data-mode localStorage no dark: variants

整套系统最后压进 2.1kb 的 CSS(gzip)。真正让它「不糊」的不是新组件, 而是那些看起来很琐碎的决定:三层发丝线、六个底色、八条色相, 以及一条不肯让步的规则 —— 悬停只换色,不做过渡。

评论区 留下您的想法
教程