СÑилизаÑÐ¸Ñ Shadow DOM покÑÑваеÑÑÑ Ð±Ð¾Ð»ÐµÐµ обÑей ÑпеÑиÑикаÑией «CSS Scoping».
Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÑÑили внÑÑÑи Shadow DOM оÑноÑÑÑÑÑ ÑолÑко к его ÑодеÑжимомÑ.
ÐапÑимеÑ:
<p>Ðили Ð¼Ñ ÑиÑ
о-миÑно, и ÑÑÑ...</p>
<p id="elem">ÐобÑое ÑÑÑо, ÑÑÑана!</p>
<template id="tmpl">
<style>
p {
color: red;
}
</style>
<h3><content></content></h3>
<p>ÐÑÐ¸Ð²ÐµÑ Ð¸Ð· подполÑÑ!</p>
</template>
<script>
var root = elem.createShadowRoot();
root.appendChild(tmpl.content.cloneNode(true));
</script>
ÐÑи запÑÑке окÑаÑеннÑм в кÑаÑнÑй ÑÐ²ÐµÑ Ð¾ÐºÐ°Ð¶ÐµÑÑÑ ÑолÑко <p> внÑÑÑи Shadow DOM. ÐбÑаÑим внимание, окÑаÑилÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ ÑÐ¾Ñ ÑлеменÑ, коÑоÑÑй наÑ
одиÑÑÑ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвенно в Shadow DOM. Ð ÑлеменÑÑ, коÑоÑÑе оÑобÑÐ°Ð¶ÐµÐ½Ñ Ð² Shadow DOM пÑи помоÑи <content>, ÑÑÐ¾Ñ ÑÑÐ¸Ð»Ñ Ð½Ðµ полÑÑили â Ñ Ð½Ð¸Ñ
еÑÑÑ Ñвои, заданнÑе на внеÑней ÑÑÑаниÑе.
ÐнеÑний ÑÑÐ¸Ð»Ñ Ð´Ð»Ñ Shadow DOM
ÐÑаниÑа Ð¼ÐµÐ¶Ð´Ñ Shadow DOM и оÑновнÑм DOM, Ñ Ð¾ÑÑ Ð¸ ÑÑÑеÑÑвÑеÑ, но пÑи помоÑи ÑпеÑиалÑнÑÑ ÑелекÑоÑов ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ пеÑÐµÑ Ð¾Ð´Ð¸ÑÑ.
ÐÑли нÑжно Ñ Ð¾Ñновной ÑÑÑаниÑÑ ÑÑилизоваÑÑ Ð¸Ð»Ð¸ вÑбÑаÑÑ ÑлеменÑÑ Ð²Ð½ÑÑÑи Shadow DOM, Ñо можно иÑполÑзоваÑÑ ÑелекÑоÑÑ:
-
::shadowâ вÑбиÑÐ°ÐµÑ ÐºÐ¾ÑÐµÐ½Ñ Shadow DOM.ÐÑбÑаннÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñам по Ñебе не ÑоздаÑÑ CSS box, но ÑлÑÐ¶Ð¸Ñ Ð¾ÑпÑавной ÑоÑкой Ð´Ð»Ñ Ð´Ð°Ð»ÑнейÑей вÑбоÑки Ñже внÑÑÑи деÑева Shadow DOM.
ÐапÑимеÑ,
#elem::shadow > divнайдÑÑ Ð²Ð½ÑÑÑи Shadow DOM#elemÑлеменÑÑdivпеÑвого ÑÑовнÑ. -
>>>â оÑобого вида CSS-ÑелекÑÐ¾Ñ Ð´Ð»Ñ Ð²ÑÐµÑ ÑлеменÑов Shadow DOM, коÑоÑÑй полноÑÑÑÑ Ð¸Ð³Ð½Ð¾ÑиÑÑÐµÑ Ð³ÑаниÑÑ Ð¼ÐµÐ¶Ð´Ñ DOMâами, вклÑÑÐ°Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñе подÑлеменÑÑ, Ñ ÐºÐ¾ÑоÑÑÑ Ñоже Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñвой Shadow DOM.ÐапÑимеÑ,
#elem >>> spanнайдÑÑ Ð²ÑеspanвнÑÑÑи Shadow DOM#elem, но кÑоме Ñого, еÑли в#elemеÑÑÑ Ð¿Ð¾Ð´ÑлеменÑÑ, Ñ ÐºÐ¾ÑоÑÑÑ Ñвой Shadow DOM, Ñо оно пÑÐ¾Ð´Ð¾Ð»Ð¶Ð¸Ñ Ð¿Ð¾Ð¸Ñк в Ð½Ð¸Ñ .ÐÐ¾Ñ Ð¿ÑимеÑ, когда внÑÑÑи одного Shadow DOM еÑÑÑ
<input type="date">, Ñ ÐºÐ¾ÑоÑого Ñоже еÑÑÑ Shadow DOM:<style> #elem::shadow span { /* Ð´Ð»Ñ span ÑолÑко внÑÑÑи Shadow DOM #elem */ border-bottom: 1px dashed blue; } #elem >>> * { /* Ð´Ð»Ñ Ð²ÑÐµÑ ÑлеменÑов внÑÑÑи Shadow DOM #elem и далее внÑÑÑи input[type=date] */ color: red; } </style> <p id="elem"></p> <script> var root = elem.createShadowRoot(); root.innerHTML = "<span>ТекÑÑее вÑемÑ:</span> <input type='date'>"; </script> -
ÐÑоме Ñого, на Shadow DOM дейÑÑвÑÐµÑ Ð¾Ð±ÑÑное CSS-наÑледование, еÑли ÑвойÑÑво поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÐµÐ³Ð¾ по ÑмолÑаниÑ.
Ð ÑÑом пÑимеÑе CSS-ÑÑили длÑ
bodyнаÑледÑÑÑÑÑ Ð½Ð° внÑÑÑенние ÑлеменÑÑ, вклÑÑÐ°Ñ Shadow DOM:<style> body { color: red; font-style: italic; } </style> <p id="elem"></p> <script> elem.createShadowRoot().innerHTML = "<span>ÐÑивеÑ, миÑ!</span>"; </script>ÐнÑÑÑенний ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑÑÐ°Ð½ÐµÑ ÐºÑаÑнÑм кÑÑÑивом.
ÐпиÑаннÑе CSS-ÑелекÑоÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð½Ðµ ÑолÑко в CSS, но и в querySelector.
ÐÑклÑÑением ÑвлÑÑÑÑÑ Ð²ÑÑÑоеннÑе ÑлеменÑÑ Ñипа <input type="date">, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
CSS-ÑелекÑоÑÑ ÑабоÑаÑÑ, но полÑÑиÑÑ Ð¸Ñ
ÑодеÑжимое нелÑзÑ.
ÐапÑимеÑ:
<p id="elem"></p>
<script>
var root = elem.createShadowRoot();
root.innerHTML = "<span>ТекÑÑее вÑемÑ:</span> <input type='date'>";
// вÑбеÑÐµÑ ÑолÑко span из #elem
// вообÑе-Ñо, должен вÑбÑаÑÑ span и из вложеннÑÑ
Shadow DOM,
// но Ð´Ð»Ñ Ð²ÑÑÑоеннÑÑ
ÑлеменÑов - не ÑмееÑ
alert( document.querySelectorAll('#elem::shadow span').length ); // 1
</script>
СÑÐ¸Ð»Ñ Ð² завиÑимоÑÑи Ð¾Ñ Ñ Ð¾Ð·Ñина
СледÑÑÑие ÑелекÑоÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð¸Ð·Ð½ÑÑÑи Shadow DOM вÑбÑаÑÑ Ð²Ð½ÐµÑний ÑÐ»ÐµÐ¼ÐµÐ½Ñ («ÑлеменÑ-Ñ Ð¾Ð·Ñин»):
-
:hostвÑбиÑÐ°ÐµÑ ÑлеменÑ-Ñ Ð¾Ð·Ñин, в коÑоÑом, живÑÑ Shadow DOM.ХозÑин :host вÑбиÑаеÑÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ в конÑекÑÑе Shadow DOM.
То еÑÑÑ, ÑÑо доÑÑÑп не к внеÑÐ½ÐµÐ¼Ñ ÑлеменÑÑ, а, ÑкоÑее, к коÑÐ½Ñ ÑекÑÑего Shadow DOM.
ÐоÑле
:hostÐ¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑказаÑÑ ÑелекÑоÑÑ Ð¸ ÑÑили, коÑоÑÑе нÑжно пÑимениÑÑ, еÑли Ñ Ð¾Ð·Ñин ÑдовлеÑвоÑÑÐµÑ ÑÐ¾Ð¼Ñ Ð¸Ð»Ð¸ Ð¸Ð½Ð¾Ð¼Ñ ÑÑловиÑ, напÑимеÑ:<style> :host > p { color: green; } </style>ÐÑÐ¾Ñ ÑелекÑÐ¾Ñ ÑÑабоÑÐ°ÐµÑ Ð´Ð»Ñ
<p>пеÑвого ÑÑÐ¾Ð²Ð½Ñ Ð²Ð½ÑÑÑи Shadow DOM. -
:host(ÑелекÑÐ¾Ñ Ñ Ð¾Ð·Ñина)вÑбиÑÐ°ÐµÑ ÑлеменÑ-Ñ Ð¾Ð·Ñин, еÑли он Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ Ð¿Ð¾Ð´ ÑелекÑоÑ.ÐÑÐ¾Ñ ÑелекÑÐ¾Ñ Ð¸ÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑемизаÑии Ñ Ð¾Ð·Ñина «изнÑÑÑи», в завиÑимоÑÑи Ð¾Ñ ÐµÐ³Ð¾ клаÑÑов и аÑÑибÑÑов. Ðн оÑлиÑно добавлÑÐµÑ Ð¿ÑоÑÑо
:host, напÑимеÑ::host p { color: green; } :host(.important) p { color: red; }ÐдеÑÑ Ð¿Ð°ÑагÑаÑÑ Ð±ÑдÑÑ Ð¸Ð¼ÐµÑÑ
color:green, но еÑли Ñ Ñ Ð¾Ð·Ñина клаÑÑ.important, Ñоcolor:red. -
:host-context(ÑелекÑÐ¾Ñ Ñ Ð¾Ð·Ñина)вÑбиÑÐ°ÐµÑ ÑлеменÑ-Ñ Ð¾Ð·Ñин, еÑли какой-либо из его ÑодиÑелей ÑдовлеÑвоÑÑÐµÑ ÑелекÑоÑÑ, напÑимеÑ::host-context(h1) p { /* ÑелекÑÐ¾Ñ ÑÑабоÑÐ°ÐµÑ Ð´Ð»Ñ p, еÑли Ñ Ð¾Ð·Ñин Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð²Ð½ÑÑÑи h1 */ }ÐÑо иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑаÑÑиÑенной ÑемизаÑии, ÑепеÑÑ Ñже не ÑолÑко в завиÑимоÑÑи Ð¾Ñ ÐµÐ³Ð¾ аÑÑибÑÑов, но и Ð¾Ñ Ñого, внÑÑÑи ÐºÐ°ÐºÐ¸Ñ ÑлеменÑов он Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ.
ÐÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑелекÑоÑа :host() Ð´Ð»Ñ Ñазной ÑаÑÑвеÑки Shadow DOM-ÑообÑениÑ, в завиÑимоÑÑи Ð¾Ñ Ñого, в каком оно <p>:
<p class="message info">ÐобÑое ÑÑÑо, ÑÑÑана!</p>
<p class="message warning">Ðнимание-внимание! ÐовоÑÐ¸Ñ Ð¸Ð½ÑоÑмбÑÑо!</p>
<template id="tmpl">
<style>
.content {
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
}
:host(.info) .content {
color: green;
}
:host(.warning) .content {
color: red;
}
</style>
<div class="content"><content></content></div>
</template>
<script>
var elems = document.querySelectorAll('p.message');
elems[0].createShadowRoot().appendChild( tmpl.content.cloneNode(true) );
elems[1].createShadowRoot().appendChild( tmpl.content.cloneNode(true) );
</script>
СÑÐ¸Ð»Ñ Ð´Ð»Ñ content
Тег <content> не менÑÐµÑ DOM, а ÑказÑваеÑ, ÑÑо где показÑваÑÑ. ÐоÑÑÐ¾Ð¼Ñ ÐµÑли ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸Ð·Ð½Ð°ÑалÑно наÑ
одиÑÑÑ Ð² ÑлеменÑе-Ñ
озÑине â внеÑний докÑÐ¼ÐµÐ½Ñ ÑоÑ
ÑанÑÐµÑ Ðº Ð½ÐµÐ¼Ñ Ð´Ð¾ÑÑÑп.
Ð Ð½ÐµÐ¼Ñ Ð±ÑдÑÑ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ñ ÑÑили и ÑÑабоÑаÑÑ ÑелекÑоÑÑ, вÑÑ ÐºÐ°Ðº обÑÑно.
ÐапÑимеÑ, здеÑÑ Ð¿ÑимениÑÑÑ ÑÑÐ¸Ð»Ñ Ð´Ð»Ñ <span>:
<style>
span { text-decoration: underline; }
</style>
<p id="elem"><span>ÐобÑое ÑÑÑо, ÑÑÑана!</span></p>
<template id="tmpl">
<h3><content></content></h3>
<p>ÐÑÐ¸Ð²ÐµÑ Ð¸Ð· подполÑÑ!</p>
</template>
<script>
elem.createShadowRoot().appendChild( tmpl.content.cloneNode(true) );
</script>
РпÑимеÑе вÑÑе заголовок «ÐобÑое ÑÑÑо, ÑÑÑана!», коÑоÑÑй пÑиÑÑл как <span> из внеÑнего докÑменÑа, бÑÐ´ÐµÑ Ð¿Ð¾Ð´ÑÑÑкнÑÑ,
ÐÑак, ÑÑили оÑновного DOM-деÑева пÑименÑÑÑÑÑ, вÑÑ Ð² поÑÑдке.
Ðо ÑÑо, еÑли Shadow DOM Ñоже Â«Ð¸Ð¼ÐµÐµÑ Ð²Ð¸Ð´Ñ» на <content> и Ñ
оÑÐµÑ ÑÑилизоваÑÑ Ð²ÑÑавленное? ÐÑо Ñоже возможно.
ÐÐ»Ñ Ð¾Ð±ÑаÑÐµÐ½Ð¸Ñ Ðº «ÑодеÑжимомÑ» <content> из ÑÑилей внÑÑÑи Shadow DOM иÑполÑзÑеÑÑÑ Ð¿ÑевдоÑÐ»ÐµÐ¼ÐµÐ½Ñ ::content.
ÐапÑимеÑ, изнÑÑÑи Shadow DOM ÑелекÑÐ¾Ñ content[select="h1"]::content span найдÑÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ <content select="h1"> и в его ÑодеÑжимом оÑÑÑÐµÑ <span>.
РпÑимеÑе ниже ÑелекÑÐ¾Ñ ::content span ÑÑилизÑÐµÑ Ð²Ñе <span> внÑÑÑи вÑеÑ
<content>:
<style>
span { text-decoration: underline; }
</style>
<p id="elem"><span>ÐобÑое ÑÑÑо, ÑÑÑана!</span></p>
<template id="tmpl">
<style>
::content span { color: green; }
</style>
<h3><content></content></h3>
<span>ÐÑÐ¸Ð²ÐµÑ Ð¸Ð· подполÑÑ!</span>
</template>
<script>
elem.createShadowRoot().appendChild( tmpl.content.cloneNode(true) );
</script>
ТекÑÑ Ð²Ð½ÑÑÑи <h3> â зелÑнÑй и подÑÑÑкнÑÑÑй одновÑеменно, но ÑÑилизÑеÑÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ ÑÐ¾Ñ <span>, коÑоÑÑй показан в <content>, а ÑоÑ, коÑоÑÑй пÑоÑÑо в Shadow DOM â неÑ.
ÐÑиоÑиÑÐµÑ ÑелекÑоÑов ÑаÑÑÑиÑÑваеÑÑÑ Ð¿Ð¾ обÑÑнÑм пÑавилам ÑпеÑиÑиÑноÑÑи, еÑли же пÑиоÑиÑеÑÑ ÑÑилей на ÑÑÑаниÑе и в Shadow DOM ÑавнÑ, Ñо, как опиÑано в ÑекÑии Cascading, Ð¿Ð¾Ð±ÐµÐ¶Ð´Ð°ÐµÑ ÑÑÑаниÑа, а Ð´Ð»Ñ !important-ÑÑÐ¸Ð»Ñ Ð¿Ð¾Ð±ÐµÐ¶Ð´Ð°ÐµÑ Shadow DOM.
ÐÑого
Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÑÑили и ÑелекÑоÑÑ Ð¸Ð· DOM-деÑева дейÑÑвÑÑÑ ÑолÑко на Ñе ÑлеменÑÑ, в коÑоÑÑÑ Ñами Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ.
ÐÑаниÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ пÑеодолеваÑÑ, пÑиÑÑм пÑоÑе, еÑÑеÑÑвенно, Ð¾Ñ ÑодиÑÐµÐ»Ñ Ðº Shadow DOM, Ñем наобоÑоÑ:
- СнаÑÑжи можно вÑбиÑаÑÑ Ð¸ ÑÑилизоваÑÑ ÑлеменÑÑ Ð²Ð½ÑÑÑи Shadow DOM â пÑи помоÑи ÑелекÑоÑов
::shadowи>>>. - ÐзнÑÑÑи Shadow DOM можно ÑÑилизоваÑÑ Ð½Ðµ ÑолÑко Ñо, ÑÑо изнаÑалÑно в Shadow DOM, но и ÑзлÑ, показÑваемÑе в
<content>. - Также можно ÑÑавиÑÑ ÑÑÐ¸Ð»Ñ Ð² завиÑимоÑÑÑ Ð¾Ñ Ñ
озÑина пÑи помоÑи ÑелекÑоÑов
::host,::host-context, но вÑбиÑаÑÑ Ð¸ ÑÑилизоваÑÑ Ð¿ÑоизволÑнÑе Ñеги внÑÑÑи Ñ Ð¾Ð·Ñина нелÑзÑ.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)