css 封装在 Angular

css encapsulation in Angular

我最近一直在探索 Angular 组件对 css 和 dom 的封装。

我使用 ng-cli 构建了一个快速项目并加载了一个组件。假设组件选择器是 'app-component'。这封装了与该组件有关的所有 dom 和 css。目前一切顺利。

我从以前的阅读中了解到,组件既不允许外部 CSS 渗入,也不允许内部 CSS 渗出(这更特定于 Web 组件)

现在,在 index.html 文件中,我包含了一个 bootstrap css 文件,只是为了观察 bootstrap css 中的样式是否渗透到组件中或没有,令我惊讶的是它确实如此。如果我的组件中有 bootstrap css,我可以使用所有 类。

为什么会这样?本质上,外部 css 正在渗透到组件中。我了解 Angular 中的视图封装概念,但这不适合。

听起来有点天真,但我可能漏掉了一点!

编辑

基本上我指的是这个:

https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom

这表示:

Scoped CSS:CSS 定义在影子 DOM 内。样式规则不会泄露,页面样式不会渗入。

阴影 DOM 在 Angular 中默认使用。默认情况下,它根据 ViewEncapsulation documentation.

通过 "surrogate ids" 进行模拟

Emulated

Emulate Native scoping of styles by adding an attribute containing surrogate id to the Host Element and pre-processing the style rules provided via ViewMetadata or ViewMetadata, and adding the new Host Element attribute to all selectors.

This is the default option.

要在支持的浏览器上启用 Shadow DOM,您必须使用 ViewEncapsulation.Native

Native

Use the native encapsulation mechanism of the renderer.

For the DOM this means using Shadow DOM and creating a ShadowRoot for Component's Host Element.

例如:

import { ..., ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'my-component',
    templateUrl: './my.component.html',
    styleUrls: ['./my.component.scss'],
    encapsulation: ViewEncapsulation.Native
})
export class AppComponent ...

在此 Working Plunker #1 中,您会注意到尽管全局样式已在 index.html(嵌入式)和 style.css 中实现,并且覆盖样式(具有更高的特异性)已在 parent 中实现,当启用 ViewEncapsulation.Native 时,这些不会渗入 child。

注意:我假设您没有使用 ViewEncapsulation.Native,因为原始问题中没有提到它。

特定的选择器(class 或 id)没有被带下(如预期的那样),尽管更多的 "general" 样式被带下。例如,应用于 bodyfont-family 将渗入 child(如果 child 没有覆盖它),正如我现在理解的那样,torazaburo 在他的 .

Working Plunker #2

Style rules don't leak out and page styles don't bleed in.

这个写的有点乱。它想说的是 父组件 (它称为 "pages")的 CSS 样式不会渗入。当然,普通的旧全局 CSS 规则 "bleed in"。很难阻止他们这样做,因为他们不在 Angular 的控制范围内。

设置样式的最新原因是用 app-child 覆盖 style.css。 例如

<app-selector> .mat-tab-active {
/** Your Style **/
}

当我使用封装时,它会影响整个应用程序,而不是我只想设置样式的单个组件。