Styling nested shadowDOM
with parts and exportparts
by WebComponents
HTML
<script>
class GridElements extends HTMLElement {
constructor() {
super().attachShadow({
mode: 'open'
})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
}
}
customElements.define('my-grid', class extends GridElements {});
customElements.define('my-post', class extends GridElements {});
</script>
<template id="MY-GRID">
<style>
:host {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 1em;
}
::slotted(my-post) {
background: green;
}
my-post::part(title) {
background: blue;
color: white;
}
</style>
<slot></slot>
<my-post><span slot="title">Hello</span>I am in <my-grid> lightDOM, can only be ::part styled from <my-grid></my-post>
<my-post exportparts="title"><span slot="title">Hello</span>I am in <my-grid> lightDOM; but global styles can *also* style me because I have a 'exportparts' attribute</my-post>
</template>
<style id="GLOBAL_STYLE!!!">
body {
font: 16px Arial;
background: grey;
color: blue;
}
my-post::part(title) {
background: red;
}
my-grid>my-post::part(title) {
color: gold;
}
my-post>my-post::part(title) {
background: lightcoral;
}
</style>
<template id="MY-POST">
<h1 part="title">
<slot name="title">[Title]</slot>
</h1>
<slot>I am in global DOM, styled with global CSS</slot>
</template>
<my-grid>
<my-post><span slot="title">One</span></my-post>
<my-post>
<my-post><span slot="title">nested my-post</span></my-post>
</my-post>
</my-grid>
<hr>
Also see: <a href="https://meowni.ca/posts/part-theme-explainer/">https://meowni.ca/posts/part-theme-explainer/</a>