在 Angular 中,组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。
通过在组件的元数据上设置视图封装模式,你可以分别控制每个组件的封装模式。 可选的封装模式一共有如下几种:
-
ShadowDom
模式使用浏览器原生的Shadow DOM
实现(参阅MDN
上的Shadow DOM
)来为组件的宿主元素附加一个Shadow DOM
。组件的视图被附加到这个Shadow DOM
中,组件的样式也被包含在这个Shadow DOM
中。(译注:不进不出,没有样式能进来,组件样式出不去。) -
Emulated
模式(默认值)通过预处理(并改名)CSS
代码来模拟Shadow DOM
的行为,以达到把CSS
样式局限在组件视图中的目的。 更多信息,见附录 1。(译注:只进不出,全局样式能进来,组件样式出不去) -
None
意味着Angular
不使用视图封装。Angular
会把CSS
添加到全局样式中。而不会应用上前面讨论过的那些作用域规则、隔离和保护等。 从本质上来说,这跟把组件的样式直接放进HTML
是一样的。(译注:能进能出。)
通过组件元数据中的 encapsulation
属性来设置组件封装模式:
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.ShadowDom
ShadowDom
模式只适用于提供了原生 Shadow DOM
支持的浏览器。 它仍然受到很多限制,这就是为什么仿真 (Emulated
) 模式是默认选项,并建议将其用于大多数情况。
查看生成的 CSS
使用默认的仿真模式时,Angular
会对组件的所有样式进行预处理,让它们模仿出标准的 Shadow CSS
作用域规则。
在启用了仿真模式的 Angular
应用的 DOM
树中,每个 DOM
元素都被加上了一些额外的属性。
<hero-details _nghost-pmm-5>
<h2 _ngcontent-pmm-5>Mister Fantastic</h2>
<hero-team _ngcontent-pmm-5 _nghost-pmm-6>
<h3 _ngcontent-pmm-6>Team</h3>
</hero-team>
</hero-detail>
生成出的属性分为两种:
- 一个元素在原生封装方式下可能是
Shadow DOM
的宿主,在这里被自动添加上一个_nghost
属性。 这是组件宿主元素的典型情况。 - 组件视图中的每一个元素,都有一个
_ngcontent
属性,它会标记出该元素属于哪个宿主的模拟Shadow DOM
。
属性的具体值并不重要。它们是自动生成的,并且你永远不会在程序代码中直接引用到它们。 但它们会作为生成的组件样式的目标,就像 DOM
的 <head>
中一样:
[_nghost-pmm-5] {
display: block;
border: 1px solid black;
}
h3[_ngcontent-pmm-6] {
background-color: white;
border: 1px solid #777;
}
这些就是那些样式被处理后的结果,每个选择器都被增加了 _nghost
或 _ngcontent
属性选择器。 这些额外的选择器实现了本文所描述的这些作用域规则。