Does The Shadow Dom Replace: :Before and: :After

Does the shadow DOM replace ::before and ::after?

CSS Scoping spec author here.

The answer is actually, officially... undefined!

I didn't think about this interaction when I was writing the Scoping spec. I'll send an email to the list, and we'll figure it out. Almost certainly, we'll settle on whatever browsers currently do (which appears to be letting ::before/after work "as expected" even in shadow hosts).

Edit: The Working Group's response was unanimous - the current implementation behavior (::before/after do work on shadow hosts) is how it should be. I'll edit it into the Scoping spec shortly.

Need help understanding the Shadow DOM

From the Shadow DOM spec,

A document tree is a node tree whose root node is a document.

Any element can host zero or one associated node trees, called a
shadow tree.

A shadow host is an element that hosts one shadow tree.

A shadow root is the root node of a shadow tree.

A tree of trees is a tree of node trees.

Sample Image

Then, yes, shadow trees are outside the document tree, but they are still linked forming a tree of trees.

And yes, the shadow contents are rendered instead of the descendants of the element, as defined in CSS Scoping:

The most recently-created shadow tree on an element is the active
shadow tree
for that element.

The descendants of a shadow host must not generate boxes in the
formatting tree. Instead, the contents of the active shadow tree
generate boxes as if they were the contents of the element instead.

Modifying custom elements' style in shadow root

In order to style the element that hosts the Shadow DOM, here <custom-calculator>, you must use de :host pseudo-class (instead of custom-calculator which is unknown inside the Shadow DOM).

:host {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}

Because the Shadow DOM will replace/recover the normal DOM tree (here <output-screen>), you'll have to use <slot> to insert/reveal it in the Shadow DOM.

calc.shadowRoot.innerHTML = `
<style>
...
</style>
<slot></slot>`

Then, in order to style what is revealed by/in the <slot> element, you mus use the ::slotted() pseudo-element:

::slotted( output-screen ){
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}

Live example:

var calc = document.querySelector('#calculator')calc.attachShadow({mode: 'open'});calc.shadowRoot.innerHTML = `  <style>    :host {      display:inline-block;      background-color:grey;      width:100%;      height:100vh;      vertical-align:top;    }
::slotted( output-screen ){ display:inline-block; background-color:orange; width:50%; height:100vh; } </style> <slot></slot>`;
<custom-calculator id="calculator">  <output-screen></output-screen></custom-calculator>

How to remove a shadow root from an HTML element adorned with a Shadow DOM from a template?

You can't remove a shadow root once you add it. However, you can replace it with a newer one.

As mentioned here, http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/, the newest shadow root "wins" and becomes the rendered root.

You can replace your shadow root with a new shadow root that only contains the <content> pseudo-element to insert everything from the light DOM back into the shadow DOM. At that point, as far as I know it will be functionally equivalent to having no shadow DOM at all.

Is shadow DOM on body element a bad idea?

1) Is BODY as a HOST ok?

Yes

2) What is best-practice for replacing Shadow DOM?

Use either:

body.shadowRoot.innerHTML = [new template innerHTML] 

or:

body.shadowRoot.replaceChild( newNodes, oldNode )

or:

body.shadowRoot.innerHTML = ''
body.shadowRoot.appendChild( newNodes )

With template.content you get directly the already parsed DocumentFragment so it could be faster in some situations, while with template.innerHTML you can take profit of template literals, and then include the values of some variables.



Related Topics



Leave a reply



Submit