角材料-全局颜色变量

NRa*_*Raf 6 css sass angular-material2 angular

他们查看Angular Material文档时,建议使用-theme每个组件一个文件来管理将与主题相关的样式应用于特定类。

在我看来,这种方法的一些缺点是:

  • 很冗长
  • 将样式分为两个不同的位置
  • 您所有的前端开发人员都需要了解Angular Material颜色如何工作
  • 使得更改值变得更加困难(例如,我们可能一直在使用mat-color($primary, 200)边框颜色,现在想将其更改为mat-color($primary, 300)。这将在整个代码库中重复进行。

给定一致的设计语言,将仅使用一部分颜色(例如,主调色板中的4种颜色,重点调色板中的3种颜色,一些不同的前景色/背景色等)。

鉴于以上所述,_colors.scss使用主题定义确切的颜色,而不是希望开发人员每次都从主题中提取正确的值,不是更有意义吗?

例如,也许像这样:

  $clr-primary-default: mat-color($primary);
  $clr-primary-contrast: mat-color($primary, default-contrast);
  $clr-primary-light: mat-color($primary, lighter);
  $clr-primary-dark: mat-color($primary, darker);

  $clr-accent-default: mat-color($accent);
  $clr-accent-light: mat-color($accent, lighter);
  $clr-accent-dark: mat-color($accent, darker);

  $clr-default-text: mat-color($foreground);
  $clr-secondary-text: mat-color($foreground, secondary-text);

  //etc
Run Code Online (Sandbox Code Playgroud)

然后-theme,我无需为需要特定颜色的每个组件创建单独的文件,而是可以简单地导入colors.scss文件并直接在*.component.scss文件中使用变量。

只是想验证上面的内容是否正确,并且我没有错过任何明显的会引起麻烦的东西?

另一个棘手的部分是如何colors有效地在单独的文件中定义它们,因为该文件需要访问主题数据。

lev*_*ney 9

我已将主色、强调色和警告色定义为styles.css文件中的 css 自定义变量,如下所示:

@import "~@angular/material/theming";
@include mat-core();

$my-primary: mat-palette($mat-blue-grey);
$my-accent: mat-palette($mat-amber, A200, A100, A400);
$my-warn: mat-palette($mat-deep-orange);

$my-2-primary: mat-palette($mat-pink, 400, 200, 600);
$my-2-accent: mat-palette($mat-blue, A200, A100, A400);
$my-2-warn: mat-palette($mat-deep-orange, 500, 300, 700);

.dark-theme {
  $my-theme-dark: mat-dark-theme($my-primary, $my-accent, $my-warn);
  @include angular-material-theme($my-theme-dark);
  $primary: mat-color($my-primary);
  $accent: mat-color($my-accent);
  $warn: mat-color($my-warn);
  $fg_palette:map-get($my-theme-dark, foreground);
  $bg_palette:map-get($my-theme-dark, background);
  $fg:map-get($fg_palette, text);
  $bg:map-get($bg_palette, background);

  --primary: #{$primary};
  --accent: #{$accent};
  --warn: #{$warn};
  --fg: #{$fg};
  --bg: #{$bg};
}

.dark-theme-2 {
  $my-2-theme-dark: mat-dark-theme($my-2-primary, $my-2-accent, $my-2-warn);
  @include angular-material-theme($my-2-theme-dark);
  $primary: mat-color($my-2-primary);
  $accent: mat-color($my-2-accent);
  $warn: mat-color($my-2-warn);
  $fg_palette:map-get($my-2-theme-dark, foreground);
  $bg_palette:map-get($my-2-theme-dark, background);
  $fg:map-get($fg_palette, text);
  $bg:map-get($bg_palette, background);

  --primary: #{$primary};
  --accent: #{$accent};
  --warn: #{$warn};
  --fg: #{$fg};
  --bg: #{$bg};
}
Run Code Online (Sandbox Code Playgroud)

并在我的任何组件中使用这些变量,如下所示:(在my-custom-component.scss中)

.some-class {
    color: var(--primary)
}

.another-class {
    background-color: var(--bg)
}

.yet-another-class {
    border-color: var(--accent)
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,我可以更改任何组件中与颜色相关的任何值,因为这些变量是全局的(在 styles.css 中定义)当我更改主题时,这些颜色也会根据新主题的颜色而变化


Fri*_*ich 5

为什么要使用@mixin

只是想验证上面的内容是否正确,并且我没有错过任何明显的会引起麻烦的东西?

我能想到的唯一一件事是,您将错过在一个应用程序中使用多个主题的机会。使用Angular Material文档中的方法,您将对@mixin每个组件都有一个,可以@include使用不同的$theme变量多次。

来自https://medium.com/@tomastrajan/the-complete-guide-to-angular-material-themes-4d165a9d24d1的示例:

.default-theme {
  @include angular-material-theme($theme);
  @include custom-component-theme($theme);
}

.light-theme {
  @include angular-material-theme($light-theme);
  @include custom-component-theme($light-theme);
}
Run Code Online (Sandbox Code Playgroud)

如果将颜色作为scss变量导入到组件中并在其中使用,则此方法将无效。

颜色的单独文件

另一个棘手的部分是如何有效地在单独的颜色文件中定义它们,因为该文件需要访问主题数据。

这其实是非常简单的:我有一个单独的文件src/styles/_variables.scss,它包含我的自定义颜色SCSS变量和$theme变量,我在以后的使用src/theme.scss

@import '~@angular/material/theming';
// Theme configuration
$primary: mat-palette($mat-blue, 800, 500, 900);
$accent:  mat-palette($mat-blue, A200, A100, A400);
$warn: mat-palette($mat-red);

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

// Custom colors
$custom-colors: (
  custom-color-a: mat-color($mat-green, 700),
  custom-color-b: mat-color($mat-red, 400),
);
$theme: map-merge($theme, (custom-colors: $custom-colors));
Run Code Online (Sandbox Code Playgroud)

要导入我_variables.scss的组件内部,我必须添加stylePreprocessorOptionsangular.json文件中

@import '~@angular/material/theming';
// Theme configuration
$primary: mat-palette($mat-blue, 800, 500, 900);
$accent:  mat-palette($mat-blue, A200, A100, A400);
$warn: mat-palette($mat-red);

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

// Custom colors
$custom-colors: (
  custom-color-a: mat-color($mat-green, 700),
  custom-color-b: mat-color($mat-red, 400),
);
$theme: map-merge($theme, (custom-colors: $custom-colors));
Run Code Online (Sandbox Code Playgroud)

现在,我可以将变量导入组件的所有scss文件中:

"styles": [
  "src/styles.scss",
  "src/theme.scss"
],
"stylePreprocessorOptions": {
  "includePaths": [
    "src/styles"
  ]
},
Run Code Online (Sandbox Code Playgroud)

为什么要使用sass-mapmap-merge

正如您所注意到的,我在sass-map中收集我的自定义颜色$custom-colors,并将它们合并到我的$theme变量中。这样,我可以通过将自定义颜色直接导入到我的组件样式表中来使用自定义颜色(如上所述)也可以@mixin按照Angular Material文档中描述的方式在我的组件内部使用它们。

@import 'variables';

.custom-class-a {
  background-color: map-get($custom-colors, custom-color-a);
  color: map-get($custom-colors, custom-color-b);
}
Run Code Online (Sandbox Code Playgroud)

也许这种组合是您的前端开发人员可以使用的方式?


Alo*_*keT 2

我正在开发一个使用 Material 2 主题的项目,并且使用了这种方法,在其中使用类名称并全局添加颜色类。

这就是我所做的:

文件名:mytheme-sidemenu.scss:

// Import all the tools needed to customize the theme and extract parts of it
@import "~@angular/material/theming";
// Define a mixin that accepts a theme and outputs the color styles for the component.
@mixin mytheme-sidemenu($theme) {
  // Extract whichever individual palettes you need from the theme.
  $primary: map-get($theme, primary);
  $accent: map-get(
    $theme,
    accent
  ); // Use mat-color to extract individual colors from a palette as necessary.

  .col-primary {
    color: mat-color($primary, 500) !important;
  }
  .col-accent {
    color: mat-color($accent, 300) !important;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的主主题文件:mytheme-theme.scss:

@import '~@angular/material/theming';
@import './variables/helper.scss';
@import './variables/spacemanager.scss';
@import './mytheme-sidemenu.scss';

// Primary theme
@include mat-core();
$mytheme-app-primary: mat-palette($mat-light-blue, 700, 600);
$mytheme-app-accent: mat-palette($mat-pink, A200, 900, A100);
$mytheme-app-warn: mat-palette($mat-deep-orange);
$mytheme-app-theme: mat-light-theme($mytheme-app-primary, $mytheme-app-accent, $mytheme-app-warn);
@include angular-material-theme($mytheme-app-theme);
// Secondary Theme
.mytheme-alt-theme {
    $mytheme-alt-primary: mat-palette($mat-blue-grey, 500);
    $mytheme-alt-accent: mat-palette($mat-pink, 500);
    $mytheme-alt-warn: mat-palette($mat-deep-orange);
    $mytheme-alt-theme: mat-light-theme($mytheme-alt-primary, $mytheme-alt-accent, $mytheme-alt-warn);
    @include angular-material-theme($mytheme-alt-theme);
}
// Using the $theme variable from the pre-built theme you can call the theming function
@include mytheme-sidemenu($mytheme-app-theme);
Run Code Online (Sandbox Code Playgroud)

并在 app.module.ts 中更新:

export class AppModule {
  constructor(
    @Inject(OverlayContainer) private overlayContainer: OverlayContainer
  ) {
    this.overlayContainer
      .getContainerElement()
      .classList.add("mytheme-alt-theme"); // this for double theme add to the root css class
  }
}
Run Code Online (Sandbox Code Playgroud)