为其他元素获取Material 2主题配色方案/调色板

Cac*_*oon 15 css themes angular-material angular

我正在构建一个应用程序,但我想保持一致的颜色方案,可以通过设置更改,所以我使用材料(2)与角度(2 +),但我不知道如何获得不直接的元素的配色方案提供了为它们着色的能力,color="primary"因此我试图弄清楚如何获得我的Material 2主题使用的颜色/颜色方案.我希望它在主题发生变化时进行更改,例如我的导航栏将适应主题更改,因为它设置为

<mat-toolbar color="primary" class="fixed-navbar mat-elevation-z10">
Run Code Online (Sandbox Code Playgroud)

但是材质2中的网格元素并没有采用相同的参数,所以我试图用足够接近的颜色来设置它的样式,或者根本不匹配它(并且它不会适应主题变化),如下所示:

在此输入图像描述

我希望它与主题垫匹配颜色,这是在这里(并在导航栏设置中选择的选项上更改)

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

@include mat-core();



$candy-app-primary: mat-palette($mat-red);
$candy-app-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$candy-app-warn:    mat-palette($mat-red);
$candy-app-theme: mat-dark-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

// 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.
.default {
  @include angular-material-theme($candy-app-theme);
}
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include angular-material-theme($light-theme);
}
@include angular-material-theme($candy-app-theme);
Run Code Online (Sandbox Code Playgroud)

Cac*_*oon 28

我找到了一个很棒的解决方法!!!! 我很高兴能够证明这一点,因为它一直困扰着我如何实现这一目标.所以这里; 首先,将所有css文件更改为scss;

对于现有项目

  • 在控制台中运行 ng set defaults.styleExt=scss

  • 将所有现有.css文件重命名为.scss

  • 手动更改的文件扩展styles.angular-cli.json从到的CSS.scss
  • 如果你没有使用像WebStorm重构一个工具来重命名,然后手动所有的改变styleUrls来自.css.scss

对于未来的项目

  • 只为您的新项目使用 ng new your-project-name --style=scss

  • 对于所有使用scss的新项目 ng set defaults.styleExt=scss --global

现在你需要在app根目录中有一个theme.scss文件,如下所示: 主题在哪里

现在在你的style.scss文件中你想要添加以下内容(你可以看到我引用背景颜色,但是你可以将它更改为任何元素来主题你的网站,但你想要):

编辑:你不需要把这个自定义的@mixin元素放在你的styles.scss任何一个你可以把它放在你的任何一个*name*.component.scss然后简单导入和包含它与你给出的例子相同的方式!

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

// Define a custom mixin that takes in the current theme
@mixin theme-color-grabber($theme) {
  // Parse the theme and create variables for each color in the pallete
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);
  // Create theme specfic styles
  .primaryColorBG {
    background-color: mat-color($primary);
  }
  .accentColorBG {
    background-color: mat-color($accent);
  }
  .warnColorBG {
    background-color: mat-color($warn);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在转到你用来主题你的Material 2项目的theme.scss文件,如果你需要帮助主题检查一下:Material 2 Github - 主题指南

现在打开你的theme.scss并导入你的style.scss,因为我的theme.scss位于/src/app/theme.scss文件夹的根目录中,我必须先用它来引用我的/src/styles.scss全局样式文件,就像这样;

@import '../styles';
Run Code Online (Sandbox Code Playgroud)

然后我们必须实际包含我们@mixin所有主题中创建的新自定义(如果您有多个像我一样,那么它会根据当前选定的主题更改颜色).

将它包含在实际的角度材质主题包括上面,如下所示:

@include theme-color-grabber($theme);
@include angular-material-theme($theme);
Run Code Online (Sandbox Code Playgroud)

如果您有像我这样的主题,请将其添加到相同位置,如下所示:

.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}
Run Code Online (Sandbox Code Playgroud)

你可以看到我添加了我的theme-color-grabber上面的包含,如果它在实际主题的上方或下方并不重要,因为它获得主题颜色这是主要观点.

我的整个themes.scss看起来像这样:

@import '~@angular/material/theming';
//We import our custom scss component here
@import '../styles';

@include mat-core();

$theme-primary: mat-palette($mat-red);
$theme-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$theme-warn:    mat-palette($mat-red);
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn);
//
@include theme-color-grabber($theme);
@include angular-material-theme($theme);
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}
Run Code Online (Sandbox Code Playgroud)

最后我们现在可以在任何地方调用我们的主题颜色作为背景!例如,我给出一个mat-grid-tile'主要'颜色(它不像color-''参数,像其他元素,如mat-toolbar)简单地将其类设置为适当的类名,如下所示:

编辑:在每个组件scss文件中,您需要将import '<path-to>/theme.scss'主题应用于该组件.不要导入theme.scss,styles.scss因为这会创建一个导入循环!

<mat-grid-list cols="4" rows="4" rowHeight="100px">
  <mat-grid-tile
    colspan="4"
    rowspan="5"
  class="primaryColorBG">
    <div fxLayout="column" fxLayoutAlign="center center">
      <h1 class="title-font">Callum</h1>
      <h1 class="title-font">Tech</h1>
    </div>
    <p>
      Ambitious and ready to take on the world of Information Technology,<br>
      my love for programming and all things I.T. has not wavered since I first got access<br>
      to my fathers computer at age 9.
    </p>
  </mat-grid-tile>

</mat-grid-list>
Run Code Online (Sandbox Code Playgroud)

最后我们的结果会是这样的!:

红色主题活跃 红色主题

蓝色主题活跃 在此输入图像描述

  • 厉害了,有可能! (3认同)
  • :3是的,我很高兴,它真的把我推到了墙上,但现在我可以让我所有的东西都工作了; D (2认同)

Ced*_*Ced 8

我个人将它们放在css4变量中,这样我就可以像这样使用没有导入的变量

background: var(--color-primary)

这是如何设置css4变量

@import '~@angular/material/theming';
// 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. Available color palettes: https://material.io/design/color/
$app-primary: mat-palette($mat-blue);
$app-accent:  mat-palette($mat-orange);
$app-warn:    mat-palette($mat-red);
$app-success: mat-palette($mat-light-green);

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

// 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($app-theme);

$primary: map-get($app-theme, primary);
$accent: map-get($app-theme, accent);

:root {
  --color-primary: #{mat-color($app-primary)};
  --color-accent: #{mat-color($app-accent)};
  --color-warn: #{mat-color($app-warn)};
  --color-success: #{mat-color($app-success)};
}
Run Code Online (Sandbox Code Playgroud)

现在颜色可以在css文件中使用而无需导入

background: var(--color-primary)
Run Code Online (Sandbox Code Playgroud)


Mir*_*ili 5

更新:

该解决方案的新版本已发布于此处:

https://github.com/mirismaili/angular-material-dynamic-themes

如果您只需要所问问题的答案,可能最好参考下面答案的第一个版本。另外,我建议阅读上述存储库文档的这一部分:对其他元素使用材质主题

但如果您想要在下面的视频中看到其他功能,我推荐这种新方法。

视频

评分此翻译: 感谢你的评分 不好好


存档的答案:

在此输入图像描述

堆栈闪电战在这里


最重要的部分:

在你的styles.scss(或者themes.scss如果你有的话):

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

@include mat-core();

@mixin define-css-classes($theme) {
    @include angular-material-theme($theme);

    $primary: map-get($theme, primary);
    $accent: map-get($theme, accent);
    $warn: map-get($theme, warn);
    $background: map-get($theme, background);
    $foreground: map-get($theme, foreground);

    // CSS THEME-DEPENDENT-STYLES ARE HERE:
    .theme-dependent-colors {
        background: mat-color($primary);
        color: mat-color($accent);
    }
}

/**
* Define your custom themes in this map. 
* The `key` of each member is the name of CSS class for that theme. 
* To better understand the schema of the map, see `@each` loop below and especially pay attention to `map-has-key()` functions.
*/ 
$app-themes: (
        indigo-pink : (primary-base: $mat-indigo, accent-base: $mat-pink),
        deeppurple-amber: (primary-base: $mat-deep-purple, accent-base: $mat-amber),
        pink-bluegrey : (primary-base: $mat-pink, accent-base: $mat-blue-gray, is-dark: true),
        purple-green : (primary-base: $mat-purple, accent-base: $mat-green, is-dark: true),
);

@each $css-class, $theme in $app-themes {
    $primary: if(map-has-key($theme, primary), map-get($theme, primary), mat-palette(map-get($theme, primary-base)));

    $accent: if(map-has-key($theme, accent), map-get($theme, accent), mat-palette(map-get($theme, accent-base)));

    $warn: if(map-has-key($theme, warn), map-get($theme, warn), mat-palette(
            if(map-has-key($theme, warn-base), map-get($theme, warn-base), $mat-red)
    ));

    .#{$css-class} {
        @include define-css-classes(mat-light-theme($primary, $accent, $warn));
    }

    .#{$css-class}-dark {
        @include define-css-classes(mat-dark-theme($primary, $accent, $warn));
    }

    .theme-primary.#{$css-class} {
        background-color: mat-color($primary);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

动态主题更改,setTheme()在打字稿中使用(请参阅此处此处):

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

@include mat-core();

@mixin define-css-classes($theme) {
    @include angular-material-theme($theme);

    $primary: map-get($theme, primary);
    $accent: map-get($theme, accent);
    $warn: map-get($theme, warn);
    $background: map-get($theme, background);
    $foreground: map-get($theme, foreground);

    // CSS THEME-DEPENDENT-STYLES ARE HERE:
    .theme-dependent-colors {
        background: mat-color($primary);
        color: mat-color($accent);
    }
}

/**
* Define your custom themes in this map. 
* The `key` of each member is the name of CSS class for that theme. 
* To better understand the schema of the map, see `@each` loop below and especially pay attention to `map-has-key()` functions.
*/ 
$app-themes: (
        indigo-pink : (primary-base: $mat-indigo, accent-base: $mat-pink),
        deeppurple-amber: (primary-base: $mat-deep-purple, accent-base: $mat-amber),
        pink-bluegrey : (primary-base: $mat-pink, accent-base: $mat-blue-gray, is-dark: true),
        purple-green : (primary-base: $mat-purple, accent-base: $mat-green, is-dark: true),
);

@each $css-class, $theme in $app-themes {
    $primary: if(map-has-key($theme, primary), map-get($theme, primary), mat-palette(map-get($theme, primary-base)));

    $accent: if(map-has-key($theme, accent), map-get($theme, accent), mat-palette(map-get($theme, accent-base)));

    $warn: if(map-has-key($theme, warn), map-get($theme, warn), mat-palette(
            if(map-has-key($theme, warn-base), map-get($theme, warn-base), $mat-red)
    ));

    .#{$css-class} {
        @include define-css-classes(mat-light-theme($primary, $accent, $warn));
    }

    .#{$css-class}-dark {
        @include define-css-classes(mat-dark-theme($primary, $accent, $warn));
    }

    .theme-primary.#{$css-class} {
        background-color: mat-color($primary);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

请参阅stackblitz中的其他内容。


styles.css注意:在我的案例中,向应用程序添加 8 个动态材质主题(4 个亮色 + 4 个暗色)增加了 build by的大小~420 kB(与一个静态材质主题相比)。

  • 我不得不再次问:您真的必须经历所有这些才能在自定义 html 标记中使用您的材质主题颜色吗?只有一些“特殊”材质组件提供了“color=”参数,可让您将其颜色设置为主题中的值(主色、强调色等)?谢谢 (2认同)
  • “再次”的意思是“虽然讨论似乎已经结束了,但我想补充一个问题,我相信除了我之外,每个人都可以轻松回答”。@Mir-Ismaili:感谢您的链接。因此,仅仅为了能够使用主题颜色就需要花费很多麻烦。这对我来说太疯狂和奇怪了。如此复杂的框架,然后你必须做 30 年前那样的事情;-) 顺便说一句:问题不在于你要做的事情太难了。如果事情出乎意料地复杂,你就会认为自己做错了。我简直不敢相信。 (2认同)