Slotted form

Slotting a form. Caveats: the form styling must live *outside* the shadow root!

by David Iglesias

HTML

<div id="shadow_container">
  <style>
    form label {
      font-weight: bold;
    }
  </style>
  <p>
  This doesn't show up, because it's not "slotted" anywhere!
  </p>
  <div slot="other-contents">
    <h1>
      Slotted form
    </h1>
  </div>
  <!-- Careful when slotting "unusual elements": https://drafts.csswg.org/css-display/#unbox (always wrap the slotted content in a DIV) -->
  <form slot="slotted-form">
    <label for="firstName">First Name:</label>
    <input id="firstName" type="text" autocomplete="given-name">
    <label for="lastName">Last Name:</label>
    <input id="lastName" type="text" autocomplete="family-name">
    <label for="pass">Password:</label>
    <input id="pass" type="password">
  </form>
</div>

CSS

* {
  font-family: sans-serif;
  box-sizing: border-box;
}

form label {
  display: block;
}

/* Does not affect things inside the shadow root */
.graphix {
  border: 1px solid red !important;
}

JavaScript

let shadow = shadow_container.attachShadow({
  mode: 'open',
  delegatesFocus: true,
});

let formSlot = document.createElement('slot');
formSlot.name = 'slotted-form';

let otherSlot = document.createElement('slot');
otherSlot.name = 'other-contents';

// The form and H1 only show up if you append
// their slot to the shadow.
shadow.append(otherSlot);
shadow.append(formSlot);

// These styles only affect things that
// are added into the shadow root.
let shadowStyles = new CSSStyleSheet();
shadowStyles.replaceSync(`
  .graphix {
    margin: 10px auto;
    padding: 5px;
    border: 1px solid blue;
    color: blue;
    text-align: center;
  }
`);

shadow.adoptedStyleSheets = [shadowStyles];

let graphix = document.createElement('div');
graphix.classList.add('graphix');
graphix.innerText = 'cool .graphix';
shadow.append(graphix);