Angular Material2 主题 - 如何设置应用背景?

Angular Material2 theming - how to set app background?

我正在使用 angular material2 构建一个 angular2 应用程序。我正在尝试设置我的应用程序的背景 "the correct way",但我不知道如何设置。

我找到了一个 class 我可以在我的 <body> 元素上使用:mat-app-background 我可以添加它,它给我一个默认颜色(取决于我是否使用浅色或深色主题)。

我想定义此背景颜色以使用我的品牌颜色,但我不知道该怎么做。

_theming.scss中是这样定义的:

// Mixin that renders all of the core styles that depend on the theme.
@mixin mat-core-theme($theme) {
  @include mat-ripple-theme($theme);
  @include mat-option-theme($theme);
  @include mat-pseudo-checkbox-theme($theme);

  // Wrapper element that provides the theme background when the
  // user's content isn't inside of a `md-sidenav-container`.
  .mat-app-background {
    $background: map-get($theme, background);
    background-color: mat-color($background, background);
  }
  ...
}

所以我认为尝试将背景颜色添加到我的自定义主题中是有意义的,但我不明白该怎么做。

在 Material2 theming 文档中它只说:

”在Angular Material中,一个主题是通过组合多个调色板来创建的。具体而言,一个主题包括:

如何将我的背景添加到主题中,或以任何其他方式添加?

还有这样的混色:

.your-class-here {
   background: mat-color($mat-grey, 700, 0.9);
}

查看 angular material 个组件时,您可以像这样分配颜色。

<md-toolbar color="primary">
</md-toolbar>

这将使您的工具栏成为您的主要颜色。

还要确保查看 angular material 中的 _theming.scss 文件。

这样您就可以使用这些混合函数从您的调色板中提取一种颜色。

我建议您在变量文件中声明背景颜色(假设您使用的是 sass),然后在需要的地方简单地导入它。例如:-

@import '../config/variables';

body {
    height: 100%;
    margin: 0;
    background-color: $brand-primary;
}

参见:palette theme scss on github Angular (2) Material (2)

代码摘录:

// Background palette for light themes.
$mat-light-theme-background: (
  status-bar: map_get($mat-grey, 300),
  app-bar:    map_get($mat-grey, 100),
  background: map_get($mat-grey, 50),
  hover:      rgba(black, 0.04), // TODO(kara): check style with Material Design UX
  card:       white,
  dialog:     white,
  disabled-button: $black-12-opacity,
  raised-button: white,
  focused-button: $black-6-opacity,
  selected-button: map_get($mat-grey, 300),
  selected-disabled-button: map_get($mat-grey, 400),
  disabled-button-toggle: map_get($mat-grey, 200),
);

// Background palette for dark themes.
$mat-dark-theme-background: (
  status-bar: black,
  app-bar:    map_get($mat-grey, 900),
  background: #303030,
  hover:      rgba(white, 0.04), // TODO(kara): check style with Material Design UX
  card:       map_get($mat-grey, 800),
  dialog:     map_get($mat-grey, 800),
  disabled-button: $white-12-opacity,
  raised-button: map-get($mat-grey, 800),
  focused-button: $white-6-opacity,
  selected-button: map_get($mat-grey, 900),
  selected-disabled-button: map_get($mat-grey, 800),
  disabled-button-toggle: map_get($mat-grey, 1000),
);

// Foreground palette for light themes.
$mat-light-theme-foreground: (
  base:              black,
  divider:           $black-12-opacity,
  dividers:          $black-12-opacity,
  disabled:          rgba(black, 0.38),
  disabled-button:   rgba(black, 0.38),
  disabled-text:     rgba(black, 0.38),
  hint-text:         rgba(black, 0.38),
  secondary-text:    rgba(black, 0.54),
  icon:              rgba(black, 0.54),
  icons:             rgba(black, 0.54),
  text:              rgba(black, 0.87),
  slider-off:        rgba(black, 0.26),
  slider-off-active: rgba(black, 0.38),
);

// Foreground palette for dark themes.
$mat-dark-theme-foreground: (
  base:              white,
  divider:           $white-12-opacity,
  dividers:          $white-12-opacity,
  disabled:          rgba(white, 0.3),
  disabled-button:   rgba(white, 0.3),
  disabled-text:     rgba(white, 0.3),
  hint-text:         rgba(white, 0.3),
  secondary-text:    rgba(white, 0.7),
  icon:              white,
  icons:             white,
  text:              white,
  slider-off:        rgba(white, 0.3),
  slider-off-active: rgba(white, 0.3),
);

没有办法做到这一点 "properly" - 只有解决方法和技巧。您的主题可以定义主要、次要和警告调色板,但不能定义前景和背景调色板。在 Angular Material 中没有 direct/easy 方法的可能原因是,根据 Material 设计,您不应该这样做。颜色旨在根据您的主题以特定方式使用以突出显示和设置各种元素的样式,但普通内容的背景和前景颜色应该是深灰色或浅灰色 - 而不是彩色。如果您确实需要这样做,关于重新定义背景主题或使用您自己的其他建议class 应该就足够了。

编辑:此策略涉及替换 Material 功能。对于大多数情况,我会推荐 Jake Stoeffler 上面的回答。

如果您想设置背景颜色,您可能希望通过模拟 mat-light-theme or mat-dark-theme functions with your own replacement. Your replacement would include your own palettes instead of the mat-light-theme-foreground 和背景调色板来自定义整个背景和前景调色板。

示例:https://stackblitz.com/edit/angular-material-custom-background?file=theme.scss

不知道这个方法是推荐的还是官方支持的

如果您想以干净的方式更改整个应用的主题背景颜色,您可以使用以下内容覆盖您的主题。

// Set custom background color
$custom-background-color: map_get($mat-blue-grey, 50);

// -or- Can set colour by hex value too
$custom-background-color: #628cc9;

$background: map-get($theme, background);
$background: map_merge($background, (background: $custom-background-color));
$theme: map_merge($theme, (background: $background));

这假设您已经使用 mat-light-thememat-dark-theme 设置了 $theme。当然,您可以用 $mat-blue-grey 替换您选择的颜色图。

这是我如何使用它的完整示例。我在名为 theme.scss 的文件中包含以下内容,该文件包含在我的 angular.json“样式”条目中:

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core;

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue.
$primary: mat-palette($mat-red, 600, 400, 900);
$accent: mat-palette($mat-blue-grey, 500, 200, 700);
$background-color: map_get($mat-blue-grey, 50);

// The warn palette is optional (defaults to red).
$warn: mat-palette($mat-blue);

// Create the theme object (a Sass map containing all of the palettes).
$theme: mat-light-theme($primary, $accent, $warn);

// Insert custom background color
$background: map-get($theme, background);
$background: map_merge($background, (background: $background-color));
$theme: map_merge($theme, (background: $background));

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($theme);
@include my-app-theme($theme);

额外的解决方案,如果以前没有工作我 angular material 2 使用 封装样式 所以无论你要做什么,你都不能自定义 angular material来自外部的组件,这是我一直使用的理想解决方案试试这个

1- 如果您想通过设置 ViewEncapsulation.None

//test.component.ts
import { ViewEncapsulation } from '@angular/core';
@Component({
  selector: 'app-test',
  templateUrl: '.....',
  styleUrls: ['....'],
  encapsulation: ViewEncapsulation.None
})

2- 如果你只想改变背景,你可以简单地试试这个

//style.css (main style file)
html, body {
  background-color: #fafafa;
}

这将改变您所有应用的整个背景颜色

不完全回答你的问题,但我想很多人最终会在这里搜索 "how to set app background color"。

在您的 project/index.html 中将 body class 设置为 mat-app-background

<body class="mat-app-background">
  <app-root></app-root>
</body>

并确保在您的 project/angular.json 中您有:

        "styles": [
          "./node_modules/@angular/material/prebuilt-themes/YOUR_STYLE.css",
          ...
        ],

我发现接受的解决方案不适用于angular 9。但是稍作调整,您就可以让它工作。

最初的问题是如何将背景颜色变量添加到自定义 material 主题。您可以执行以下操作。

styles.scss

// Only import this one time in your project
@include mat-core;

@import '~@angular/material/theming';

// Divine what you want the 'default' variables to look like
$primary: mat-palette($mat-grey, 700, 300, 900);
$accent: mat-palette($mat-blue-grey, 400);
$warn: mat-palette($mat-red, 500);

// create a theme. This can be mat-dark-theme or mat-light-theme
$theme: mat-dark-theme(
  $primary,
  $accent,
  $warn
);

/* This is where you create your custom variable map
Make sure that the variable name you chose is one that does not exist in 
the $theme map. In the accept answer, it uses $background but this one is 
already taken. By using for example, 'background-of-main' you are sure 
that there is no collision */
// You can choose any #hexa color code you want
$custom-variables: (background-of-main: #48494d);

// Merge theme and the custom variables together
$theme: map_merge($theme, $custom-variables);

// Expose custom theme globally
@include angular-material-theme($theme);

在要使用背景变量的组件中,可以进行如下操作。我为下面的代码创建了一个单独的文件:

<path-to-component>/custom-background-component-theme.scss

@import '~@angular/material/theming';

@mixin custom-background-component-theme($theme) {
  $background: map-get($theme, background-of-main);

  <css-selector> {
    background-color: $background;
  }

最后一步是调用 styles.scss 中的 custom-background-component-theme mixin。因此 styles.scss 的最终版本是:

styles.scss

// Only import this one time in your project
@include mat-core;

@import '~@angular/material/theming';

// Divine what you want the 'default' styles to look like
$primary: mat-palette($mat-grey, 700, 300, 900);
$accent: mat-palette($mat-blue-grey, 400);
$warn: mat-palette($mat-red, 500);

// create a theme. This can be mat-dark-theme or mat-light-theme
$theme: mat-dark-theme(
  $primary,   
  $accent,
  $warn
);

/* This is where you create your custom variable map
Make sure that the variable name you chose is one that does not exist in 
the $theme map. In the accept answer, it uses $background but this one is 
already taken. By using for example, 'background-of-main' you are 
sure that there is not collision */
// You can choose any #hexa color code you want
$custom-variables: (background-of-main: #48494d);

// Merge theme and the custom variables together
$theme: map_merge($theme, $custom-variables);

// Expose custom theme globally
@include angular-material-theme($theme);

// Import custom mixin
@import './<path-to-component>/custom-background-component-theme.scss';

// Insert custom theme into component styling
@include custom-background-component-theme($theme);

这应该可以完成工作!

最近,从 Material 10.x 开始,主题方法正在改进。使用新方法 mat-light-thememat-dark-theme 只接受颜色的配置对象。这是我在评论中找到的内容:

Previously in Angular Material, theme objects contained the color configuration directly. With the recent refactoring of the theming system to allow for density and typography configurations, this is no longer the case.

目前这些方法也支持遗留方法,但我希望很快这将被宣布为重大更改。由于我们无法像以前那样将新背景合并到主题对象,因此接受的答案可能不再有效。

我没有这样做,而是在创建新主题之前用我的自定义背景更新了 $mat-light-theme-background 调色板并完成了工作。

$app-primary: mat-palette($md-light);
$app-accent: mat-palette($mat-pink, A200, A100, A400);
$app-warn: mat-palette($mat-red);
$custom-background-color: map_get($md-light, 50);

$mat-light-theme-background: map_merge($mat-light-theme-background, (background: $custom-background-color));

$light-theme: mat-light-theme((
    color: (
        primary: $app-primary,
        accent: $app-accent,
        warn:  $app-warn
    )
));

注意:$md-light 是我为我的应用程序定义的自定义托盘,您可以使用任何其他值。 我也尝试传递 'background' 以及其他颜色属性,但由于某些原因不起作用。

包含主题的方式也略有变化。现在有一种名为 angular-material-color 的新方法用于包含主题。

@include angular-material-color($light-theme);

聚会有点晚了。我知道这是 Angular Material 2 但是,google 引向这里 material。添加我的发现。

Angular Material 确实让在 Material 11.2 中更改背景和前景样式变得有点困难。我浏览了主题文件以了解它是如何工作的。

更改主题背景。假设您有 core.scss 文件,其中包含与您的主题相关的样式。 Material Doc

$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);
$candy-app-warn:    mat-palette($mat-red);

您可以通过修改 $mat-light-theme-background 浅色主题和深色主题来更改主题背景。使用 map-merge 来防止不必要的问题。

$mat-light-theme-background: map-merge($mat-light-theme-background, (
   app-bar: map-get($mat-grey, A100), // Change color to whatever you want.
   background: map-get($mat-grey, A100) // Change color to whatever you want. 
));

// Follow by calling mat-light-theme(//) or mat-dark-theme(//)

这将更改 Angular 应用程序的背景。

添加我在 Angular Material 12 中尝试执行此操作的经验,(特别是:"@angular/material": "~12.2.0-sha-7a97590aeb")似乎改变了很多这些功能。不是一个非常有经验的网络开发人员,所以请耐心等待。

我想要一个 light/dark/black 主题,其中黑色主题是背景设置为黑色的深色主题。我从 docs:

中的示例开始
$dark-theme: mat.define-dark-theme((
  color: (
    primary: $dark-primary,
    accent: $dark-accent,
    warn: $dark-warn,
  )
));

此时 $dark-theme 拿着一个物体,里面有一堆风格的东西。背景颜色的对象路径是 $dark-theme.color.background.background,您必须使用 map_get & map_merge.

提取和设置它
$background-color: black;

// note- this is a reference, but will get it's own copy later on
$black-theme: $dark-theme;

// get $black-theme-color.color.background
$black-theme-color-config: map_get($black-theme, 'color');
$black-theme-color-config-background: map_get($black-theme-color-config, 'background');

// set $black-theme-color.color.background.background
$black-theme-color-config-background: map_merge($black-theme-color-config-background, ('background': $background-color));
$black-theme-color-config: map_merge($black-theme-color-config, ('background': $black-theme-color-config-background));
$black-theme: map_merge($black-theme, ('color': $black-theme-color-config));

此时,$black-theme$dark-theme 相同,只是背景现在是 #000000,这符合我的需要。

我怀疑这是否受支持并且将来可能会改变,所以使用风险自负。

我确实发现了一个要求添加这个的问题,所以如果你希望它得到官方支持,你可以在 https://github.com/angular/components/issues/6244 上投票给它。

此解决方案在 Angular Material 12

工作

_前景-背景-light.scss

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


$light-primary-color: map_get($md-white-blue-cotcha, 500);
$light-secondary-color: map_get($md-red-cotcha, 500);

$dark-primary-text: rgba(black, 0.87);
$dark-secondary-text: rgba(black, 0.54);
$dark-dividers: rgba(black, 0.12);
$dark-disabled-text: rgba(black, 0.38);
$dark-focused: rgba(black, 0.12);

$light-primary-text: white;

$grey-palette: (
  50: #fafafa,
  100: #f5f5f5,
  200: #eeeeee,
  300: #e0e0e0,
  400: #bdbdbd,
  500: #9e9e9e,
  600: #757575,
  700: #616161,
  800: #424242,
  900: #212121,
  A100: #ffffff,
  A200: #eeeeee,
  A400: #bdbdbd,
  A700: #616161,
  contrast: (
    50: $dark-primary-text,
    100: $dark-primary-text,
    200: $dark-primary-text,
    300: $dark-primary-text,
    400: $dark-primary-text,
    500: $dark-primary-text,
    600: $light-primary-text,
    700: $light-primary-text,
    800: $light-primary-text,
    900: $light-primary-text,
    A100: $dark-primary-text,
    A200: $dark-primary-text,
    A400: $dark-primary-text,
    A700: $light-primary-text,
  )
);


// get color of light-theme
$mat-light-theme-color: map_get($mat-light-theme, 'color');

// get Foreground palette for light theme
$light-theme-foreground-palette: map_get($mat-light-theme-color, 'foreground');

// set Foreground palette for light theme.
$light-theme-foreground-palette: map_merge($light-theme-foreground-palette,
  (
    'base':              black,
    'divider':           $dark-dividers,
    'dividers':          $dark-dividers,
    'disabled':          $dark-disabled-text,
    'disabled-button':   rgba(black, 0.26),
    'disabled-text':     $dark-disabled-text,
    'elevation':         black,
    'hint-text':         $dark-disabled-text,
    'secondary-text':    $dark-secondary-text,
    'icon':              rgba(black, 0.54),
    'icons':             rgba(black, 0.54),
    'text':              rgba(black, 0.87),
    'slider-min':        rgba(black, 0.87),
    'slider-off':        rgba(black, 0.26),
    'slider-off-active': rgba(black, 0.38),
  )
);

// get Background palette for light theme.
$light-theme-background-palette: map_get($mat-light-theme-color, 'background');

// set Background palette for light theme.
$light-theme-background-palette: map_merge($light-theme-background-palette,
  (
    'status-bar':               map.get($grey-palette, 300),
    'app-bar':                  map.get($grey-palette, 100),
    'background':               $light-primary-color,
    'hover':                    rgba(black, 0.04), // TODO(kara)': check style with Material Design UX
    'card':                   white,
    'dialog':                 white,
    'disabled-button':          rgba(black, 0.12),
    'raised-button':          white,
    'focused-button':           $dark-focused,
    'selected-button':          map.get($grey-palette, 300),
    'selected-disabled-button': map.get($grey-palette, 400),
    'disabled-button-toggle':   map.get($grey-palette, 200),
    'unselected-chip':          map.get($grey-palette, 300),
    'disabled-list-option':     map.get($grey-palette, 200),
    'tooltip':                  map.get($grey-palette, 700),
  )
);

//set color for light theme.
$mat-light-theme-color: map_merge($mat-light-theme-color, 
  (
    'foreground': $light-theme-foreground-palette,
    'background': $light-theme-background-palette
  )
);
  
// set light theme.
$mat-light-theme: map_merge($mat-light-theme, 
  (
    'color': $mat-light-theme-color
  )
);

styles.scss

@use '~@angular/material' as mat;


@include mat.core();


@import './styles/foreground-background-light';

实施良好

Angular 12

// For example Orange palette
$orange-palette: mat.define-palette(mat.$orange-palette);

// Define theme
$theme: mat.define-dark-theme((
  color: (
    primary: $orange-palette,
    accent: $orange-palette
  )
));

// Get color param from our theme
$palette-color : map-get($theme, color);
// Get background param from color param
$background: map-get($palette-color, background);
// $background also has background param contains color, set it to red (for example)
$background: map_merge($background, (background: red));
// Set background param for palette
$palette-color: map_merge($palette-color, (background: $background));
// Set palette for theme
$theme: map_merge($theme, (color: $palette-color));

@include mat.all-component-themes($theme);

或函数:

@function mat-set-background($theme, $backgroundColor) {
  $palette-color : map-get($theme, color);
  $background: map-get($palette-color, background);
  $background: map_merge($background, (background: $backgroundColor));
  $palette-color: map_merge($palette-color, (background: $background));
  @return map_merge($theme, (color: $palette-color));
}

$orange-palette: mat.define-palette(mat.$orange-palette);

$theme: mat.define-dark-theme((
  color: (
    primary: $orange-palette,
    accent: $orange-palette
  )
));

$theme: mat-set-background($theme, #FF0000);
@include mat.all-component-themes($theme);