资讯动态

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

发布时间:2026/9/12 21:35:28 来源:尧图企业网站定制
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 3MD3token 定义包展开该包从上游 [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 3与Design system version: v0.161见 _md-sys-typescale.scss。从构建角度看BUILD.bazel 将整个 m3 目录声明为一个名为m3的sass_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)两个函数分别面向浅色与深色主题。它们接收一个包含neutral、neutral-variant、primary、secondary、tertiary、error等色阶调色板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 阶、surface取neutral6 阶、surface-container取 12 阶on-*类 token 相应取高亮度色阶如on-primary为 20 阶。两个函数在组装完基础 map 后都会与md-sys-color-internal中的内部取值合并见 _md-sys-color-internal.scss。该文件专门用于存放“与外部 Material Design 规范有分歧的内部专用值”当前实现中values-light与values-dark均返回空 map()即暂无内部差异这一“预留扩展点”的设计意味着未来若组件需要偏离规范的自定义颜色可以在此处增量补充而不必改动主 map。2. 字体排印系统md-sys-typescale_md-sys-typescale.scss 的md-sys-typescale-values($typography)接收$typographymap其中约定plain、brand、bold、medium、regular五个键分别表示正文字体族、品牌字体族以及三种字重$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-large3.562rem 字号、4rem 行高、-0.016rem字距、brand字体族、regular字重headline-medium1.75rem 字号、2.25rem 行高、brand字体族title-large1.375rem 字号、1.75rem 行高、brand字体族body-large1rem 字号、1.5rem 行高、plain字体族label-large0.875rem 字号、1.25rem 行高、medium字重并额外提供label-large-weight-prominent: $boldlabel-medium/label-small0.75rem / 0.688rem 字号均带-weight-prominent变体display、headline、title系列使用brand字体族body、label系列使用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 的全部圆角尺寸 tokenfunction 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-full9999px用于实现完全圆角胶囊/圆形元素带-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 个时长 tokenduration-short150ms 至duration-extra-long41000ms与 10 个缓动 token时长按档次递增short50/100/150/200ms、medium250/300/350/400ms、long450/500/550/600ms、extra-long700/800/900/1000ms缓动提供多套曲线standard、emphasized二者均为cubic-bezier(0.2, 0, 0, 1)、legacycubic-bezier(0.4, 0, 0.2, 1)、linear且standard、emphasized、legacy三族各有-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汇总 colorlight 模式、typescale、elevation、state、shape 五个维度并额外补两个非标准 tokenneutral10用于表单原生 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-10、neutral-variant20一并并入 color 维度输出generate-typography-tokens($typography, $system-variables-prefix)只输出 typescale 维度generate-base-tokens()输出 motion 与 shape 两个“与颜色、字体、密度无关”的维度当启用系统变量时sass-utils.$use-system-color-variables/$use-system-typography-variablesget-sys-color/get-sys-typeface会把每个值替换为var(--前缀-key)形式仅shadow保留原值这正是组件 token 引用--mat-sys-*变量的实现机制见 _m3-tokens.scss。_system.scss系统级变量的实际输出_system.scss 的多个 mixin 最终把 token 值写入 CSStheme-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-variant20、neutral10两个组件直接使用的调色板值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-container、inverse-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-internal与md-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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价