Angular - 组件样式



Angular 组件可以使用 CSS 以及流行的预处理器(如 Sass 和 Less)进行样式设置。本章将介绍为 Angular 组件应用样式的不同技术,以及组件用户安全有效地自定义样式的不同方法。

在组件视图中应用样式

styles

styles 属性是为组件设置样式最简单、最快捷的方法。styles 是 @Component 装饰器的属性,它接受 CSS 样式数组并将其应用于组件视图。使用组件中的 styles 的伪代码如下:

@Component({
   // selector and template code
   
   styles: ['p { font-style: italic; }', 'em { font-style: italic;
   font-weight: bold }']
   
   // other properties / meta data
})
export class MyComponent {
   // ...
}

限制

使用 styles 应用的样式将仅影响通过组件模板生成的组件视图,不会继承到组件模板中嵌套组件的视图,也不会继承到组件视图中投影的任何内容。

styleUrls

styleUrls 是 @Component 装饰器的属性,类似于 styles 属性。它接受 CSS 样式文件路径数组而不是样式本身,并将其应用于组件视图。使用组件中 styleUrls 的伪代码如下:

@Component({
   // selector and template code
   
   styleUrls: ['my-component.component.css', 'my-component-another.component.css']
   
   // other properties / meta data
})
export class MyComponent {
   // ...
}

限制

使用 styleUrls 应用的样式将仅影响通过组件模板生成的组件视图,不会继承到组件模板中嵌套组件的视图,也不会继承到组件视图中投影的任何内容。

通过模板设置样式

通过模板设置样式是使用 HTML 中的 CSS 样式的传统方法,通过 @Component 装饰器的 template 属性实现。它有两种选择。

  • 使用 html style 标签内联样式
  • 通过 link 标签链接 CSS 文件

通过模板设置样式不会将样式限制在组件视图中,而是应用于从组件生成的整个 HTML,包括嵌套组件和投影。

使用 style 标签应用样式

使用 style 标签应用样式的伪代码如下:

@Component({
   // selector
   
   template: `
      <style>
         h1 {
               color: red;
         }
      </style>
      <h1>Hello</h1>
   `,
   
   // other properties / meta data
})
export class MyComponent {
   // ...
}

使用 link 标签应用样式

使用 link 标签应用样式的伪代码如下:

@Component({
   // selector
   
   template: `
      <link rel="stylesheet" href="../assets/my-component.component.css">
      <h1>Hello</h1>
   `,
   
   // other properties / meta data
})
export class MyComponent {
   // ...
}

CSS 文件路径应相对于组件文件。否则,生成的 HTML 中的 CSS 路径可能指向错误的文件或不存在的文件。

@import 可用于 CSS 文件中加载更多 CSS 文件,导入文件应相对于主机 CSS 文件。

@import './another-css.css'

通过全局样式

全局样式将在应用程序创建期间配置。Angular CLI 将 src/styles.css 文件设置为全局样式表。我们可以用它来设置针对应用程序中任何内容的样式。我们可以根据需要使用全局设置来设置一个或多个样式表。以下代码片段显示了通过 Angular CLI 在应用程序创建期间创建的初始 Angular 配置。

{
   "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
   "version": 1,
   "newProjectRoot": "projects",
   "projects": {
      "tutorial": {
         // ...
         "architect": {
            "build": {
               "builder": "@angular-devkit/build-angular:browser",
               "options": {
                  "outputPath": "dist/tutorial",
                  "index": "src/index.html",
                  "main": "src/main.ts",
                  "polyfills": [
                     "zone.js"
                  ],
                  "tsConfig": "tsconfig.app.json",
                  "assets": [
                     "src/favicon.ico",
                     "src/assets"
                  ],
                  "styles": [
                     "src/styles.css"
                  ],
                  "scripts": []
               },
               "configurations": {
                  "production": {
                     // ...
                  },
                  "development": {
                     // ...
                  }
               },
               "defaultConfiguration": "production"
            },
         }
      }
   }
}

使用 CSS 预处理器

Angular 不仅允许使用纯 CSS 来设置组件的样式,还允许使用流行的 CSS 预处理器,如 Sass 和 Less。使用 Sass 和 Less 就像包含 Sass 和 Less 文件一样简单,而不是 CSS 文件。

组件 styleUrls 可以用来包含 Sass 和 Less,如下所示。

@Component({
   // selector and template code
   
   styleUrls: ['my-component.component.scss']
   
   // other properties / meta data
})
export class MyComponent {
   // ...
}

CSS 预处理器可以在项目级别或通过 Angular 设置在组件级别配置。Angular CLI ng new 将在初始项目创建期间询问预处理器设置。

$ ng new myapp
? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? (Use arrow keys)
❯ CSS
  SCSS   [ https://sass-lang.com.cn/documentation/syntax#scss                ]
  Sass   [ https://sass-lang.com.cn/documentation/syntax#the-indented-syntax ]
  Less   [ https://lesscss.org.cn  

Angular CLI 将使用正确的 CSS 预处理器配置项目。

提供组件样式自定义

通常,每个 Angular 组件都与其关联的默认样式。由于组件可以在各种场景中使用,因此有必要自定义组件的样式以匹配给定的场景。一个好的组件应该有一种清晰的方法来更改样式以适应使用组件的环境。Angular 提供了四种自定义组件样式的方法。

  • CSS 自定义属性
  • 全局 CSS 以及 @mixins
  • 使用 shadow DOM 的伪选择器
  • 使用组件属性/API

CSS 自定义属性

CSS 提供 CSS 变量来保存样式。定义 CSS 变量后,它可以在任何 CSS 属性中使用,并允许通过更改 CSS 变量的值来更改应用程序中的某些样式。

让我们看看如何定义和使用 CSS 变量。CSS 变量可以使用 :root 伪选择器创建,如下所示:

:root {
   --myColor: red;
}

这里,定义了 myColor 变量,其初始值为红色。myColor 变量可以在另一个 CSS 属性中使用,如下所示:

p {
   color: var(--myColor, grey);
}

这里,颜色将设置为 myColor 的值(在本例中为红色)。如果 myColor 没有值或未定义,则将灰色设置为颜色。

可以通过使用组件属性和 CSS 变量在组件中应用相同的概念,如下所示。

  • 在组件中声明 CSS 变量myColorVar 的属性,如下所示:

@Component({ 
   // setting
})
export class MyComponent {
   myColorVar: string = null;
}
  • 在样式(模板)中使用 CSS 变量 myColor 和组件属性 myColorVar,如下所示:

<p [style.--myColor]="myColorVar">Hello</p>
  • 现在,可以通过更改 :root 伪选择器中的 CSS 变量来自定义组件,如下所示:

:root {
   --myColor: green;
}

全局 CSS 和 @mixins

CSS 预处理器提供了一个很好的选项,可以使用 mixin 概念根据需要混合 CSS 中的不同样式。Mixin 只是将一个或多个 CSS 样式组合在一起并命名,然后在需要的地方使用定义的名称。让我们定义两个 mixin,一个用于颜色,另一个用于字体样式。

@mixin color($c) {
   color: $c;
}

@mixin fontstyle($fs) {
   font-style: $fs;
}

接下来,我们可以使用 mixin 使用 @include 选项定义全局样式,如下所示:

.mystyle {
   @include color('red');
   @include fontstyle('italic');
}

最后,用户可以在全局样式中自定义颜色和字体样式,而不会干扰组件。

shadow DOM 的伪选择器

使用 shadow DOM 的组件可以使用 part 属性设置,允许用户使用 CSS 样式中的 ::part 伪选择器自定义样式,如下所示:

<template id="my-web-component">
   <h1 part="hello">Hello</h1>
</tempalte>

这里,my-web-component web 组件为 h1 标签设置了 part 属性。

my-web-component::part(hello) {
   // custom css styles
}

这里,h1 标签通过 ::part 选择器进行定位,可以进行自定义。

组件属性

自定义组件样式的最后一种也是最不推荐的方法是通过自定义组件属性,如下所示:

@Component({
   // ...
})
export class MyComponent() {
   color: string;
}

这里,组件将使用属性从用户那里获取颜色信息并将其设置在模板中。

自定义选择器

Angular 提供了两个类似于 shadow DOM 概念的自定义选择器。

  • :host
  • :host-context

:host 选择器用于设置组件的主元素的样式。它有两种形式。第一种是简单的形式,如下所示:

这里,:host 选择器应用于主机元素及其所有后代元素。

第二种是函数形式,只有当主机元素包含包含的选择器(作为参数)时,才会定位主机元素,如下所示:

:host(.active) {
   font-weight: bold;
}

这里,:host(.active) 仅当主机元素具有 active 类时才定位主机元素。

最后,:host-context 选择器类似于 :host() 函数形式,不同之处在于它检查宿主元素的任何祖先元素是否具有指定的(参数中的)选择器。

:host(.active) {
   font-weight: bold;
}

此处,只有当宿主元素的任何祖先元素都分配了 .active 类时,样式才应用于宿主元素。

广告