簡體   English   中英

使用 CSS 變量創建角度材質主題

[英]Create angular material theme with CSS variables

我正在開發一個需要在運行時可以主題化的項目。 所以我創建了一個主題系統,將 SCSS 變量與 CSS 變量相結合。 這是它的樣子。

:root {
  --primary-color: 196;
}


// Primary
$primary-100: hsl(var(--primary-color), 90%, 98%);
$primary-400: hsl(var(--primary-color), 90%, 65%);
$primary-main: hsl(var(--primary-color), 90%, 50%);
$primary-700: hsl(var(--primary-color), 90%, 30%);
$primary-900: hsl(var(--primary-color), 90%, 10%);

雖然這對我的自定義組件非常有效,但我很難讓它與 Material design 主題系統一起工作。

我的想法是我將按照 Angular 材料文檔中的說明創建主題,而不是使用靜態顏色,我將使用我的 SCSS 變量。 這就是我的 theme.scss 文件的樣子。

@import '~@angular/material/theming';
@import 'var.scss';

@include mat-core();

$shop-primary: (
  50: $primary-100,
  100: $primary-100,
  200: $primary-200,
  300: $primary-300,
  400: $primary-400,
 // ..... all other colors
  contrast: (
    50: $black-87-opacity,
    100: $black-87-opacity,
    200: $black-87-opacity,
     // ..... all other colors
  )
);


$shop-app-primary: mat-palette($shop-primary);
$shop-app-accent:  mat-palette($shop-primary);
$shop-app-warn: mat-palette($shop-primary);


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

@include angular-material-theme($shop-app-theme);

我收到一個錯誤:

 Argument `$color` of `rgba($color, $alpha)` must be a color

推測是因為 Angular Material mixin 需要color而不是hsl()值。

所以我的問題是如何使用運行時 CSS 變量創建自定義材質主題?

我創建了一個小庫,使這更容易一些。

你可以像這樣使用它:

  1. 安裝:

     npm i angular-material-css-vars -S
  2. 然后刪除任何現有的@import '~@angular/material/theming'; 從您的主樣式表文件。

  3. 將此添加到您的主樣式表中:

     @import '~angular-material-css-vars/main'; @include initMaterialCssVars();
  4. 像這樣更改主題顏色:

     import {MaterialCssVarsService} from 'angular-material-css-vars'; export class SomeComponentOrService { constructor(public materialCssVarsService: MaterialCssVarsService) { const hex = '#3f51b5'; this.materialCssVarsService.changePrimaryColor(hex); } }

如果您升級到 @angular/material 7.3.4 CSS 變量將主要工作。 只有漣漪和其他使用不透明度的東西需要一些修復。 我的項目使用 rgba(),但它也適用於 hsla()

包括這個:

@function mat-color($palette, $hue: default, $opacity: null) {
    @if type-of($hue) == number and $hue >= 0 and $hue <= 1 {
        @return mat-color($palette, default, $hue);
    }

    $color: map-get($palette, $hue);

    @if (type-of($color) != color) {
        @if ($opacity == null){
            @return $color;
        }

        // Here is the change from the original function:
        // If the $color resolved to something different from a color, we assume it is a CSS variable
        // in the form of rgba(var(--rgba-css-var),a) and replace the 'a' value.
        @return #{str-slice($color, 0, str-index($color, ',')) + $opacity + ')'};
    }

    @return rgba($color, if($opacity == null, opacity($color), $opacity));
}

直接在:

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

並像這樣定義你的顏色:

--primary-color-50-parts: 0,158,224;
// ... all other colors

$color-primary: (
    50: rgba(var(--primary-color-50-parts), 1),
    // ... all other colors
);

如果您像這樣在地圖中定義顏色:

50: hsla(var(--primary-color), 90%, 98%, 1);

那么您需要將 sass 函數中的 str-index($color, ',') 更改為找到字符串中最后一個 ',' 的內容。 不幸的是,我的 sass 知識只涵蓋了最低限度,我不知道該怎么做:/

我創建了一個小庫 - material-theme-creator

您可以為 angular 應用程序設置主題或使用這種方法來創建主題

NPM: https : //www.npmjs.com/package/material-theme-creator

文檔: https : //artik-man.github.io/material-theme-creator/

npm i material-theme-creator

@import "~material-theme-creator/ngx-mtc";
@import '~@angular/material/theming';

@include mat-core();
@include ngx-mtc-init();

$primary-map: ngx-mtc-create-theme-map('primary');
$accent-map: ngx-mtc-create-theme-map('accent');
$warn-map: ngx-mtc-create-theme-map('warn');

:root {
  --is-dark-theme: 1; // Is dark theme? 1 or 0;
  @include ngx-mtc-theme-base(); // Creates base colors

  // Creates theme colors
  @include ngx-mtc-create-variables-from-color('primary', #009688, 38%);
  @include ngx-mtc-create-variables-from-color('accent', #2196f3, 57%);
  @include ngx-mtc-create-variables-from-color('warn', #f44336, 62%);
}

// Creates Angular Material Theme
@include angular-material-theme(
  ngx-mtc-custom-theme(
    mat-palette($primary-map),
    mat-palette($accent-map),
    mat-palette($warn-map)
  )
);
 

第二個主題代碼:

.second-theme {
  --is-dark-theme: 0;
  @include ngx-mtc-update-theme('primary', #142148, 45%);
  @include ngx-mtc-update-theme('accent', #658e14, 50%);
  @include ngx-mtc-update-theme('warn', #750101, 50%);
}

您可以將它與 Angular Material 或 SCSS 或純 CSS 一起使用

Sooo... css 變量是運行時,而不是編譯時。 SASS 不知道如何處理它們。 您應該能夠使用 SCSS 的 ${} 插值來重構您的 css 變量,並使一切仍然正常工作。 http://sass-lang.com/documentation/file.SASS_REFERENCE.html#interpolation_

$primary-color: 196;

:root {
  --primary-color: #{$primary-color};
}

$primary-100: hsl($primary-color, 90%, 98%);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM