鹏叔(https://pengtech.net)

导航

Angular Material 3 自定义主题

1. 什么是 Material 3

Material 3 (M3)是 Google 开源设计系统 Material Design 的最新版本。它是 Angular Material 所遵循的设计系统 Material 2 (M2)的继承者。

从 v17.2.0 开始,Angular Material 除了 M2 之外还包括对 M3 样式的实验性支持。该团队计划在短暂的实验后稳定对 M3 的支持,以获得有关设计和 API 的反馈。

2. 如何在您的应用中使用 Material 3

作为许多应用程序已使用的同一组 Angular Material 组件的备用 Sass 主题。要将 M3 与 Angular Material 结合使用,请使用函数@angular/material-experimental 包中的 define-theme 创建主题,而不是 使用 @angular/material 的 define-light-theme 或 define-dark-theme 用于创建 M2 主题。

2.1. 定义您的主题

API 最简单的用法$theme: matx.define-theme()是定义具有默认值的主题。但是,与 M2 对应项一样,define-theme 允许您通过传递主题配置对象,沿着三个主题维度配置 Angular Material 应用程序的外观:颜色、排版和密度。配置对象可以具有以下属性。

属性 描述
color [可选] 颜色选项。有关详细信息,请参阅自定义颜色
typography [可选] 颜色选项。有关详细信息,请参阅自定义排版
density [可选] 密度选项。有关详细信息,请参阅自定义密度
@use "@angular/material-experimental" as matx;

$theme: matx.define-theme(
  (
    color: (
      theme-type: dark,
      primary: matx.$m3-violet-palette,
    ),
    typography: (
      brand-family: "Comic Sans",
      bold-weight: 900,
    ),
    density: (
      scale: -1,
    ),
  )
);

2.2. 定制您的颜色

您的应用程序颜色的以下方面可以通过 color 主题配置对象的属性进行自定义(请参阅M3 颜色规范以了解有关这些术语的更多信息):

颜色属性 描述
theme-type [可选] 指定主题的类型,light 或 dark.
primary [可选] 指定用于应用程序主要调色板的调色板。 (注意:M3 规范中描述的辅助调色板、中性调色板和中性变体调色板将根据您的主调色板自动选择,以确保和谐的颜色组合)。
tertiary [可选] 指定用于应用程序的第三调色板的调色板。

有许多可用的调色板@angular/material-experimental 可以与 primary 和 tertiary 选项一起使用:

  • $m3-red-palette 红色
  • $m3-green-palette 绿色
  • $m3-blue-palette 蓝色
  • $m3-yellow-palette 黄色
  • $m3-cyan-palette 青色主题
  • $m3-magenta-palette 洋红色
  • $m3-orange-palette 橙色
  • $m3-chartreuse-palette 浅黄色/浅绿色
  • $m3-azure-palette 天蓝色的/蔚蓝色的
  • $m3-violet-palette 蓝紫色/紫罗兰色
  • $m3-rose-palette 玫红色

2.3. 定制 typography

您的应用程序排版的以下方面可以通过 typography 主题配置对象的属性进行自定义(请参阅 M3 排版规范以了解有关这些术语的更多信息):

版式属性 描述
plain-family [可选] 用于纯文本(例如正文)的字体系列。
brand-family [可选] 用于品牌文本(例如标题)的字体系列。
bold-weight [可选] 用于粗体文本的字体粗细。
medium-weight [可选] 用于中等文本的字体粗细。
regular-weight [可选] 用于常规文本的字体粗细。

2.4. 定制密度

您的应用程序密度的以下方面可以通过 density 主题配置对象的属性进行自定义:

密度特性 描述
scale [可选] 应用程序中组件的紧凑程度,从 0(最多空间)到-5(最紧凑)。

3. 应用主题

创建主题后,您可以使用与应用 M2 相同的-theme、-color、-typography、 density 以及 -base mixin 来应用主题(在主题通用指南中了解有关这些 mixins 的更多信息)。对于 M3 主题,这些 mixins 对生成的样式做出了一些保证。这些保证对 M2 主题时不适用。

mixins 在您指定的确切选择器下生成属性。它们不会被添加到选择器或增加规则的特殊性。
mixin 只生成 CSS 自定义属性声明 (例如--some-prop: xyz)。它们不发出任何标准 CSS 属性,例如 color、 width 等。

3.1. 使用组件颜色变体

许多组件都有一个 color 属性,允许开发人员应用组件的不同颜色变体。当使用 M3 主题时,此属性仍然向组件添加 CSS 类(例如.mat-accent)。但是,没有针对这些类的内置样式。您可以通过将$color-variant 选项传递给组件-theme 或 -color mixin 来应用颜色变体。

<mat-checkbox class="tertiary-checkbox" />
<section class="tertiary-checkbox">
  <mat-checkbox />
</section>
@use "@angular/material" as mat;
@use "@angular/material-experimental" as matx;

$theme: matx.define-theme();

.tertiary-checkbox {
  @include mat.checkbox-color($theme, $color-variant: tertiary);
}

此 API 更灵活,并且生成的 CSS 更少。例如,.tertiary-checkbox 上面显示的类可以应用于任何复选框或包含复选框的任何元素,以更改该元素内所有复选框的颜色。

虽然您应该更喜欢显式应用具有颜色变体的 mixins,但您也可以使用 mixins 提供的向后兼容性 ,将样式直接应用于现有 CSS 类(mat-primary、mat-accent 和 mat-warn)。

下表显示了$color-variant 每个组件支持的值。 (未列出的组件不支持任何颜色变体。)

组件 支持的$color-variant 值 默认
Badge 徽章 primary, secondary, tertiary,error error
Button 按钮 primary, secondary, tertiary,error primary
Button-toggle primary, secondary, tertiary,error secondary
Checkbox 复选框 primary, secondary, tertiary,error primary
Chips primary, secondary, tertiary,error secondary
Datepicker 日期选择器 primary, secondary, tertiary,error primary
Fab primary, secondary,tertiary primary
Form-field primary, secondary, tertiary,error primary
Icon 图标 surface, primary, secondary, tertiary,error surface
Option 选项 primary, secondary, tertiary,error secondary
Progress-bar 进度条 primary, secondary, tertiary,error primary
Progress-spinner primary, secondary, tertiary,error primary
Pseudo-checkbox primary, secondary, tertiary,error primary
Radio 单选框 primary, secondary, tertiary,error primary
Select primary, secondary, tertiary,error primary
Slide-toggle primary, secondary, tertiary,error primary
Slide primary, secondary, tertiary,error primary
Stepper primary, secondary, tertiary,error primary
Tabs primary, secondary, tertiary,error primary

3.2. 使用 CSS 自定义属性进行精细自定义

主题 mixin 生成的 CSS 自定义属性源自 M3 的设计令牌。要在 API 之外进一步自定义 UI define-theme,您可以在样式中手动设置这些自定义属性。

主题 mixin 做出的保证意味着您不需要以组件的内部选择器为目标,也不需要使用过多的特异性来覆盖任何这些标记化属性。始终将基本主题应用到应用程序的根元素(通常为 html 或 body),并将任何覆盖应用到适用的最高级别选择器上。

<mat-sidenav-container>
  Some content...
  <mat-sidenav>
    Some sidenav content...
    <mat-checkbox class="danger">Enable admin mode</mat-checkbox>
  </mat-sidenav>
</mat-sidenav-container>
@use "@angular/material" as mat;
@use "@angular/material-experimental" as matx;

$light-theme: matx.define-theme();
$dark-theme: matx.define-theme(
  (
    color: (
      theme-type: dark,
    ),
  )
);

html {
  // Apply the base theme at the root, so it will be inherited by the whole app.
  @include mat.all-component-themes($light-theme);
}

mat-sidenav {
  // Override the colors to create a dark sidenav.
  @include mat.all-component-colors($dark-theme);
}

.danger {
  // Override the checkbox hover state to indicate that this is a dangerous setting. No need to
  // target the internal selectors for the elements that use these variables.
  --mdc-checkbox-unselected-hover-state-layer-color: red;
  --mdc-checkbox-unselected-hover-icon-color: red;
}

4. 使用 Material 3 主题为您自己的组件设置主题

用于读取 M2 主题属性的相同实用程序函数(在 我们的组件主题化指南中描述)可用于从 M3 主题读取属性。然而,根据规范,M3 主题的可用命名调色板、排版级别等有所不同。

主题对象的结构被视为实现细节。代码不应依赖于直接读取其属性,例如使用 map.get.始终使用 Angular Material 提供的实用函数来访问主题的属性。

@use "@anuglar/material" as mat;
@use "@anuglar/material-experimental" as matx;

@mixin my-comp-theme($theme) {
  .my-comp {
    font: mat.get-theme-typography($theme, body-large, font);
    letter-spacing: mat.get-theme-typography(
      $theme,
      body-large,
      letter-spacing
    );
    background: mat.get-theme-color($theme, surface);
    @if mat.get-theme-type($theme) == dark {
      color: mat.get-theme-color($theme, primary, 20);
    } @else {
      color: mat.get-theme-color($theme, primary, 80);
    }
    padding: 48px + (2px * mat.get-theme-density($theme));
  }
}

4.1. 读取色调调色板颜色

要从主题中读取 色调调色板颜色 get-theme-color,请使用带有三个参数的函数:

参数 描述
$theme 要读取的 M3 主题。
$palette 要读取的调色板的名称。这可以是任何标准 M3 调色板:
primary
secondary
tertiary
error
neutral
neutral-variant
$hue 在调色板中读取的色相编号。这可以是任何标准色调:
0
10
20
30
40
50
60
70
80
90
95
99
100

4.2. 解读色彩角色

要读取颜色角色,请 使用 get-theme-color 与两个参数一起使用:

参数 描述
$theme 要读取的 M3 主题。
$role 颜色角色的名称。这可以是任何 M3 颜色角色:
primary
on-primary
primary-container
on-primary-container
primary-fixed
primary-fixed-dim
on-primary-fixed
on-primary-fixed-variant
secondary
on-secondary
secondary-container
on-secondary-container
secondary-fixed
secondary-fixed-dim
on-secondary-fixed
on-secondary-fixed-variant
tertiary
on-tertiary
tertiary-container
on-tertiary-container
tertiary-fixed
tertiary-fixed-dim
on-tertiary-fixed
on-tertiary-fixed-variant
error
on-error
error-container
on-error-container
surface-dim
surface
surface-bright
surface-container-lowest
surface-container-low
surface-container
surface-container-high
surface-container-highest
on-surface
on-surface-variant
outline
outline-variant
inverse-surface
inverse-on-surface
inverse-primary
scrim
shadow

4.3. 读取主题类型

要读取主题类型(light 或 dark),请 使用 get-theme-type 并存入一个参数进行调用:

参数 描述
$theme 要读取的 M3 主题。

4.4. 读取类型比例属性

要从主题读取 typescale 请使用 get-theme-typography 方法,并传入三个参数进行调用:

参数 描述
$theme 要读取的 M3 主题。
$level 字体级别。这可以是任何 M3 类型级别:
display-large
display-medium
display-small
headline-large
headline-medium
headline-small
title-large
title-medium
title-small
body-large
body-medium
body-small
label-large
label-medium
label-small
$property 要获取值的 CSS 字体属性。这可以是以下 CSS 属性之一:
font(CSS 字体简写,包括除字母间距之外的所有字体属性)
font-family
font-size
font-weight
line-height
letter-spacing

4.5. 读取密度标尺

要从主题 读取密度标度(0、-1、-2、-3、-4 或 -5),请使用单个参数进行调用:get-theme-density

| 参数 | 描述 |
| $theme | 要读取的 M3 主题。|

5. 如何将应用程序从 Material 2 迁移到 Material 3

Angular Material 不提供从 M2 到 M3 的自动迁移,因为应用程序的设计是主观的。 Material Design 提供了一般原则和约束来指导您,但最终由您决定如何在您的应用程序中应用这些原则和约束。也就是说,Angular Material 的 M3 主题在设计时就考虑到了最大兼容性。

5.1. 更新使用 Angular Material 主题的组件以与 Material 3 兼容

为了促进从 M2 到 M3 的平滑过渡,让您的组件同时支持 M2 和 M3 主题可能是有意义的。迁移整个应用程序后,可以删除对 M2 主题的支持。

实现此目的的最简单方法是检查主题版本并为 M2 和 M3 发出不同的样式。您可以使用 的 get-theme-version 功能 检查主题版本@angular/material。该函数将返回 0M2 主题或 1M3 主题(请参阅 使用 Material 3 主题主题您自己的组件, 了解如何从 M3 主题读取值)。

@use "@angular/material" as mat;

@mixin my-comp-theme($theme) {
  @if (mat.get-theme-version($theme) == 1) {
    // Add your new M3 styles here.
  } @else {
    // Keep your old M2 styles here.
  }
}

5.2. 在您的全局主题样式中传递新的 M3 主题

使用创建一个新的 M3 主题对象 define-theme 并将其传递到您之前传递 M2 主题的任何地方。所有采用 M2 主题的 Angular Material mixins 也与 M3 主题兼容。

5.3. 更新 Material 3 主题不支持的 API

由于 Material 3 是作为 Material 2 所用相同组件的替代主题实现的,因此两者的 API 基本相同。但是,有一些差异需要注意:

  • M3 期望任何@include、-theme、-color、-typography 或-densitymixin-base 都应包装在选择器中。如果您的应用程序@include 在根级别包含这样的内容,我们建议将其包装在 html
  • M3 有一个不同的 API 用于设置组件的颜色变体(有关更多信息,请参阅 使用组件颜色变体)。
  • 不支持 backgroundColor 属性,并且不应与 M3 主题一起使用。
  • 不支持 appearance="legacy" 变量,并且不应与 M3 主题一起使用。
  • 对于 M3 主题,调用 all-component-typographies 不会生成样式 typography-hierarchy ,因为这会违反 M3 不添加选择器的保证。相反, 如果您希望在应用程序中使用 typography-hierarchy 的这些样式,则必须显式调用 mixin。
  • mixintypography-hierarchy 输出对应于 M3 字体级别而不是 M2 字体级别名称的 CSS 类名称。如果您依赖 M2 类来设计应用程序的样式,则可能需要更新类名称。

5.4. 为颜色变体添加向后兼容样式(可选)

我们建议不要依赖许多 Angular Material 组件提供的的 color="primary"、color="accent"或 color="warn" M2 主题选项。但是,如果您想快速更新到 M3 并愿意接受为这些变体生成的额外 CSS,您可以启用向后兼容样式来恢复此 API 的行为。使用您想要为其生成颜色变体样式的 M3 主题调用 @angular/material-experimental
的 color-variants-back-compat mixin 。

@use "@angular/material" as mat;
@use "@angular/material-experimental" as matx;

$theme: matx.define-theme();

html {
  @include mat.all-component-themes($theme);
  @include matx.color-variants-back-compat($theme);
}

5.5. 为排版层次结构添加向后兼容样式(可选)

使用 M3 主题调用 typography-hierarchy mixin 会生成与 M3 typescale 名称(例如.mat-headline-large)相匹配的 CSS 类样式,而不是与 M2 类型规模名称匹配的 CSS 类样式(.mat-headline-1)。如果您在应用程序中使用 M2 类名称,我们建议将所有用法更新为新类名称。然而,为了使迁移更容易, typography-hierarchy mixin 除了新的类名之外还支持生成旧的类名。我们已尽最大努力将 M2 类映射到 M3 中合理的等效项。要启用这些样式,请将附加参数$back-compat: true 传递 给 mixin。

@use "@angular/material" as mat;
@use "@angular/material-experimental" as matx;

$theme: matx.define-theme();

@include mat.typography-hierarchy($theme, $back-compat: true);

5.6. 常问问题

  1. 我可以使用预定义的 Material 3 调色板以外的颜色吗?

    目前,我们仅提供预定义的调色板,但我们计划添加对使用自定义生成的调色板的支持.

  2. 我可以依赖稳定的 CSS 自定义属性名称吗?

    在将 Material 3 API 走出实验阶段之前,我们可能会对自定义属性名称进行更改,但伴随着这些更改我们将提供相应的 schematic,以便在您的应用程序中方便的替换旧名称为新名称。

  3. Material 2 样式和 API 会消失吗?

    Material 2 样式及其 API 将继续受到支持,并且我们没有立即计划弃用它们。我们知道应用程序切换到最新的 Material 3 样式需要一些时间,我们希望为迁移提供足够的时间。当我们决定删除这些 API 时,它们将被标记为已弃用,并在以下两个主要版本中继续受支持。截至目前,它们尚未被视为已弃用。

6. Angular 系列文章

最新更新以及更多 Angular 相关文章请访问 Angular 合集 | 鹏叔的技术博客

7. 参考文档

Material 3 Theming

posted on 2024-04-09 06:11  eagle.supper  阅读(145)  评论(0编辑  收藏  举报