如何用 Angular Material 的 --mat-sys CSS 变量为自定义组件应用应用主题的颜色与排版
如何用 Angular Material 的 --mat-sys CSS 变量为自定义组件应用应用主题的颜色与排版【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components当你的 Angular 应用已经用 Angular Material 设置了应用主题而你自己的自定义组件banner、卡片、提示条等仍然写死颜色与字号时会出现两套视觉语言并存的问题。Angular Material 的mat.theme()Sass mixin 会输出一组以--mat-sys为前缀的 CSS 变量基于 Material Design 的 Design Tokens你在组件样式表里直接引用这些变量就能让自定义组件的颜色、排版与应用主题保持一致并自动获得浅色/深色两种模式。本文适用前提应用使用 Angular Material v19 引入的 Sass 主题 APImat.theme如果你的应用是更早版本或基于旧的 theme config文末给出了兼容做法。前提先让主题文件真正输出 CSS 变量--mat-sys变量不是默认就存在的必须先有一个 Sass 主题文件调用mat.thememixin并且该 mixin 接受定义 color、typography 和 density 的 map。下面是文档给出的标准主题文件写法目标是html选择器确保变量作用于整个应用use angular/material as mat; html { color-scheme: light dark; include mat.theme(( color: mat.$violet-palette, typography: Roboto, density: 0 )); }颜色可以传单色调色板如上例的mat.$violet-palette此时 primary、secondary、tertiary 都取自它也可以传颜色 map 单独配置 tertiary 并指定theme-typecolor-scheme、light或dark。color-scheme: light dark表示跟随用户系统偏好决定浅色还是深色。两个影响后续步骤的行为需要留意变量按输入类别输出mat.theme只声明输入中出现的类别对应的 CSS 变量。如果 map 里没有typography排版相关的--mat-sys-*变量就不会出现在产物中——这是核对排版变量是否生效的直接判断依据。不想手写主题文件时可以把预置主题 CSS 加入angular.json的styles数组例如angular/material/prebuilt-themes/azure-blue.css。其中四个是 M3 主题如azure-blue.css、rose-red.css、cyan-orange.css、magenta-violet.css四个是 M2 主题想要现代 Material 3 视觉语言应选 M3。同时文档建议用下面这段全局样式让 surface 背景与 on-surface 文字色成为应用默认值这也顺带验证了颜色变量已生效页面整体应呈现主题色而非白色底body { background: var(--mat-sys-surface); color: var(--mat-sys-on-surface); }在组件样式表中使用 --mat-sys 颜色变量颜色变量按“背景 前景成对”的方式组织选定一个背景角色如primary、surface、error其上的文字和图标应使用对应的on-*变量以保证对比度。常用角色及 Angular Material 自身的使用场景--mat-sys-primary/--mat-sys-on-primary页面中重要性较高的元素如 datepicker 选中日期、slider 手柄、checkbox 背景--mat-sys-primary-container/--mat-sys-on-primary-container需要在 surface 上突出的容器如悬浮操作按钮--mat-sys-secondary/--mat-sys-on-secondary次要但独立于主色的组件--mat-sys-error/--mat-sys-on-error错误状态如无效输入框、badge 背景--mat-sys-surface/--mat-sys-on-surface、--mat-sys-on-surface-variant通用表面及其文字on-surface-variant用于强调更低的副文本、caption、hint--mat-sys-surface-container-*系列从lowest到highest的强调层级分别用于 bottom sheet、menu、datepicker、filled card 等背景--mat-sys-outline、--mat-sys-outline-variant描边色后者用于 outline card 描边、divider 这类更不显眼的边界完整的颜色 token 列表primary、secondary、tertiary、error、surface 及各 container、inverse 变体见 theming-your-components 指南。文档给出的自定义组件示例是一个应用级信息横幅同时使用了背景、文字、边框三个 token.my-component { background: var(--mat-sys-primary-container); color: var(--mat-sys-on-primary-container); border: 1px solid var(--mat-sys-outline-variant); font: var(--mat-sys-body-large); }使用排版变量统一字号、行高与字重排版变量按 Material 的五大类组织body、display、headline、label、title每类有 small、medium、large 三个尺寸title 无 small 之外的特殊项按实际列表为准。每个级别同时提供整体 shorthand 变量和拆分变量--mat-sys-body-medium --mat-sys-body-medium-font --mat-sys-body-medium-line-height --mat-sys-body-medium-size --mat-sys-body-medium-tracking --mat-sys-body-medium-weight在组件样式中引用 shorthand 变量并单独设置letter-spacing取自对应的-tracking变量是文档展示的标准写法/* 正文表格行文字、对话框辅助文字medium 为默认正文字号 */ .widget-body { font: var(--mat-sys-body-medium); letter-spacing: var(--mat-sys-body-medium-tracking); } /* 说明文字、副标题body-small 用于 caption 类文本 */ .widget-caption { font: var(--mat-sys-body-small); letter-spacing: var(--mat-sys-body-small-tracking); } /* 卡片标题类文本 */ .widget-title { font: var(--mat-sys-title-large); letter-spacing: var(--mat-sys-title-large-tracking); }各字号在 Angular Material 中的实际用途可作为选型参考body-small用于 form field 下标文字和分页器文字body-large用于列表项文字和 select 触发器文字headline-small用于 dialog 标题title-medium用于 card 副标题和 expansion panel 标题label-large用于按钮、chips 和菜单文字。完整排版 token 列表见 theming-your-components 指南。如果你还需要边框圆角和阴影也跟随主题同一体系还有--mat-sys-corner-*如--mat-sys-corner-medium、--mat-sys-corner-large和--mat-sys-level0到--mat-sys-level5的阴影变量写法同为border-radius: var(--mat-sys-corner-medium)/box-shadow: var(--mat-sys-level1)。可选分支在模板中直接使用 system-classes 工具类如果你的组件结构简单也可以不在样式表里写var()而是在主题文件中额外引入mat.system-classes()然后在模板里直接挂工具类html { ... include mat.system-classes(); }body classmat-bg-surface mat-text-on-surface widget-a classmat-bg-surface mat-text-on-surface mat-font-body-md/ widget-b classmat-bg-primary mat-text-on-primary/这两条路径等价都包裹的是同一组--mat-sys变量样式表写法适合结构复杂、需要组合自定义声明的组件工具类适合直接在模板上快速套用主题风格。工具类的完整清单mat-bg-*、mat-text-*、mat-font-*、mat-corner-*、mat-shadow-*等可由 system-classes mixin 源码 核对它通过 src/material/_index.scss 对外导出。浅色与深色模式如何跟随颜色变量用 CSS 的light-dark()函数定义实际取值由全局样式中的color-scheme决定color-scheme: light dark跟随用户系统偏好切换color-scheme: light或color-scheme: dark显式固定模式如果应用没有声明color-scheme浅色颜色会一直被应用——这是深色模式不生效时的第一判断点。也可以把color-scheme挂在某个选择器上实现按类切换例如默认浅色、body 加上dark-mode类后切换为深色html { color-scheme: light; include mat.theme(( color: mat.$violet-palette, typography: Roboto, density: 0 )); } body.dark-mode { color-scheme: dark; }Angular Material 不会基于prefers-color-scheme之类的媒体查询自动切换需要你通过color-scheme、自定义媒体查询或读取用户偏好自行控制。另外若应用必须支持较老或非主流浏览器light-dark覆盖不足可把颜色 map 的theme-type显式设为light或dark此时只输出单模式颜色值。核对结果与限制完成上面步骤后按以下文档给出的行为核对页面 body 呈现--mat-sys-surface背景与--mat-sys-on-surface文字色自定义组件的背景、文字、边框颜色与相邻的 Material 组件如 button、card一致说明取到的是同一主题 token切换color-scheme如给 body 加/去掉dark-mode类后颜色整体换到另一套证明变量走了light-dark()而非写死的色值排版变量存在的前提是主题 map 里定义了typography否则产物中不会有排版 CSS 变量。限制与边界均来自文档的明确说明不要用组件外部直接覆盖 CSS 的方式改色。Angular Material 明确不直接支持在主题 API 之外覆盖组件 CSS组件的 DOM 结构与类名属于私有实现随时可能变化。需要微调某个系统 token 时用mat.theme-overrides或mat.theme的第二个参数$overrides例如把primary-container改成指定颜色针对单个组件的 token如 card 的elevated-container-color用各组件的*-overridesmixin。Shadow DOM 应用Angular Material 默认假设主题样式是全局 CSS。如果自定义组件运行在 Shadow DOM 中必须把主题样式加载进每个包含 Material 组件的 shadow root。旧 Material Design 2 主题如果应用用 M2 的 legacy theme-configmat.m2-define-light-theme等定义主题在主题文件中加include mat.m2-theme($theme);配合mat.system-classes()会按当前 M2 主题配置生成对应的系统 token同样可以使用本文的 CSS 变量与工具类从而避免再维护一套从$themeSass map 里取值的组件级 theme mixin。更多细节全部颜色/排版/圆角/阴影 token 清单、每个 token 在 Material 组件中的使用位置、M2 迁移示例见 Theming your components 指南与 Theming 指南。【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →