news 2026/9/12 21:35:24

Angular Material 3 Token 体系解析:m3 包结构与 `--mat-sys` 系统变量机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Angular Material 3 Token 体系解析:m3 包结构与 `--mat-sys` 系统变量机制

Angular Material 3 Token 体系解析:m3 包结构与--mat-sys系统变量机制

【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components

导读

本文围绕 src/material/core/tokens/m3/README.md 所定义的 Material Design 3(MD3)token 定义包展开:该包从上游 [@material/tokens] 分叉而来,锁定v0_161版本的 token 定义,是 Angular Material 主题系统中 M3 组件样式与系统级 CSS 变量的数据源头。读完本文,你将理解 m3 包的目录/文件结构、六大 token 维度(颜色、字体排印、高度、形状、状态、动效)的取值定义方式,以及这些定义如何被_system.scss_m3-tokens.scss等上层文件消费,最终转化为运行时可见的--mat-sys-*CSS 变量与组件私有 token。

包定位:从上游分叉的 MD3 token 定义

README.md给出了该包的核心定位:它是 Material Design 3 系统 token 的定义集合,与 Angular Material 主题实现中依赖的上游规范包进行了一次明确的分叉(fork)。分叉时间是 2024 年 7 月 22 日,此后仓库直接携带并使用v0_161版本的 token 值,而不是在构建时动态拉取 npm 上的@material/tokens

README 同时记录了两条与上游的差异:

  • 裁剪未使用 token:凡 Angular Material 当前未使用到的 token 都被移入unused目录(在本仓库 m3 目录内体现为仅保留实际被消费的定义文件,未使用的定义不参与sass_library构建)。
  • 统一格式化:token 文件的书写格式被调整为符合本仓库 stylelint 与 sass lint 规则,例如所有注释头统一为Design system display name: Material 3Design system version: v0.161(见 _md-sys-typescale.scss)。

从构建角度看,BUILD.bazel 将整个 m3 目录声明为一个名为m3sass_library,其 srcs 包含_index.scss、六个_md-sys-*.scss、两个*-internal.scss以及_theme.scss共 10 个文件,任何上层 Sass 文件只需@use './m3'(如 _m3-tokens.scss)即可获得全部 token 函数。

模块入口:_index.scss 与导出面

_index.scss 是该包的统一入口,使用@forward将六个维度文件与_theme.scss全部导出:

@forward './md-sys-color'; @forward './md-sys-elevation'; @forward './md-sys-motion'; @forward './md-sys-shape'; @forward './md-sys-state'; @forward './md-sys-typescale'; @forward './theme';

每个被 forward 的文件都暴露一个md-sys-xxx-values(...)纯函数,返回一个 Sass map。函数命名遵循统一约定:md-sys-color-values-light()/md-sys-color-values-dark()md-sys-typescale-values()md-sys-elevation-values()md-sys-shape-values()md-sys-state-values()md-sys-motion-values()。上层代码统一通过m3.函数名(...)方式调用,例如 _m3-tokens.scss 中的m3.md-sys-color-values-dark($palettes)m3.md-sys-color-values-light($palettes)

系统 token 的六大维度与完整取值

以下逐一说明各维度函数的完整取值,全部以当前仓库源码为准(版本 v0.161)。

1. 颜色系统(md-sys-color)

_md-sys-color.scss 提供md-sys-color-values-light($palettes)md-sys-color-values-dark($palettes)两个函数,分别面向浅色与深色主题。它们接收一个包含neutralneutral-variantprimarysecondarytertiaryerror等色阶调色板(palette)的 map,然后从调色板的指定色阶(如primary, 40表示 primary 调色板第 40 阶)取出颜色值,组装成系统颜色 token map。

light 模式下的关键映射包括:

Token取值来源
primary/on-primaryprimary调色板 40 / 100 阶
primary-container/on-primary-containerprimary调色板 90 / 30 阶
secondary/tertiary/error各自调色板 40 阶
surface/surface-containerneutral98 / 94 阶
surface-container-lowest/surface-container-highestneutral100 / 90 阶
background/on-backgroundneutral98 / 10 阶
on-surface/on-surface-variantneutral10 /neutral-variant30 阶
outline/outline-variantneutral-variant50 / 80 阶
scrim/shadowneutral0 阶
surface-tintprimary40 阶

dark 模式整体将色阶向暗部偏移,例如primary取 80 阶、primary-container取 30 阶、surfaceneutral6 阶、surface-container取 12 阶,on-*类 token 相应取高亮度色阶(如on-primary为 20 阶)。

两个函数在组装完基础 map 后,都会与md-sys-color-internal中的内部取值合并(见 _md-sys-color-internal.scss)。该文件专门用于存放“与外部 Material Design 规范有分歧的内部专用值”,当前实现中values-lightvalues-dark均返回空 map(),即暂无内部差异;这一“预留扩展点”的设计意味着未来若组件需要偏离规范的自定义颜色,可以在此处增量补充,而不必改动主 map。

2. 字体排印系统(md-sys-typescale)

_md-sys-typescale.scss 的md-sys-typescale-values($typography)接收$typographymap,其中约定plainbrandboldmediumregular五个键,分别表示正文字体族、品牌字体族以及三种字重:

$plain: map.get($typography, plain); $brand: map.get($typography, brand); $bold: map.get($typography, bold); $medium: map.get($typography, medium); $regular: map.get($typography, regular);

函数输出覆盖 Material 3 全部 15 种文字样式(display-large/medium/small、headline-large/medium/small、title-large/medium/small、body-large/medium/small、label-large/medium/small),每种样式都展开为 6 个 token:简写组合值(如body-large: $regular 1rem / 1.5rem $plain)以及-font-line-height-size-tracking-weight五个分项。典型取值如下:

  • display-large:3.562rem 字号、4rem 行高、-0.016rem字距、brand字体族、regular字重
  • headline-medium:1.75rem 字号、2.25rem 行高、brand字体族
  • title-large:1.375rem 字号、1.75rem 行高、brand字体族
  • body-large:1rem 字号、1.5rem 行高、plain字体族
  • label-large:0.875rem 字号、1.25rem 行高、medium字重,并额外提供label-large-weight-prominent: $bold
  • label-medium/label-small:0.75rem / 0.688rem 字号,均带-weight-prominent变体

displayheadlinetitle系列使用brand字体族,bodylabel系列使用plain字体族,这正是 M3 区分“品牌展示型文字”与“功能型正文”的设计原则。函数末尾同样与md-sys-typescale-internal合并(见 _md-sys-typescale-internal.scss),提供内部专用字体的扩展点。

3. 高度系统(md-sys-elevation)

_md-sys-elevation.scss 仅定义一个函数,返回 6 个高度等级的“高度值”(阴影扩散半径基准):

@function md-sys-elevation-values() { @return ( level0: 0, level1: 1, level2: 3, level3: 6, level4: 8, level5: 12 ); }

注意这里存储的是阴影等级数值而非最终 box-shadow。真正将等级转换为 CSS 阴影的是上层 _system.scss 的system-level-elevationmixin:它以调色板neutral0 阶作为阴影颜色,调用elevation.get-box-shadow($level, $shadow-color)生成实际阴影,再以--mat-sys-levelN形式输出。这解释了_m3-tokens.scss中“elevation 需要归入 color 维度一起生成”的注释——阴影值必须与颜色值组合才有意义。

4. 形状系统(md-sys-shape)

_md-sys-shape.scss 定义 M3 的全部圆角尺寸 token:

@function md-sys-shape-values() { @return ( corner-none: 0, corner-extra-small: 4px, corner-extra-small-top: (4px 4px 0 0), corner-small: 8px, corner-medium: 12px, corner-large: 16px, corner-large-top: (16px 16px 0 0), corner-large-start: (16px 0 0 16px), corner-large-end: (0 16px 16px 0), corner-extra-large: 28px, corner-extra-large-top: (28px 28px 0 0), corner-full: 9999px ); }

corner-full(9999px)用于实现完全圆角(胶囊/圆形元素);带-top-start-end后缀的变体是四值圆角列表,用于仅对特定角落生效的场景,例如顶部圆角(16px 16px 0 0)

5. 状态层系统(md-sys-state)

_md-sys-state.scss 定义交互状态层(state layer)的透明度:

@function md-sys-state-values($exclude-hardcoded-values: false) { @return ( dragged-state-layer-opacity: 0.16, focus-state-layer-opacity: 0.12, hover-state-layer-opacity: 0.08, pressed-state-layer-opacity: 0.12 ); }

这些透明度配合颜色 token 生成带透明度的状态层颜色,如 hover 8%、focus/pressed 12%、拖拽 16%。由于状态值经常与颜色值一起组合成 rgba 颜色,_m3-tokens.scss 的注释说明 state 因此被归入 color 维度一起生成,属于实现层面的刻意安排。

6. 动效系统(md-sys-motion)

_md-sys-motion.scss 定义 M3 的时长与缓动曲线 token,包含 16 个时长 token(duration-short150ms 至duration-extra-long41000ms)与 10 个缓动 token:

  • 时长按档次递增:short(50/100/150/200ms)、medium(250/300/350/400ms)、long(450/500/550/600ms)、extra-long(700/800/900/1000ms)
  • 缓动提供多套曲线:standardemphasized(二者均为cubic-bezier(0.2, 0, 0, 1))、legacycubic-bezier(0.4, 0, 0.2, 1))、linear,且standardemphasizedlegacy三族各有-accelerate/-decelerate变体

_theme.scss:系统变量 map 的组装

_theme.scss 是 m3 包的“收口”文件。其核心函数_create-system-app-vars-map($map)将任意 token map 的键转换为--mat-sys-<key>形式的 CSS 变量字符串:

@function _create-system-app-vars-map($map) { $new-map: (); @each $key, $value in $map { $new-map: map.set($new-map, $key, --mat-sys-#{$key}); } @return $new-map; }

随后$_sys-maps汇总 color(light 模式)、typescale、elevation、state、shape 五个维度,并额外补两个非标准 token:

  • neutral10:用于表单原生 select 选项文字颜色
  • neutral-variant20:用于 Sidenav 打开时的 scrim(容器背景阴影)

这些 map 全部 merge 进$_system(并附density-scale: 0),最终导出:

$sys-theme: (_mat-system: $_system);

_mat-system这一键名正是上层代码读取系统 token 的入口——_m3-utils.scss 的get-system($theme)直接map.get($theme, _mat-system),而 _system.scss 则据此批量输出--mat-sys-*CSS 变量。值得注意的是:这里的$sys-theme提供的是变量引用--mat-sys-key字符串),而真正把变量值落地的过程发生在 _system.scss 的各system-level-*mixin 中。

上层消费链路:从 token map 到 CSS 变量

m3 包本身不输出任何 CSS,它只是定义与函数的“数据层”。将其接入主题系统的是 _m3-tokens.scss 与 _system.scss。

_m3-tokens.scss:命名空间化 token 生成

generate-tokens($systems, ...)将六大系统 map 合并后输出命名空间化的 token map,其中(mat, theme)指向md-sys-color(mat, typography)指向md-sys-typescale,让使用者通过组件 API 即可访问系统颜色与字体。三个更具体的入口函数:

  • generate-color-tokens($type, $palettes, $system-variables-prefix):根据light/dark选择浅色或深色系统颜色,并把 elevation、state(以及部分调色板值neutral-10neutral-variant20)一并并入 color 维度输出
  • generate-typography-tokens($typography, $system-variables-prefix):只输出 typescale 维度
  • generate-base-tokens():输出 motion 与 shape 两个“与颜色、字体、密度无关”的维度

当启用系统变量时(sass-utils.$use-system-color-variables/$use-system-typography-variables),get-sys-color/get-sys-typeface会把每个值替换为var(--前缀-key)形式(仅shadow保留原值),这正是组件 token 引用--mat-sys-*变量的实现机制,见 _m3-tokens.scss。

_system.scss:系统级变量的实际输出

_system.scss 的多个 mixin 最终把 token 值写入 CSS:

  • theme-overrides($overrides):以palettes.$blue-palette与 Roboto 字体定义构建一份完整的系统 token 名列表,用于校验用户传入mat.theme-overrides((primary: red))中的键是否合法,合法则输出覆盖值
  • system-level-colors($theme, $overrides, $prefix):按light/dark/color-scheme三种主题类型生成系统颜色(color-scheme模式下用 CSSlight-dark()同时打包浅/深两套值),并手动补入neutral-variant20neutral10两个组件直接使用的调色板值
  • system-level-typography:将 typescale 每个键输出为系统字体变量
  • system-level-elevation:将高度等级与neutral0 阶阴影色组合成真实 box-shadow 后输出
  • system-level-shape/system-level-state:分别输出圆角与状态层透明度变量

这一层正是--mat-sys-*变量在页面中可被 DevTools 观察到的最终输出者。

配套工具函数:_m3-utils.scss

_m3-utils.scss 提供三个被上层反复使用的 Sass 工具:

  • replace-colors-with-variant($system, $color, $variant):把系统 map 中on-<color>on-<color>-container<color><color>-containerinverse-<color>五个键的值替换为对应<variant>的取值,用于实现主题中的角色替换
  • get-system($theme):从主题 map 中取出_mat-system系统 token 子图
  • color-with-opacity($color, $opacity):基于color-mix(in srgb, ...)为颜色叠加透明度;若颜色本身是--开头的变量名则自动包一层var(),若透明度小于 1 的数字(如 0.38)则换算为百分比字符串

版本与维护注意点

  • 本包 token 版本锁定为Material 3 v0.161,所有带版本头注释的文件均标注Design system version: v0.161(见 _md-sys-motion.scss 等)。
  • 分叉日期为 2024-07-22,此后 M3 规范的更新不会自动同步进本仓库,需要由维护者按需手动合入,因此文中所有取值均以当前仓库为准
  • md-sys-color-internalmd-sys-typescale-internal是 Angular Material 预留的“规范分歧点”:当前为空 map,未来若组件需要偏离上游规范的值,应优先在此增量补充,以保持与上游 diff 的最小化。
  • 未使用 token 不进入本仓库(README 所述的unused目录机制),因此当你在仓库中找不到某个上游 token 时,通常意味着该 token 未被 Angular Material 消费,不应视为缺失。

结语

m3 包是 Angular Material 主题体系中最底层的“事实来源”:六个md-sys-*-values()函数固化 Material 3 v0.161 的颜色、字体、高度、形状、状态与动效取值,_theme.scss把它们组织为_mat-systemmap,再经_m3-tokens.scss_system.scss两层消费,最终以--mat-sys-*CSS 变量的形式呈现给组件与开发者。理解这一链路,就能在排查主题覆盖、自定义 token、或阅读组件私有 token 定义时,快速定位数值的最终出处。

【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 21:31:30

西门子S7-200 PLC水泵一用一备控制系统设计与实现

1. 项目概述&#xff1a;200 PLC水泵一用一备控制系统 在工业自动化领域&#xff0c;水泵控制是最基础也最经典的应用场景之一。我从业十多年来&#xff0c;处理过上百个水泵控制项目&#xff0c;其中西门子S7-200 PLC实现的一用一备方案堪称教科书级别的案例。这种配置不仅保证…

作者头像 李华
网站建设 2026/9/12 21:28:17

告别手动改100份合同:用python批量生成Word文档,5分钟搞定!

-docx &手动改 100 份合同花了一整天&#xff1f;你该换方法了&#xff01;上周, HR同事小王找我诉苦, 销售部新加八人, 她需复制同一份劳动合同模板八次, 手动将每份中的人名、部门、入职日期、月薪逐一修改, 改至第六份时眼花, 把“张三”写成“张二”, 改第七份时又将月…

作者头像 李华
网站建设 2026/9/12 21:26:26

讲师如何通过系统化记录提升课程价值与收入

1. 讲师活动记录的底层逻辑与核心价值讲师这个职业看似光鲜亮丽&#xff0c;实则是个需要持续积累的"手艺活"。我做了8年企业内训师&#xff0c;累计授课超过2000小时&#xff0c;最深刻的体会就是&#xff1a;那些能持续接到高价课约的讲师&#xff0c;都有一套科学…

作者头像 李华
网站建设 2026/9/12 21:25:22

Flask+Bootstrap博客系统:Python全栈入门最佳实践

简介&#xff1a;这是一套基于Flask后端框架与Bootstrap前端库构建的轻量级博客系统开源实现&#xff0c;面向Python Web开发初学者及全栈入门者&#xff0c;帮助快速掌握MVC结构、数据库操作、用户认证与响应式页面开发等核心实践能力。资源共70个文件&#xff0c;压缩包仅463…

作者头像 李华