You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确设置Angular v15 Material组件内部样式

Angular Material 15 组件样式定制指南(迁移后样式失效解决方案)

问题背景

项目从Angular Material 14迁移到15版本后,之前直接修改组件内部类名(比如mat-button-disabled)的定制方式完全失效——因为这些内部类名已变更。现在需要通过官方主题系统正确定制组件内部颜色样式,比如将按钮禁用状态的背景色从默认灰色改为蓝色。

已尝试的无效/非规范方案

  • 修改主主题颜色对象的背景调色板,添加on-surface值并全局应用,未生效。
  • 硬编码样式(不符合主题规范,不推荐):
.mat-mdc-raised-button:disabled {
  --mdc-protected-button-disabled-container-color: mat.get-color-from-palette($primary-palette, 500);
  background-color: mat.get-color-from-palette($primary-palette, 500);
}
  • 自定义类被默认样式覆盖:
.custom-button {
  @include button.disabled-container-fill-color(pink);
}
  • 目前可用但不符合规范的写法:
.mat-mdc-raised-button[disabled][disabled] {
  --mdc-protected-button-disabled-container-color: #{mat.get-color-from-palette($accent-palette, 500, 0.3)};
  --mdc-protected-button-disabled-label-text-color: #{mat.get-color-from-palette($background, background, 0.3)}
}

当前主题代码

@use 'sass:map';
@use '@angular/material' as mat;

$primary-palette: (
  50: #e3e4e8,
  100: #b9bcc5,
  200: #8b909f,
  300: #5c6479,
  400: #39425c,
  500: #232d6a,
  600: #131d39,
  700: #101831,
  800: #0c1429,
  900: #060b1b,
  A100: #5a7cff,
  A200: #2753ff,
  A400: #0032f3,
  A700: #002cda,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #ffffff,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #ffffff,
    A400: #ffffff,
    A700: #ffffff,
  )
);

$accent-palette: (
  50: #e4ebf3,
  100: #bbcee0,
  200: #8eadcc,
  300: #618cb7,
  400: #3f73a7,
  500: #0075c9,
  600: #1a5290,
  700: #154885,
  800: #113f7b,
  900: #0a2e6a,
  A100: #9cbcff,
  A200: #6999ff,
  A400: #3676ff,
  A700: #1c65ff,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #000000,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #000000,
    A400: #ffffff,
    A700: #ffffff
  )
);

$warn-palette: (
  50: #ffebee,
  100: #ffcdd2,
  200: #ef9a9a,
  300: #e57373,
  400: #ef5350,
  500: #f44336,
  600: #e53935,
  700: #d32f2f,
  800: #c62828,
  900: #b71c1c,
  A100: #ff8a80,
  A200: #ff5252,
  A400: #ff1744,
  A700: #d50000,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #000000,
    400: #000000,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #ffffff,
    A400: #ffffff,
    A700: #ffffff,
  )
);

$text: map.get($primary-palette, 900);
$secondary-text: map.get($primary-palette, 300);
$light-text: white;
$light-secondary-text: rgba(white, 0.6);
$dividers: map.get($primary-palette, 100);
$focused: map.get($accent-palette, 500);
$background: white;
$secondaryBackground: #f5f5f8;
$success: #0ccf9e;
$lite-success: #b4f0e1;
$caution: #ffb300;
$fab-background: #ffdf1c;
$highlight: #ebf6ff;
$text-highlight: #ffff00;
$warning: #e539351a;
$warning-outline: #e53935;
$tabsicons: #f581f1;
$polygon-on: #1efac180;
$polygon-off: #1b1a1c33;
$slider-gradient-1: #70cdfc;
$slider-gradient-2: #9dfcff;
$slider-gradient-3: #faff86;
$slider-gradient-4: #fdcb2b;
$slider-gradient-5: #fb3502;
$slider-thumb-1: #8f4444;
$slider-thumb-2: #08c557;
$loading-backdrop: #1B1A1C;

$background-palette: (
  status-bar: map.get($accent-palette, 500),
  app-bar: map.get($primary-palette, 900),
  background: $background,
  hover: rgba(map.get($accent-palette, 50), 0.2),
  card: white,
  dialog: $background,
  disabled-button: map.get($accent-palette, 500),
  raised-button: white,
  focused-button: $focused,
  selected-button: map.get($accent-palette, 50),
  selected-disabled-button: map.get($accent-palette, 100),
  disabled-button-toggle: map.get($accent-palette, 100),
  unselected-chip: map.get($accent-palette, 300),
  disabled-list-option: map.get($primary-palette, 200),
  tooltip: map.get($primary-palette, 700),
  secondary-background: $secondaryBackground,
  custom-fab: map.get($accent-palette, 700),
  active-accent: rgba($success, 0.2),
  dropdown-background: $highlight,
  loading-backdrop: $loading-backdrop,
);

$foreground-palette: (
  base: map.get($accent-palette, 500),
  divider: $dividers,
  dividers: $dividers,
  disabled: map.get($accent-palette, 100),
  disabled-button: map.get($primary-palette, 100),
  disabled-text: map.get($primary-palette, 100),
  elevation: map.get($primary-palette, 300),
  hint-text: $text,
  secondary-text: $secondary-text,
  icon: map.get($accent-palette, 50),
  icons: map.get($accent-palette, 50),
  text: $text,
  slider-min: rgba(map.get($accent-palette, 700), 0.87),
  slider-off: rgba(map.get($accent-palette, 700), 0.26),
  slider-off-active: rgba(map.get($accent-palette, 700), 0.38),
  active-accent: $success,
  caution: $caution,
  tab-icon: #f581f1,
  slider-gradient-1: #70cdfc,
  slider-gradient-2: #9dfcff,
  slider-gradient-3: #faff86,
  slider-gradient-4: #fdcb2b,
  slider-gradient-5: #fb3502,
  slider-thumb-1: #8f4444,
  slider-thumb-2: #08c557,
  warning: #e539351a,
  warning-outline: #e53935,
  polygon-on: #1efac180,
  polygon-off: #1b1a1c33,
  selected: rgba($focused, 0.1),
  inactive-icon: #5F5F60,
  on-surface: pink
);

$primary-palette: mat.define-palette($primary-palette, 500);

$accent-palette: mat.define-palette($accent-palette, 500);

$warn-palette: mat.define-palette($warn-palette, 700);

$custom-typography-config: mat.define-typography-config(
  $font-family: 'Aeonik',
);

$primary-theme: (
  color: (
    primary: $primary-palette,
    accent: $accent-palette,
    warn: $warn-palette,
    is-dark: false,
    foreground: $foreground-palette,
    background: $background-palette,
  ),
  typography: $custom-typography-config,
  density: 0
);

正确的主题定制方案

1. 全局定制按钮样式(利用组件主题混入)

Angular Material 15基于MDC组件,每个组件都提供了官方Sass混入用于覆盖默认样式变量。以按钮禁用状态为例:

// 先初始化全局按钮主题
@include mat.button-theme($primary-theme);

// 自定义按钮禁用状态的颜色变量
@include mat.button-color($primary-theme, (
  disabled-container: mat.get-color-from-palette($accent-palette, 500, 0.3),
  disabled-label-text: mat.get-color-from-palette($background-palette, background, 0.3)
));

2. 局部定制特定按钮样式

如果仅需给部分按钮定制样式,可结合自定义类和组件混入:

// 给目标按钮添加custom-disabled-button类
.custom-disabled-button {
  @include mat.button-color($primary-theme, (
    disabled-container: mat.get-color-from-palette($accent-palette, 500, 0.3),
    disabled-label-text: mat.get-color-from-palette($background-palette, background, 0.3)
  ));
}

注意:需确保这段代码在主题初始化之后调用,若优先级不足,可通过父容器类包裹提升权重。

3. 通过调色板全局覆盖

若希望所有组件的对应状态统一生效,可在背景/前景调色板中添加对应变量,再重新生成主题:

// 扩展背景调色板,添加按钮禁用容器色
$background-palette: map.merge($background-palette, (
  button-disabled-container: mat.get-color-from-palette($accent-palette, 500, 0.3)
));

// 重新生成主题
$primary-theme: (
  color: (
    primary: $primary-palette,
    accent: $accent-palette,
    warn: $warn-palette,
    is-dark: false,
    foreground: $foreground-palette,
    background: $background-palette,
  ),
  typography: $custom-typography-config,
  density: 0
);

// 初始化按钮主题
@include mat.button-theme($primary-theme);

关键注意事项

  • 禁止直接修改mat-mdc-*类或MDC内部CSS变量,这些属于私有实现,版本升级时会随时变更。
  • 所有样式定制必须通过Angular Material官方提供的Sass混入和主题API完成,保证跨版本兼容性。
  • 组件主题混入需在mat.core()之后调用,且确保主题变量已正确定义。

内容的提问来源于stack exchange,提问作者Michael Broussard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:22:32