您可以将 Angular 主题原色应用于 div 吗?
Can you apply an Angular themes primary color to a div?
有没有办法为 Angular 7 应用程序设置主题,以便您可以:
- 也将主题应用于普通 HTML 元素,而不仅仅是 Angular Material 组件
- 运行时切换主题
- 不必为每种颜色和每种用法使用 class(
color
、background-color
、border-color
、...),例如在其他一些问题和解决方案中。
例如
我想做这样的事情:
<div color="primary">
</div>
但这不起作用,因为 color
属性仅适用于 angular material 个组件。
此外,我希望能够根据当前主题更改背景颜色、文本颜色等。 (深色主题、浅色主题)
关于解决方案
使用此解决方案,您可以:
- 运行时切换主题
- 运行时获取当前主题
- 主题直接在 CSS 中而不使用额外的 classes 或任何东西
- 有一个易于使用且易于理解的解决方案,只需要一次性设置
缺点:
- 使用 CSS 个变量。一些较旧的浏览器可能不支持它们
- 依赖更新的 Angular 版本。我不知道这是否适用于旧版本(在 Angular 6 和 7 中测试)
这是我现在在我的项目中使用的:
设置
首先你需要定义一个主题。
这是一个名为 dark-theme.scss
的示例,位于 src/themes
:
@import '~@angular/material/theming';
@include mat-core();
// Set variables to whatever colors you want for your app
$dark-theme-primary: mat-palette($mat-pink);
$dark-theme-accent: mat-palette($mat-light-blue);
$dark-theme-warn: mat-palette($mat-red);
$dark-theme: mat-dark-theme(
$dark-theme-primary,
$dark-theme-accent,
$dark-theme-warn
);
@include angular-material-theme($dark-theme);
那么你需要一个可以创建主题SCSS和CSS变量的SCSS函数:
这是我的 functions.scss
在 src/assets/scss
:
@mixin generate-theme-vars($theme) {
//default palette foreground/background:
$foreground-palette: map-get($theme, foreground);
$background-palette: map-get($theme, background);
/////////////////////////////////////////////////
// SCSS VARS
/////////////////////////////////////////////////
$primary: mat-color(map-get($theme, primary));
$accent: mat-color(map-get($theme, accent));
$warn: mat-color(map-get($theme, warn));
$base: mat-color($foreground-palette, base);
$divider: mat-color($foreground-palette, divider);
$dividers: mat-color($foreground-palette, dividers);
$disabled: mat-color($foreground-palette, disabled);
$disabled-button: mat-color($foreground-palette, disabled-button);
$disabled-text: mat-color($foreground-palette, disabled-text);
$hint-text: mat-color($foreground-palette, hint-text);
$secondary-text: mat-color($foreground-palette, secondary-text);
$icon: mat-color($foreground-palette, icon);
$icons: mat-color($foreground-palette, icons);
$text: mat-color($foreground-palette, text);
$slider-off: mat-color($foreground-palette, slider-off);
$slider-off-active: mat-color($foreground-palette, slider-off-active);
$status-bar: mat-color($background-palette, status-bar);
$app-bar: mat-color($background-palette, app-bar);
$background: mat-color($background-palette, background);
$hover: mat-color($background-palette, hover);
$card: mat-color($background-palette, card);
$dialog: mat-color($background-palette, dialog);
$disabled-button: mat-color($background-palette, disabled-button);
$raised-button: mat-color($background-palette, raised-button);
$focused-button: mat-color($background-palette, focused-button);
$selected-button: mat-color($background-palette, selected-button);
$selected-disabled-button: mat-color($background-palette, selected-disabled-button);
$disabled-button-toggle: mat-color($background-palette, disabled-button-toggle);
/////////////////////////////////////////////////
// CSS VARS
/////////////////////////////////////////////////
--primary-color: #{$primary};
--accent-color: #{$accent};
--warn-color: #{$warn};
--base-color: #{$base};
--divider-color: #{$divider};
--dividers-color: #{$dividers};
--disabled-color: #{$disabled};
--disabled-text-color: #{$disabled-text};
--hint-text-color: #{$hint-text};
--secondary-text-color: #{$secondary-text};
--icon-color: #{$icon};
--icons-color: #{$icons};
--text-color: #{$text};
--slider-off-color: #{$slider-off};
--slider-off-active-color: #{$slider-off-active};
--status-bar-color: #{$status-bar};
--app-bar-color: #{$app-bar};
--background-color: #{$background};
--hover-color: #{$hover};
--card-color: #{$card};
--dialog-color: #{$dialog};
--disabled-button-color: #{$disabled-button};
--raised-button-color: #{$raised-button};
--focused-button-color: #{$focused-button};
--selected-button-color: #{$selected-button};
--selected-disabled-button-color: #{$selected-disabled-button};
--disabled-button-toggle-color: #{$disabled-button-toggle};
}
之后,一切就绪,您只需为全局 styles.scss
:
中的每个主题创建一个 class
@import "functions";
@import "~@angular/material/theming";
// You have to define one of those for every theme you offer
.dark-theme {
@import "themes/dark-theme";
@include angular-material-theme($dark-theme);
@include generate-theme-vars($dark-theme);
}
.light-theme {
@import "themes/light-theme";
@include angular-material-theme($light-theme);
@include generate-theme-vars($light-theme);
}
用法
要应用您要使用的主题,您需要将 CSS class dark-theme
(或任何您称呼它的东西)放在一个包含所有其他元素的元素中。
我把它放到HTML标签:
<!doctype html>
<html lang="en" class="dark-theme">
<!-- ... -->
</html>
现在您可以在运行时切换主题,例如将 class 和 JavaScript 更改为 light-theme
。
在每一个 CSS 属性 想要颜色的地方,你现在可以使用变量:
div {
width: 300px;
height: 300px;
background-color: var(--app-bar-color);
.someText {
color: var(--text-color);
}
}
如果你想在你的 CSS 中做一些事情,如果应用了一个特殊的主题并且改变的不是颜色本身,那么这样做:
// Example: We want to remove some div only when the light-theme is used
div {
width: 300px;
height: 300px;
background-color: var(--app-bar-color);
:host-context(.light-theme) & {
display: none;
}
}
PS
对于可能想知道为什么我使用 @import "functions";
的每个人,即使它们位于不同的文件夹中:
进入 angular.json
并向对象 projects > <YourProject> > architect > build > options
添加以下内容:
"stylePreprocessorOptions": {
"includePaths": [
"src/assets/scss"
]
},
现在您可以从每个路径使用 @import "functions";
。
如果您需要支持 IE(未经测试,可能需要改进)
因此,如果您不能在某些客户端上使用 CSS 变量,您可以像这样为指定的颜色定义回退:
div {
background-color: red; // fallback to red if the variable doesnt exist -> Old browsers, or IE
background-color: var(--app-bar-color);
}
有了这些知识,您可以在 styles.scss
:
中定义一些 SCSS 变量
@import "functions";
@import "~@angular/material/theming";
// Default theme
@import "themes/dark-theme";
@include angular-material-theme($dark-theme);
// Generate SCSS vars
$foreground-palette: map-get($theme, foreground);
$background-palette: map-get($theme, background);
/////////////////////////////////////////////////
// SCSS VARS
/////////////////////////////////////////////////
$primary: mat-color(map-get($theme, primary));
$accent: mat-color(map-get($theme, accent));
$warn: mat-color(map-get($theme, warn));
// ... and all the other vars from above if you would like
// You have to define one of those for every theme you offer
.dark-theme {
// Only init the CSS vars here, because the rest is in default
@include generate-theme-vars($dark-theme);
}
.light-theme {
@import "themes/light-theme";
@include angular-material-theme($light-theme);
@include generate-theme-vars($light-theme);
}
现在你可以像这样使用它了:
div {
background-color: $primary; // fallback
background-color: var(--primary-color);
}
This cant be changed dynamically with JS during the runtime anymore
though!!
对于可能出现错误的人 - SassError: Undefined variable.
,如果您尝试使用 @mixin generate-theme-vars($theme)
下定义的任何变量,则需要在这些变量中添加 !global
.例如定义:
$base: mat-color($foreground-palette, base) !global;
这将使变量成为全局变量,您可以在任何地方使用它。
有没有办法为 Angular 7 应用程序设置主题,以便您可以:
- 也将主题应用于普通 HTML 元素,而不仅仅是 Angular Material 组件
- 运行时切换主题
- 不必为每种颜色和每种用法使用 class(
color
、background-color
、border-color
、...),例如在其他一些问题和解决方案中。
例如
我想做这样的事情:
<div color="primary">
</div>
但这不起作用,因为 color
属性仅适用于 angular material 个组件。
此外,我希望能够根据当前主题更改背景颜色、文本颜色等。 (深色主题、浅色主题)
关于解决方案
使用此解决方案,您可以:
- 运行时切换主题
- 运行时获取当前主题
- 主题直接在 CSS 中而不使用额外的 classes 或任何东西
- 有一个易于使用且易于理解的解决方案,只需要一次性设置
缺点:
- 使用 CSS 个变量。一些较旧的浏览器可能不支持它们
- 依赖更新的 Angular 版本。我不知道这是否适用于旧版本(在 Angular 6 和 7 中测试)
这是我现在在我的项目中使用的:
设置
首先你需要定义一个主题。
这是一个名为 dark-theme.scss
的示例,位于 src/themes
:
@import '~@angular/material/theming';
@include mat-core();
// Set variables to whatever colors you want for your app
$dark-theme-primary: mat-palette($mat-pink);
$dark-theme-accent: mat-palette($mat-light-blue);
$dark-theme-warn: mat-palette($mat-red);
$dark-theme: mat-dark-theme(
$dark-theme-primary,
$dark-theme-accent,
$dark-theme-warn
);
@include angular-material-theme($dark-theme);
那么你需要一个可以创建主题SCSS和CSS变量的SCSS函数:
这是我的 functions.scss
在 src/assets/scss
:
@mixin generate-theme-vars($theme) {
//default palette foreground/background:
$foreground-palette: map-get($theme, foreground);
$background-palette: map-get($theme, background);
/////////////////////////////////////////////////
// SCSS VARS
/////////////////////////////////////////////////
$primary: mat-color(map-get($theme, primary));
$accent: mat-color(map-get($theme, accent));
$warn: mat-color(map-get($theme, warn));
$base: mat-color($foreground-palette, base);
$divider: mat-color($foreground-palette, divider);
$dividers: mat-color($foreground-palette, dividers);
$disabled: mat-color($foreground-palette, disabled);
$disabled-button: mat-color($foreground-palette, disabled-button);
$disabled-text: mat-color($foreground-palette, disabled-text);
$hint-text: mat-color($foreground-palette, hint-text);
$secondary-text: mat-color($foreground-palette, secondary-text);
$icon: mat-color($foreground-palette, icon);
$icons: mat-color($foreground-palette, icons);
$text: mat-color($foreground-palette, text);
$slider-off: mat-color($foreground-palette, slider-off);
$slider-off-active: mat-color($foreground-palette, slider-off-active);
$status-bar: mat-color($background-palette, status-bar);
$app-bar: mat-color($background-palette, app-bar);
$background: mat-color($background-palette, background);
$hover: mat-color($background-palette, hover);
$card: mat-color($background-palette, card);
$dialog: mat-color($background-palette, dialog);
$disabled-button: mat-color($background-palette, disabled-button);
$raised-button: mat-color($background-palette, raised-button);
$focused-button: mat-color($background-palette, focused-button);
$selected-button: mat-color($background-palette, selected-button);
$selected-disabled-button: mat-color($background-palette, selected-disabled-button);
$disabled-button-toggle: mat-color($background-palette, disabled-button-toggle);
/////////////////////////////////////////////////
// CSS VARS
/////////////////////////////////////////////////
--primary-color: #{$primary};
--accent-color: #{$accent};
--warn-color: #{$warn};
--base-color: #{$base};
--divider-color: #{$divider};
--dividers-color: #{$dividers};
--disabled-color: #{$disabled};
--disabled-text-color: #{$disabled-text};
--hint-text-color: #{$hint-text};
--secondary-text-color: #{$secondary-text};
--icon-color: #{$icon};
--icons-color: #{$icons};
--text-color: #{$text};
--slider-off-color: #{$slider-off};
--slider-off-active-color: #{$slider-off-active};
--status-bar-color: #{$status-bar};
--app-bar-color: #{$app-bar};
--background-color: #{$background};
--hover-color: #{$hover};
--card-color: #{$card};
--dialog-color: #{$dialog};
--disabled-button-color: #{$disabled-button};
--raised-button-color: #{$raised-button};
--focused-button-color: #{$focused-button};
--selected-button-color: #{$selected-button};
--selected-disabled-button-color: #{$selected-disabled-button};
--disabled-button-toggle-color: #{$disabled-button-toggle};
}
之后,一切就绪,您只需为全局 styles.scss
:
@import "functions";
@import "~@angular/material/theming";
// You have to define one of those for every theme you offer
.dark-theme {
@import "themes/dark-theme";
@include angular-material-theme($dark-theme);
@include generate-theme-vars($dark-theme);
}
.light-theme {
@import "themes/light-theme";
@include angular-material-theme($light-theme);
@include generate-theme-vars($light-theme);
}
用法
要应用您要使用的主题,您需要将 CSS class dark-theme
(或任何您称呼它的东西)放在一个包含所有其他元素的元素中。
我把它放到HTML标签:
<!doctype html>
<html lang="en" class="dark-theme">
<!-- ... -->
</html>
现在您可以在运行时切换主题,例如将 class 和 JavaScript 更改为 light-theme
。
在每一个 CSS 属性 想要颜色的地方,你现在可以使用变量:
div {
width: 300px;
height: 300px;
background-color: var(--app-bar-color);
.someText {
color: var(--text-color);
}
}
如果你想在你的 CSS 中做一些事情,如果应用了一个特殊的主题并且改变的不是颜色本身,那么这样做:
// Example: We want to remove some div only when the light-theme is used
div {
width: 300px;
height: 300px;
background-color: var(--app-bar-color);
:host-context(.light-theme) & {
display: none;
}
}
PS
对于可能想知道为什么我使用 @import "functions";
的每个人,即使它们位于不同的文件夹中:
进入 angular.json
并向对象 projects > <YourProject> > architect > build > options
添加以下内容:
"stylePreprocessorOptions": {
"includePaths": [
"src/assets/scss"
]
},
现在您可以从每个路径使用 @import "functions";
。
如果您需要支持 IE(未经测试,可能需要改进)
因此,如果您不能在某些客户端上使用 CSS 变量,您可以像这样为指定的颜色定义回退:
div {
background-color: red; // fallback to red if the variable doesnt exist -> Old browsers, or IE
background-color: var(--app-bar-color);
}
有了这些知识,您可以在 styles.scss
:
@import "functions";
@import "~@angular/material/theming";
// Default theme
@import "themes/dark-theme";
@include angular-material-theme($dark-theme);
// Generate SCSS vars
$foreground-palette: map-get($theme, foreground);
$background-palette: map-get($theme, background);
/////////////////////////////////////////////////
// SCSS VARS
/////////////////////////////////////////////////
$primary: mat-color(map-get($theme, primary));
$accent: mat-color(map-get($theme, accent));
$warn: mat-color(map-get($theme, warn));
// ... and all the other vars from above if you would like
// You have to define one of those for every theme you offer
.dark-theme {
// Only init the CSS vars here, because the rest is in default
@include generate-theme-vars($dark-theme);
}
.light-theme {
@import "themes/light-theme";
@include angular-material-theme($light-theme);
@include generate-theme-vars($light-theme);
}
现在你可以像这样使用它了:
div {
background-color: $primary; // fallback
background-color: var(--primary-color);
}
This cant be changed dynamically with JS during the runtime anymore though!!
对于可能出现错误的人 - SassError: Undefined variable.
,如果您尝试使用 @mixin generate-theme-vars($theme)
下定义的任何变量,则需要在这些变量中添加 !global
.例如定义:
$base: mat-color($foreground-palette, base) !global;
这将使变量成为全局变量,您可以在任何地方使用它。