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

如何在其他CSS中使用Angular Material当前主题颜色?

问题:如何在Angular Material中根据动态主题获取primary/accent/warn颜色设置Snackbar样式

背景

我的应用使用自定义Angular Material主题,支持根据系统偏好自动切换深色/浅色模式,主题代码themes.css如下:

@use '@angular/material' as mat;

@include mat.core();

$myapp-light-theme-primary: mat.define-palette(mat.$indigo-palette, 700, 300, 900);
$myapp-light-theme-accent: mat.define-palette(mat.$pink-palette);
$myapp-light-theme-warn: mat.define-palette(mat.$deep-orange-palette, A200);

$myapp-light-theme: mat.define-light-theme((color: (primary: $myapp-light-theme-primary,
                accent: $myapp-light-theme-accent,
                warn: $myapp-light-theme-warn),
            typography: mat.define-typography-config(),
            density: 0,
        ));

$myapp-dark-theme-primary: mat.define-palette(mat.$light-blue-palette, A200);
$myapp-dark-theme-accent: mat.define-palette(mat.$light-green-palette, A200);
$myapp-dark-theme-warn: mat.define-palette(mat.$yellow-palette, A200);

$myapp-dark-theme: mat.define-dark-theme((color: (primary: $myapp-dark-theme-primary,
                accent: $myapp-dark-theme-accent,
                warn: $myapp-dark-theme-warn),
            typography: mat.define-typography-config(),
            density: 0,
        ));

// 默认应用浅色主题
@include mat.core-theme($myapp-light-theme);
@include mat.all-component-themes($myapp-light-theme);

// 系统偏好深色时切换主题
@media (prefers-color-scheme: dark) {
    @include mat.core-theme($myapp-dark-theme);
    @include mat.all-component-themes($myapp-dark-theme);
}

当前实现

我通过MatSnackBarConfig的panelClass属性为Snackbar添加自定义类,在styles.css中定义了样式:

.custom-snackbar {
    .mat-mdc-snack-bar-container .mdc-snackbar__surface {
        border-radius: 8px !important;
    }

    .mat-mdc-button.mat-mdc-snack-bar-action {
        color: white !important;
    }
}

.snackbar-success {
    .mdc-snackbar__surface {
        background-color: green !important;
    }

    .mdc-snackbar__label {
        color: white !important;
    }
}

.snackbar-error {
    .mdc-snackbar__surface {
        background-color: red !important;
    }

    .mdc-snackbar__label {
        color: white !important;
    }
}

.snackbar-info {
    .mdc-snackbar__surface {
        background-color: var(--color-accent) !important;
    }

    .mdc-snackbar__label {
        color: white !important;
    }
}

.snackbar-warn {
    .mdc-snackbar__surface {
        background-color: yellow !important;
    }

    .mdc-snackbar__label {
        color: black !important;
    }

    .mat-mdc-button.mat-mdc-snack-bar-action {
        color: black !important;
    }
}

核心问题

如何通过纯CSS方式获取当前主题的primary、accent、warn颜色,避免硬编码固定值,确保样式能跟随深浅主题自动切换?


解决方案

步骤1:在主题文件中定义全局CSS变量

修改themes.css,在应用深浅主题的同时,将主题色映射为全局CSS变量,这样CSS可以直接引用这些变量并跟随主题切换:

@use '@angular/material' as mat;

@include mat.core();

// ... 保留原有主题变量定义代码 ...

// 默认应用浅色主题并定义变量
@include mat.core-theme($myapp-light-theme);
@include mat.all-component-themes($myapp-light-theme);

:root {
  --primary-color: #{mat.get-color-from-palette($myapp-light-theme-primary, default)};
  --accent-color: #{mat.get-color-from-palette($myapp-light-theme-accent, default)};
  --warn-color: #{mat.get-color-from-palette($myapp-light-theme-warn, default)};
  // 同时定义对应的文本对比色,确保可读性
  --primary-text-color: #{mat.get-color-from-palette($myapp-light-theme-primary, contrast-text)};
  --accent-text-color: #{mat.get-color-from-palette($myapp-light-theme-accent, contrast-text)};
  --warn-text-color: #{mat.get-color-from-palette($myapp-light-theme-warn, contrast-text)};
}

// 系统偏好深色时切换主题并覆盖变量
@media (prefers-color-scheme: dark) {
    @include mat.core-theme($myapp-dark-theme);
    @include mat.all-component-themes($myapp-dark-theme);

    :root {
      --primary-color: #{mat.get-color-from-palette($myapp-dark-theme-primary, default)};
      --accent-color: #{mat.get-color-from-palette($myapp-dark-theme-accent, default)};
      --warn-color: #{mat.get-color-from-palette($myapp-dark-theme-warn, default)};
      --primary-text-color: #{mat.get-color-from-palette($myapp-dark-theme-primary, contrast-text)};
      --accent-text-color: #{mat.get-color-from-palette($myapp-dark-theme-accent, contrast-text)};
      --warn-text-color: #{mat.get-color-from-palette($myapp-dark-theme-warn, contrast-text)};
    }
}

步骤2:在styles.css中使用全局变量替换硬编码颜色

修改Snackbar的自定义样式,用全局CSS变量代替固定颜色值:

.custom-snackbar {
    .mat-mdc-snack-bar-container .mdc-snackbar__surface {
        border-radius: 8px !important;
    }

    .mat-mdc-button.mat-mdc-snack-bar-action {
        color: var(--primary-text-color) !important;
    }
}

.snackbar-success {
    .mdc-snackbar__surface {
        background-color: var(--primary-color) !important;
    }

    .mdc-snackbar__label {
        color: var(--primary-text-color) !important;
    }
}

.snackbar-error {
    .mdc-snackbar__surface {
        background-color: var(--warn-color) !important;
    }

    .mdc-snackbar__label {
        color: var(--warn-text-color) !important;
    }
}

.snackbar-info {
    .mdc-snackbar__surface {
        background-color: var(--accent-color) !important;
    }

    .mdc-snackbar__label {
        color: var(--accent-text-color) !important;
    }
}

.snackbar-warn {
    .mdc-snackbar__surface {
        background-color: var(--warn-color) !important;
    }

    .mdc-snackbar__label {
        color: var(--warn-text-color) !important;
    }

    .mat-mdc-button.mat-mdc-snack-bar-action {
        color: var(--warn-text-color) !important;
    }
}

说明

  • 使用mat.get-color-from-palette函数可以从主题调色板中提取指定色调的颜色,确保和Angular Material组件使用的颜色完全一致
  • 定义对比文本色可以保证在不同主题下文本始终具备可读性,无需手动判断深浅色
  • 全局CSS变量会跟随prefers-color-scheme媒体查询自动切换,实现纯CSS的动态主题适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:06:03