Angular 应用使用标准的 CSS 来设置样式。这意味着你可以把关于 CSS 的那些知识和技能直接用于 Angular 程序中,例如:样式表、选择器、规则以及媒体查询等。
另外,Angular 还能把组件样式捆绑在组件上,以实现比标准样式表更加模块化的设计,具体可查看官方文档中的介绍。
本文主要结合代码说明一下,Angular中的特殊选择器:host, ::ng-deep以及视图封装模式。
特殊的选择器
组件样式中有一些从影子(Shadow) DOM 样式范围领域(记录在W3C的CSS Scoping Module Level 1中) 引入的特殊选择器:
:host
使用:host 伪类选择器,用来选择组件宿主元素中的元素(相对于组件模板内部的元素)。
确切的来说,就是类似与<app-hero-search></app-hero-search>这样的自定义元素,这些自定义元素不是组件自身模板的一部分,而是父组件模板的一部分,所以我们需要:host来指定它,这也是在组件内部样式规则中选择宿主元素的唯一方式。
:host {
border: 1px solid #00f;
}
::ng-deep
在Angular中,对组件的样式规则进行了内部封装,即为组件定义的样式规则都只在组件内部才能生效,不进不出,所以组件样式通常只会作用于组件自身的 HTML 上。因此我们可以使用::ng-deep来强制一个样式对各级子组件的视图也生效。
子组件和父组件中都有h4标签,假设我们在父组件的css文件中写入
::ng-deep h4{
color: #00f;
}
可以看到不止父组件中的h4标签中的字体颜色改变了,子组件中的也改变了。
:host ::ng-deep
但是需要注意的是,在我们的项目中,不止写入上面样式代码相关的组件和其子组件样式改变了,其他的不相关的组件h4标签颜色也发生了改变。
那这样该怎么办呢,我们并不想改变全局的h4标签的字体颜色,那么只需要在::ng-deep前面加上:host就可以把当前样式限制在当前组件和其子组件内部了,我们来看一下
这时候其他组件就不会被影响到了。
视图封装模式
Angular中组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。
通过在组件的元数据上设置视图封装模式,你可以分别控制每个组件的封装模式。 可选的封装模式一共有如下几种:
- ShadowDom 模式使用浏览器原生的 Shadow DOM 实现(参见 MDN 上的 Shadow DOM)来为组件的宿主元素附加一个 Shadow DOM。组件的视图被附加到这个 Shadow DOM 中,组件的样式也被包含在这个 Shadow DOM 中。(译注:不进不出,没有样式能进来,组件样式出不去。)
- Native 视图包装模式使用浏览器原生 Shadow DOM 的一个废弃实现
- Emulated 模式(默认值)通过预处理(并改名)CSS 代码来模拟 Shadow DOM 的行为,以达到把 CSS 样式局限在组件视图中的目的。(注:只进不出,全局样式能进来,组件样式出不去)
-
None 意味着 Angular 不使用视图封装。 Angular 会把 CSS 添加到全局样式中。而不会应用上前面讨论过的那些作用域规则、隔离和保护等。 从本质上来说,这跟把组件的样式直接放进 HTML 是一样的。(注:能进能出。)
通过组件元数据中的 encapsulation 属性来设置组件封装模式:
我们举一个例子说明一下,其他的可以自己体验。
我们在元数据中设置了
encapsulation: ViewEncapsulation.None
也就是说,样式将不再模块化,这时候,设置样式
可以看到:
所有的h4标签都受到了影响,不再隔离作用域。