A proof-of-concept implementation of open-styleable shadow-roots, using a combination of:
attachShadow
View the hosted examples:
Edit the code live:
(See standalone setup instructions below if you're trying to use this in your own project) 👀
The access for open styles is controlled at the shadow-root level. Every shadow-root needs to explicitly opt-in using one of the following ways.
For declarative shadow DOM (DSD):
Add the adopthoststyles
attribute to the DSD template. This shadow-root will now automatically inherit all styles from the host context (i.e. the document or a parent shadow-root).
<template shadowrootmode="open" adopthoststyles>…</template>
Alternatively, if you only want to adopt styles from the document and not from the parent shadow-root, then you can use adoptpagestyles
.
<template shadowrootmode="open" adoptpagestyles>…</template>
For client-rendered shadow-roots, use the adoptPageStyles
and adoptHostStyles
options when calling attachShadow
.
adoptHostStyles
to adopt all styles from the host context.
this.attachShadow({
mode: "open",
adoptHostStyles: true,
});
adoptPageStyles
to adopt all styles from the page/document only.
this.attachShadow({
mode: "open",
adoptPageStyles: true,
});
[!IMPORTANT] There are some known limitations/caveats that you should be aware of.
To use this "polyfill" in your own project:
open-styleable
from npm (or use import maps).
npm add open-styleable
.eleventy.js
for an example). This should ideally be executed after all bundling steps.
import { transformHtml } from "open-styleable";
// assuming `htmlContent` is the original page content
htmlContent = transformHtml(htmlContent);
/client
script in your <head>
before any custom elements are registered.
<script>
import "open-styleable/client";
</script>
or from a CDN:
<script src="https://esm.sh/open-styleable/client"></script>
[!NOTE] You do not always need to use both the build-time transform and the client-side script. They are completely independent and do different things.
This demo is built with 11ty. All test pages go in the pages/
directory.