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 &lt;my-grid> lightDOM, can only be ::part styled from &lt;my-grid></my-post>
  <my-post exportparts="title"><span slot="title">Hello</span>I am in &lt;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>