角度材质 - 全局颜色变量

时间:2018-04-04 03:08:13

标签: css angular sass angular-material2

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

从我的角度来看,这种方法的一些缺点是:

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

鉴于一致的设计语言,将只使用一部分颜色(例如主要调色板中的4种颜色,重点调色板中的3种颜色,前景/背景颜色中的一些颜色等)。

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

e.g。也许是这样的:

  $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

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

只是想验证上述情况是否合理,并且我没有遗漏任何明显会导致痛苦的事情?

另一个棘手的部分是如何在一个单独的colors文件中实际定义这些文件,因为文件需要访问主题数据。

3 个答案:

答案 0 :(得分:4)

为什么使用@mixin

  

只是想验证上述内容是否正确,并且我没有错过任何明显会导致痛苦的东西?

我能想到的唯一一件事是,您将错过在一个应用程序中使用多个主题的机会。使用Angular Material documentation的方法,您将为每个组件拥有一个@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);
}

如果您将颜色作为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));

要将_variables.scss导入组件内,我必须add stylePreprocessorOptions to the angular.json file

"styles": [
  "src/styles.scss",
  "src/theme.scss"
],
"stylePreprocessorOptions": {
  "includePaths": [
    "src/styles"
  ]
},

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

@import 'variables';

.custom-class-a {
  background-color: map-get($custom-colors, custom-color-a);
  color: map-get($custom-colors, custom-color-b);
}

为什么要使用sass-mapmap-merge

您注意到,我在sass-map $custom-colors中收集了我的自定义颜色,并将它们合并到我的$theme变量中。这样,我可以通过将自定义颜色直接导入到我的组件样式表中来使用自定义颜色(如上所述),或者可以在组件@mixin中使用它们,就像在角材料文档。

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

@mixin custom-component-theme($theme) {
  $custom-colors: map-get($theme, custom-colors);

  .custom-class-a {
    background-color: map-get($custom-colors, custom-color-a);
    color: map-get($custom-colors, custom-color-b);
  }
}

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

答案 1 :(得分:1)

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

这就是我所做的:

FileName: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;
  }
}

这是我的主题文件: 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);

并在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
  }
}

答案 2 :(得分:0)

我已经在 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};
}

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

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

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

.yet-another-class {
    border-color: var(--accent)
}

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