在html中,不管一個style元素定義在什麼地方,其內部的規則都是做用到整個html文檔的。
從框架的設計和使用者角度來看,對組件樣式都一種封裝需求:就是但願針對組件定義的樣式只在這個組件內部生效,不影響這個組件以外的元素。
Angular 提供了3種樣式封裝選項: ViewEncapsulation.Native, ViewEncapsulation.Emulated, ViewEncapsulation.None。 這裏有篇介紹文章:https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html
能夠在定義組件時配置樣式封裝的方式,例如:css
@Component({ moduleId: module.id, selector: '...', templateUrl: '....component.html', styles: [`...`], encapsulation: ViewEncapsulation.None })
默認的封裝方式是 ViewEncapsulation.Emulated, 由於Native會使用shadow Dom, 而shadow Dom 如今並無獲得普遍的瀏覽器支持。html
默認的封裝方式 Emulated ,Angular在運行時會同時對該組件的 html 模板和 css規則進行修改:web
html模板中的元素都會添加一個屬性 _ngcontent-c* , 星號表示一個數字,例如api
<div _ngcontent-c39="" class="topo-container">
每條樣式規則的每一個selector都會加上和上面元素新增的屬性對應的屬性選擇器,例如:瀏覽器
你定義的規則是這樣的:angular2
div.button-cotainer div.play-button button.fa-arrow-left { padding-left: 7px; padding-top: 1px; }
在瀏覽器中查看規則,你看到的是這樣的:app
div.button-cotainer[_ngcontent-c39] div.play-button[_ngcontent-c39] button.fa-arrow-left [_ngcontent-c39] { padding-left: 7px; padding-top: 1px; }
上面這種對CSS規則的修改,會帶來一個問題:框架
因爲在JS代碼中經過web api(例如 appenChild())動態添加的元素是沒有 _ngcontent-c* 這種屬性的,致使組件的元數據中的CSS規則沒法應用到這種動態添加的元素。dom
規避這個問題的方法:使用 /deep/ 語法,該語法告知angular不要在 /deep/以後的元素類型上添加屬性修飾,例如:選擇器 /deep/ p span 通過angular編譯後 就是 p span, 固然這樣就使得樣式具備了全局性,因此最好是結合:host 使用, 例如 :host /deep/ p span。spa