如何正确设置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
相关产品推荐
相关产品推荐

