填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

檢視封裝模式

View encapsulation

在 Angular 中,元件的 CSS 樣式被封裝進了自己的檢視中,而不會影響到應用程式的其它部分。

In Angular, component CSS styles are encapsulated into the component's view and don't affect the rest of the application.

透過在元件的元資料上設定檢視封裝模式,你可以分別控制每個元件的封裝模式。 可選的封裝模式一共有如下幾種:

To control how this encapsulation happens on a per component basis, you can set the view encapsulation mode in the component metadata. Choose from the following modes:

  • ShadowDom 模式使用瀏覽器原生的 Shadow DOM 實現(參閱 MDN 上的 Shadow DOM)來為元件的宿主元素附加一個 Shadow DOM。元件的檢視被附加到這個 Shadow DOM 中,元件的樣式也被包含在這個 Shadow DOM 中。(譯註:不進不出,沒有樣式能進來,元件樣式出不去。)

    ShadowDom view encapsulation uses the browser's native shadow DOM implementation (see Shadow DOM on the MDN site) to attach a shadow DOM to the component's host element, and then puts the component view inside that shadow DOM. The component's styles are included within the shadow DOM.

  • Emulated 模式(預設值)透過預處理(並改名)CSS 程式碼來模擬 Shadow DOM 的行為,以達到把 CSS 樣式侷限在元件檢視中的目的。 更多資訊,見附錄 1。(譯註:只進不出,全域性樣式能進來,元件樣式出不去)

    Emulated view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing (and renaming) the CSS code to effectively scope the CSS to the component's view. For details, see Inspecting generated CSS below.

  • None 意味著 Angular 不使用檢視封裝。 Angular 會把 CSS 新增到全域性樣式中。而不會應用上前面討論過的那些作用域規則、隔離和保護等。 從本質上來說,這跟把元件的樣式直接放進 HTML 是一樣的。(譯註:能進能出。)

    None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML.

透過元件元資料中的 encapsulation 屬性來設定元件封裝模式:

To set the components encapsulation mode, use the encapsulation property in the component metadata:

// warning: few browsers support shadow DOM encapsulation at this time encapsulation: ViewEncapsulation.ShadowDom
src/app/quest-summary.component.ts
      
      // warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.ShadowDom
    

ShadowDom 模式只適用於提供了原生 Shadow DOM 支援的瀏覽器(參閱 Can I use 上的 Shadow DOM v1 部分)。 它仍然受到很多限制,這就是為什麼模擬 (Emulated) 模式是預設選項,並建議將其用於大多數情況。

ShadowDom view encapsulation only works on browsers that have native support for shadow DOM (see Shadow DOM v1 on the Can I use site). The support is still limited, which is why Emulated view encapsulation is the default mode and recommended in most cases.

檢視產生的 CSS

Inspecting generated CSS

當使用預設的模擬模式時,Angular 會對元件的所有樣式進行預處理,讓它們模仿出標準的 Shadow CSS 作用域規則。

When using emulated view encapsulation, Angular preprocesses all component styles so that they approximate the standard shadow CSS scoping rules.

在啟用了模擬模式的 Angular 應用的 DOM 樹中,每個 DOM 元素都被加上了一些額外的屬性。

In the DOM of a running Angular application with emulated view encapsulation enabled, each DOM element has some extra attributes attached to it:

<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>
      
      <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>
    

產生出的屬性分為兩種:

There are two kinds of generated attributes:

  • 一個元素在原生封裝方式下可能是 Shadow DOM 的宿主,在這裡被自動新增上一個 _nghost 屬性。 這是元件宿主元素的典型情況。

    An element that would be a shadow DOM host in native encapsulation has a generated _nghost attribute. This is typically the case for component host elements.

  • 元件檢視中的每一個元素,都有一個 _ngcontent 屬性,它會標記出該元素屬於哪個宿主的模擬 Shadow DOM。

    An element within a component's view has a _ngcontent attribute that identifies to which host's emulated shadow DOM this element belongs.

這些屬性的具體值並不重要。它們是自動產生的,並且你永遠不會在程式程式碼中直接參考到它們。 但它們會作為產生的元件樣式的目標,就像 DOM 的 <head> 中一樣:

The exact values of these attributes aren't important. They are automatically generated and you never refer to them in application code. But they are targeted by the generated component styles, which are in the <head> section of the DOM:

[_nghost-pmm-5] { display: block; border: 1px solid black; } h3[_ngcontent-pmm-6] { background-color: white; border: 1px solid #777; }
      
      [_nghost-pmm-5] {
  display: block;
  border: 1px solid black;
}

h3[_ngcontent-pmm-6] {
  background-color: white;
  border: 1px solid #777;
}
    

這些就是那些樣式被處理後的結果,每個選擇器都被增加了 _nghost_ngcontent 屬性選擇器。 這些額外的選擇器實現了本文所描述的這些作用域規則。

These styles are post-processed so that each selector is augmented with _nghost or _ngcontent attribute selectors. These extra selectors enable the scoping rules described in this page.