EDIT 1
Thanks very much @Danny for the very useful answer. I guess my question has more to do with CSS sope and encapsulation. If I import a CSS StyleSheet into a module then I don't want that Stylesheet to bleed out into the parent and lightDOM of the caller. The effect I want to achieve is similar to this basic Custom Element In this case I build a STYLE element and attach it to the Extension class of HTMLElement.
I'm trying to achieve the same thing with Javascript/CSS modules. I will try with myDiv.part='shadowTree' but that seems to be defeating the whole purpose of ShadowDOM.
I'll go read up om SLOTs again but I only want to expose certain elements from my module call. This is what I thought #returnedDiv::part(styleableRuleException) wass, the rest of the CSS I expected to be forcably scoped to my JS module?
WRT MDN I think my problem is my imported StyleSheet is not a "constructed stylesheet"? Like:-
let sheet = new CSSStyleSheet();
But Web.Dev says ok?
<EDIT 1
I am trying to use Shadow DOM in my Javascript module and also import a CSS module/sheet into the Javascript module: -
module.js
import sheet from '/styles.css' assert {type: 'css'};
export function message()
{
const myDiv = document.createElement("div");
const shadowRoot = myDiv.attachShadow({mode:"open"});
document.adoptedStyleSheets = [sheet];
myDiv.textContent = "This is Text";
return myDiv;
}
As soon as I add the line to .attachShadow() the content of the DIV "This is Text" stopped appearing.
If I went further an tried to adoptStyleSheets to the shadowRoot instead of the document then no CSS from styles.css took effect.
styles.css
host:: {
background-color: yellow;
}
div {
background-color: red;
}
What do I have to do to be able to use Shadow DOM in my Modules in concert with Adopted Styles from CSS modules?
test_mod.html
<!DOCTYPE html>
<html>
<style type="text/css">
div div {
height: 100px;
width: 100px;
text-align: center;
background-color: lightblue;
}
</style>
<script type="module">
import {message} from "http://localhost/message.js";
document.getElementById("demo").appendChild(message());
</script>
<body>
<h1>JavaScript Modules</h1>
<div id="demo"></div>
</body>
</html>
As soon as I add the line to .attachShadow() the content of the DIV "This is Text" stopped appearing.
Because you set content in lightDOM which will only be shown in shadowDOM when you <slot>
it.
If I went further an tried to adoptStyleSheets to the shadowRoot instead of the document then no CSS from styles.css took effect.
The syntax is :host
not host::
Do read:
Here is a playground with almost all shadowDOM goodies.
JSFiddle: https://jsfiddle.net/WebComponents/bj4n1L0r/
<h1>shadowDOM, loathed but loaded</h1>
<script>
function adoptSheet(atRoot, styles) {
let sheet = new CSSStyleSheet();
sheet.replaceSync(styles);
atRoot.adoptedStyleSheets.push(sheet);
}
// Global CSS
adoptSheet(document, "h1 { background: hotpink }" +
"div { background: pink }" +
"div::part(shadowH1) { background: lightgreen }");
const myDiv = document.createElement("div");
myDiv.setAttribute("border", "true");
const shadowRoot = myDiv.attachShadow({ mode: "open" });
adoptSheet(shadowRoot, ":host { background: red; padding: 5px }" +
":host([border]) { border:2px dashed green }" +
"h1 { color: green }" +
"::slotted(h1) { color: blue }");
myDiv.innerHTML = "<h1 >I am in lightDOM</h1>";
shadowRoot.innerHTML = "<h1 part='shadowH1'>I am in shadowDOM</h1>" +
"<slot>lightDOM will be slotted here</slot>";
document.body.append(myDiv);
</script>
Global CSS styles BOTH <h1>
in the main document background:hotpink
, because slotted content is not moved to shadowDOM but reflected to shadowDOM
See (long read): ::slotted CSS selector for nested children in shadowDOM slot
::part
in global CSS can style content inside shadowDOM
https://developer.mozilla.org/en-US/docs/Web/CSS/::part
:host
has no Specificity, so the shadowDOM is not background: red
This is so (web) Component users can override default styling (see background:pink
), if you do not want that, add an extra <div>
layer in your shadowDOM and style that.
There are 2 types of (Web Component) Developers:
Those who moan about shadowDOM, and those who learned to master shadowDOM