對於Webcomponent而言,Shadow Dom 帶來了不少做用域以及樣式封裝之類的好處,使得組件在CSS影響範圍上變得更加安全和簡單。樣式不會被上層的組件介入影響,更不會被內層組件影響。css
這對保護樣式不受未知的,不可控的外界因素所幹擾很是有用。可是當你想要刻意去修改一個自定義組件的樣式時該怎麼辦?咱們常常要面臨這個問題,好比在某個固定的主題(theme)下作一些針對某些組件的特殊的樣式修改。舉個例子,「custom-checkbox」組件使用 .checked這個class,而另一個component也碰巧使用了.checked 這個class的時候Polymer提供的Shadow Style功能就很好的解決了同名class相互影響,相互污染的問題。html
爲了解決污染的問題傳統的作法每每是,給css定義加上不少前綴,以前加上不少dom層級的定義(相似於namespace)來區分重名的class,而有了Shadow Style以後,媽媽就不再擔憂class重名了。chrome
咱們先來看一段代碼,定義一個componentsass
<link rel="import" href="../bower_components/polymer/polymer.html"> <dom-module id="my-toolbar"> <style> :host{ padding: 4px; background-color: gray; } .title{ color: var(--my-toolbar-title-color); } </style> <template> <span class="title">{{title}}</span> </template> <script> Polymer({ is: 'my-toolbar', properties: { title: String } }); </script> </dom-module>
咱們能夠看到span上的className爲title,而titile的定義裏出現了奇怪的東西var (xxxxxx)安全
.title{ color: var(--my-toolbar-title-color); }
咱們望文生義一下,從字面上理解這個color應該是個動態的值,具體顏色必定是由外部使用這個component的父component來決定的,而--my-toolbar-title-color應該就是一個變量名,存放外部傳入的具體顏色值。
接下去咱們再定義一個父component來使用這個my-toolbarapp
<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="my-toolbar.html"> <dom-module id="my-element"> <style> :host{ --my-toolbar-title-color: green; } .warning{ --my-toolbar-title-color:red; } </style> <template> <my-toolbar title="This one is green."></my-toolbar> <my-toolbar title="This one is green too."></my-toolbar> <my-toolbar class="warning" title="This one is red."></my-toolbar> </template> <script> Polymer({ is: 'my-element' }); </script> </dom-module>
運行結果一目瞭然,my-toolbar這個component中定義的css變量能夠被外部使用它的my-element這個父component賦值。形式上感受就是--my-toolbar-title-color這個自定義的變量稱爲一個新的css屬性,能夠被賦值(正如咱們小標題上的稱呼—— 自定義css屬性)。dom
固然你也能夠給var --my-toobar-title-color一個默認的初始值,以防外界沒有給它賦值,如spa
color: var(--my-toolbar-title-color, blue);
這種自定義css屬性,對於擴展咱們傳統的樣式十分有幫助,尤爲是切換不一樣配色的主題時,目前Firefox已經原生支持這種寫法,chrome和safari也已經宣稱要支持這一特性,鼓掌!code
瞭解過sass的朋友應該對@mixin不陌生,polymer也提供了整塊整塊定義css樣式的功能,先看代碼,咱們對以前的my-toolbar的代碼稍做改動,使用@apply來聲明瞭2個變量接收mixin的樣式塊。component
<link rel="import" href="../bower_components/polymer/polymer.html"> <dom-module id="my-toolbar"> <style> :host{ padding: 4px; background-color: gray; /* apply a mixin*/ @apply(--my-toolbar-theme); } .title{ @apply(--my-toolbar-title-theme); } </style> <template> <span class="title">{{title}}</span> </template> <script> Polymer({ is: 'my-toolbar', properties: { title: String } }); </script> </dom-module>
以後對my-element也作一下修改
<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="my-toolbar.html"> <dom-module id="my-element"> <style> /* Apply custom theme to toolbars */ :host { --my-toolbar-theme: { background-color: yellow; border-radius: 4px; border: 1px solid gray; }; --my-toolbar-title-theme: { color: green; }; } /* Make only toolbars with the .warning class red and bold */ .warning { --my-toolbar-title-theme: { color: red; font-weight: bold; }; } </style> <template> <my-toolbar title="This one is green."></my-toolbar> <my-toolbar title="This one is green too."></my-toolbar> <my-toolbar class="warning" title="This one is red."></my-toolbar> </template> <script> Polymer({ is: 'my-element' }); </script> </dom-module>
運行結果
咱們能夠看到@apply和以前的var做用實際上是相似的,只不過@apply定義的變量接收的是由多條style規則組成的塊。