4491 字
12 分钟
yutsukarin 博客设计规范

本文是 yutsukarin 博客当前视觉语言的设计基线。它以 Material Design 3 为骨架,并针对壁纸、长文阅读和 Web 平台加入实时毛玻璃扩展。后续新增页面和组件应优先复用这里定义的语义、token 与交互规则。

1. 设计目标#

本站的视觉目标可以概括为四个词:柔和、清晰、真实、克制

  • 柔和:以淡粉动态主题为默认表达,避免高饱和色大面积争夺注意力。
  • 清晰:颜色承担语义,层级依靠色调、模糊和空间关系建立,不依赖廉价的细线框。
  • 真实:所有半透明表面都必须实时采样并模糊背后内容,不能只降低不透明度。
  • 克制:阅读内容始终优先。文章正文不漂浮、不抬升,装饰和动效不能干扰长文阅读。

本站不是照搬 Material 组件库,而是使用 MD3 的设计 token、色彩角色、形状、层级和动效思想,构建适合 Astro 的 CSS 设计系统。

2. 核心原则#

2.1 语义优先#

组件不得直接依赖固定色值,而应使用语义角色:

  • 主操作使用 primary 与 on-primary。
  • 强调容器使用 primary-container 与 on-primary-container。
  • 页面背景使用 surface。
  • 卡片与导航使用不同等级的 surface-container。
  • 正文使用 on-surface,次级说明使用 on-surface-variant。
  • 分割线只在确有结构意义时使用 outline-variant。

颜色必须成对使用。例如 primary 上的文本或图标使用 on-primary,容器表面上的内容使用 on-surface 或 on-surface-variant。

2.2 色调层级优先于描边#

MD3 主要通过容器色调表达层级。本站的卡片、顶栏、按钮和浮层默认采用 filled 或 elevated 语义,边框保持透明。只有输入框焦点、键盘焦点环、错误状态等功能性边界可以使用清晰描边。

2.3 壁纸与内容分离#

壁纸负责情绪与空间,内容表面负责可读性。两者通过真实毛玻璃建立联系,但壁纸纹理不能破坏正文对比度。

2.4 阅读表面不是按钮#

文章正文卡片是稳定的阅读平面:

  • 悬停时不得上移、缩放或改变深度。
  • 不能因鼠标经过而大幅改变亮度。
  • 链接、按钮、目录项可以有局部状态反馈。

3. 色彩系统#

默认主题色相为 345,即偏玫红的淡粉色。调色盘修改 —hue,其余颜色通过 OKLCH 和语义角色随之生成。

语义角色本站用途
—md-sys-color-primary当前状态、主操作、强调竖线、图标
—md-sys-color-primary-container选中项、强调容器
—md-sys-color-surface页面基础背景
—md-sys-color-surface-container-low低层级容器
—md-sys-color-surface-container普通卡片与导航
—md-sys-color-surface-container-high浮层和高强调区域
—md-sys-color-on-surface正文与主要标题
—md-sys-color-on-surface-variant元数据与次级说明
—md-sys-color-outline需要明确识别的功能边界
—md-sys-color-outline-variant必要的弱分割线

浅色和深色主题共享同一语义结构。固定品牌色只用于不承载关键可读信息的装饰;文本与交互状态必须随主题变化。

4. 实时毛玻璃#

毛玻璃是本站在 MD3 之外的重要视觉扩展。只设置半透明背景不算毛玻璃,合格表面必须同时具备:

background: var(--card-bg-transparent);
backdrop-filter:
blur(var(--glass-blur))
saturate(var(--glass-saturate))
contrast(var(--glass-contrast));
-webkit-backdrop-filter:
blur(var(--glass-blur))
saturate(var(--glass-saturate))
contrast(var(--glass-contrast));

4.1 模糊等级#

Token当前值使用场景
—glass-blur20px卡片、设置面板、主浮层
—glass-blur-soft14px顶栏、按钮、次级浮层、媒体控件
—glass-blur-subtle8px面板内部控件、轻量状态层
—glass-saturate1.72恢复模糊后的壁纸色彩
—glass-contrast1.04轻微增强背景分离

4.2 表面层级#

  • 主卡片使用 —card-bg。
  • 壁纸覆盖与全屏模式使用 —card-bg-transparent。
  • 设置面板等浮层使用 —float-panel-bg。
  • 面板内部控件使用 —glass-control-light 或 —glass-control-dark。
  • 独立卡片与浮层使用 —glass-blur,按钮、标签和内部控件使用 —glass-blur-subtle。
  • 同一视觉链路只允许最近的独立表面拥有实时模糊。嵌套控件不能穿透祖先的 backdrop root,因此必须使用不透明的 MD3 tonal surface,而不是继续叠加半透明背景制造“假玻璃”。
  • 模糊半径必须与表面尺寸匹配。窄顶栏和小控件不得使用会把整片壁纸平均成纯色色块的超大半径。

浏览器不支持 backdrop-filter 时,使用更不透明的 tonal surface 降级,保证文字对比度;不得用整体 opacity 代替,因为它会同时削弱内容。

4.3 全局玻璃契约#

任何能够看到其后方内容的前景表面,都必须进入统一的实时毛玻璃管线:

  • 通用组件使用 card-basefloat-panelbtn-cardbtn-regular,不得在组件里重新拼一份半透明样式。
  • 特殊表面使用 glass-realtime;用 glass-realtime--softglass-realtime--control 选择较轻的模糊等级。
  • 使用 —card-bg、—btn-regular-bg 或半透明主题色工具类的前景组件由公共规则自动适配,新增后仍需在复杂壁纸上实机检查。
  • 纯图片遮罩、渐变高光、阴影、文字透明度和 pressed/hover 状态层不是独立表面,不使用毛玻璃。需要显式排除时使用 glass-state-layer
  • 完全不透明的 MD3 tonal surface 可以使用 glass-tonal,但它不能同时保留可透出壁纸的 alpha 背景。
  • 浮层若由玻璃顶栏触发,必须通过 portal 移到顶栏外再渲染,否则即使计算样式存在 backdrop-filter,也无法采样真实壁纸。

检查时不能只看样式表里是否写了 backdrop-filter。必须在 600、840、1200 和 1600px 宽度下读取实际计算样式,并观察壁纸纹理经过表面时是否被实时模糊。

5. 形状系统#

Token数值用途
extra-small4px小提示、紧凑状态
small8px菜单、输入控件、标签
medium12px小卡片
large16px普通浮动组件
large-increased20px站点主卡片,即 —radius-large
extra-large28px对话框、侧边面板
full9999px按钮、图标按钮、徽章

组件不得散落任意圆角。头像使用圆角矩形,保持柔和但不强制裁成圆形;按钮优先使用 full,信息卡片使用 medium 或 large-increased。

6. 字体与排版#

内容推荐角色
首页横幅标题Display Large,并响应式缩放
文章标题Headline Large
卡片标题Title Medium
正文Body Large
卡片说明Body Medium
按钮与标签Label Large
元数据Label Medium 或 Body Small

正文保持约 1rem / 1.5rem 的基准节奏,长文行宽控制在约 65–80 个字符。数学公式、代码块和表格可以横向滚动,但不得撑破正文容器。

标题前的短竖线属于标题组件,不属于其后的日期或图标。标题隐藏时,竖线也必须一起隐藏,不能因绝对定位漂移到下一行。

7. 间距与响应式布局#

本站以 4px 为基础网格,以 8px 为主要节奏:

  • 组件内部:4、8、12、16、24px。
  • 组件之间:8、12、16、24px。
  • 段落和章节:24、32、48px。
  • 移动端页面边距:16px。
  • 平板与桌面页面边距:24px。
等级宽度博客布局
Compact小于 600px单栏文章流,辅助内容折叠或下移
Medium600–839px主内容优先,可出现第二栏
Expanded840–1199px主栏与辅助栏并置
Large1200–1599px复用 Expanded 的界面结构,仅展开顶栏文字
Extra-large1600px 以上延续同一结构并约束正文,不新增独立宽屏界面

首页属于 Feed 布局;文章页属于 Supporting Pane 布局。右侧统计、日历和目录都是辅助信息,窄屏下不得挤压正文。

8. 组件规范#

8.1 卡片#

  • 默认是 filled 或 elevated card,不使用装饰性一像素边框。
  • 静止层级使用 —md-elevation-1;真正浮起的菜单和面板使用 —md-elevation-2。
  • 普通内容卡片可在精确指针设备上轻微抬升。
  • 文章正文卡片永远保持静止。
  • 嵌套卡片通过 tonal surface 和间距区分,避免出现两层重复外壳。

8.2 按钮#

  • 主操作使用 primary filled。
  • 次操作使用 tonal 或 text button。
  • 图标按钮最小可交互区域为 48 × 48px。
  • 按钮不使用装饰性细边框。
  • hover 使用 8% 状态层,pressed 使用 12% 状态层。

8.3 顶栏#

  • 顶栏是高层级玻璃表面,必须实时模糊壁纸。
  • 默认没有轮廓细线。
  • 全屏或覆盖壁纸模式不能盖住顶栏。
  • 品牌头像使用圆角,并与站点名保持稳定间距。

8.4 设置与调色盘#

  • 设置面板位于普通卡片、目录和右栏组件之上。
  • 面板内部选项依靠填充与状态层区分,不使用大量矩形描边。
  • 设置面板在所有断点都从右上角以浮层覆盖内容,不因宽屏切换为独立 Supporting Pane,也不挤压正文;宽屏时其右边缘与顶栏右边缘对齐,保持触发器与浮层的空间来源一致。
  • 壁纸模式使用 2 × 2 填充选项组,选中状态同时使用强调填充与图标表达,不能只依靠颜色。
  • 面板只保留主题色、壁纸模式与壁纸效果;横幅选项、水波纹与文章列表布局不作为用户设置暴露。
  • 面板、壁纸选项和壁纸效果卡片使用同一 large-increased 圆角,数值与复位控件使用 medium 圆角。
  • 开启、关闭和快速反向操作必须平滑打断,并从当前视觉状态继续。
  • 面板高度受视口限制,超出时内部滚动,不能延伸到页面底部之外。

8.5 日历与目录#

  • 日历分割线使用与当前背景形成足够对比的 outline-variant 或反相角色。
  • 当月、当前日、文章日通过填充、文字权重和状态点建立层级。
  • 目录只对当前章节使用高强调状态;其余项目保持低对比。

8.6 随机段落推荐#

  • 随机段落只出现在宽屏辅助栏,不挤压中窄布局的正文与首页信息流。
  • 候选内容来自所有公开文章的自然段,必须排除草稿、加密内容、纯公式与过短文本。
  • 外层使用实时毛玻璃卡片,正文直接落在玻璃表面,不额外嵌套大块圆角卡片。
  • 段落正文不重复使用标题强调竖线,并按文章原始 Markdown 与 TeX 语义预渲染。
  • 来源文章使用 tonal 文本按钮表达,刷新使用具备可访问名称的 48px 图标按钮。
  • 连续刷新时取消上一段过渡并从当前状态继续;reduced motion 下立即替换内容。

8.7 音乐播放卡片#

  • 音乐卡片属于左侧辅助栏;分类、标签与随机段落位于右侧辅助栏。
  • 封面固定为 1:1 正方形媒体内容,使用 large-increased 圆角,不在玻璃卡片内重复添加描边容器。
  • 歌词与“歌手 / 歌曲 / 专辑”各保持单行,溢出时截断并保留完整 title 提示。
  • 歌词切换使用纵向轮动:顺播时旧行向上离开、新行从下方进入;回退时方向反转。动画必须可被拖动进度等新状态打断,reduced motion 下立即切换。
  • 播放、暂停、上一首和下一首使用 48px 圆形触控目标;主播放按钮使用 primary filled,切歌使用 standard icon button。
  • 进度条必须支持指针拖动与键盘调整,并显示当前位置和总时长。
  • 只有一首歌曲时,切歌操作回到同一首开头,不显示失效的假按钮。

9. 层级与浮层#

层级顺序从低到高为:

  1. 壁纸;
  2. 页面背景与装饰;
  3. 普通内容卡片;
  4. 顶栏与固定导航;
  5. 目录、搜索和普通浮层;
  6. 设置与调色盘;
  7. 对话框、遮罩与全局提示。

组件进入全屏、横幅或覆盖模式时,必须显式验证顶栏和设置面板的堆叠关系,不能依赖 DOM 顺序。

10. 动效#

Token当前值用途
—md-motion-duration-short180mshover、pressed、颜色变化
—md-motion-duration-medium300ms面板、卡片和布局变化
—md-motion-duration-long500ms大范围或强调过渡
—md-motion-emphasizedcubic-bezier(0.2, 0, 0, 1)屏幕内状态变化
—md-motion-deceleratecubic-bezier(0.05, 0.7, 0.1, 1)元素进入
—md-motion-acceleratecubic-bezier(0.3, 0, 0.8, 0.15)元素退出

可中断动画优先使用 CSS transition、Web Animations API 或可反向状态机。禁止用延迟回调在动画结束后强制写死状态,因为快速点击会产生跳帧、重叠或两层残影。

10.1 空间来源与原路返回#

动效必须能够回答三个问题:它从哪里来、为什么这样移动、关闭后回到哪里

  • 来源明确:浮层从触发它的按钮或容器附近出现,transform-origin 必须指向该来源。
  • 路径可逆:关闭不是另一套动画,而是沿打开路径反向返回原处。
  • 状态连续:快速反向时从当前位移、缩放和透明度继续,不能跳回起点再播放。
  • 速度连续:交互改变目标而不是重启动画;浏览器或动画系统保留当前插值速度。
  • 形变守恒:面板可以轻微缩放和位移,但不能被压成一条线或凭空改变长宽比例。
  • 层级一致:元素靠近观察者时可提高 tonal elevation,返回来源时同步降低。
  • 距离决定时间:剩余路程越短,反向完成越快,不强制重新执行完整时长。

本站的典型空间映射如下:

组件出现来源返回方向
搜索面板顶栏搜索按钮右上方
调色盘顶栏调色盘按钮右上方
移动目录顶栏目录按钮右上方
导航菜单顶栏菜单按钮右上方
对话框当前操作位置与视口中心之间沿进入路径返回

实现时优先切换目标状态类,让 CSS transition 从当前计算值自然反向。只有需要手势速度、拖拽或真实弹簧时才使用 Web Animations API;不得用定时器等待动画结束后再切换可见性。

当 prefers-reduced-motion: reduce 生效时,应取消位移、缩放和复杂过渡,只保留必要的即时状态反馈。

11. 可访问性#

  • 普通文本与背景至少达到 WCAG 4.5:1。
  • 大号文本和关键 UI 边界至少达到 3:1。
  • 所有交互支持键盘,并提供可见的 focus-visible。
  • 图标按钮必须有可访问名称。
  • 不能只用颜色表达选中、错误或当前状态。
  • 毛玻璃必须在壁纸最复杂的区域测试对比度。
  • 触控目标保持至少 48 × 48px。

12. 实现约束#

必须#

  • 使用 —md-sys-* 和本站别名 token。
  • 半透明表面同时声明标准与 -webkit- 的 backdrop-filter。
  • 明暗主题共用语义角色。
  • 在 600、840、1200、1600px 验证布局。
  • 所有开合面板验证快速重复点击和反向操作。
  • 新增固定或浮动组件时验证 z-index。

禁止#

  • 用 opacity 模拟毛玻璃。
  • 给所有卡片和按钮统一加细边框。
  • 在组件中大量硬编码颜色和圆角。
  • 让文章正文产生悬停抬升动画。
  • 让全屏内容覆盖顶栏。
  • 用不可打断的定时器拼接面板动画。
  • 为宽屏无限拉长正文行宽。

13. 发布前检查表#

  • 浅色、深色和不同主题色相下文字均清晰。
  • 所有半透明卡片都能看到实时模糊后的壁纸变化。
  • 卡片与按钮没有多余细线。
  • 标题强调竖线没有漂移到元数据图标。
  • 正文卡片悬停时保持静止。
  • 调色盘可以快速开关并平滑打断动画。
  • 设置面板没有被右栏或顶栏遮挡。
  • 全屏与横幅模式不会覆盖顶栏。
  • 移动端没有双层卡片或横向溢出。
  • reduced motion 下没有非必要运动。
  • 键盘焦点、触控目标和色彩对比符合要求。

14. 单一事实来源#

  • 设计 token:src/styles/variables.styl
  • 全局卡片、按钮和阅读表面:src/styles/main.css
  • 毛玻璃公共规则:src/styles/glass-surfaces.css
  • 壁纸与顶栏:src/styles/wallpaper-navbar-transparent.css
  • 可中断面板动画:src/styles/panel-animations.css

更新视觉系统时,应先修改 token 和公共规则,再处理组件特例。若文档与实现不一致,应在同一次改动中同步更新本文。

yutsukarin 博客设计规范
https://yutsukarin.pages.dev/posts/yutsukarin-design-system/
作者
yutsukarin
发布于
2026-07-26
许可协议
CC BY-NC-SA 4.0

目录