Injects custom CSS into open shadow roots via HTML attributes with optional runtime watching for attribute changes or newly added nodes.
- Add inline CSS or external
.cssfiles into open shadow roots - Works with one or multiple attributes
- Optional live watching via MutationObserver: React to attribute changes and dynamically added nodes
- Zero dependencies, tiny footprint
npm install @glowingblue-dev/shadow-cssor
yarn add @glowingblue-dev/shadow-cssAssuming an unstyleable third party WebComponent with an open shadow DOM like:
<custom-element>[#shadowDOM]<div class="classname"></div>[/#shadowDOM]</custom-element><custom-element data-css=".classname { color: red; }"></custom-element>import $shadowCSS from "@glowingblue-dev/shadow-css";
$shadowCSS("data-css");<custom-element data-css="/path/to/styles.css"></custom-element>$shadowCSS("data-css", { watch: true });<custom-element
data-theme="/themes/dark.css"
data-css=".classname { color: red; }"
></custom-element>$shadowCSS(["data-theme", "data-css"], { watch: true });$shadowCSS(attrs?: string | string[], options?: { watch?: boolean }, target?: Node): MutationObserver- attrs — one or more attribute names (default:
"data-css"). - options.watch — if
true, sets up aMutationObserverto update when the attribute value changes or when new elements with the attribute are added. - options.target - The target node to to look for attributes and optionally observe, defaults to the global
document.
Always returns a MutationObserver instance, if watch: true it is already activated and observing the DOM and can be disabled by calling .disconnect() at any later point. If watch: false (default) you can activate it at a point of your choosing by calling .observe(<target>, <options>). The default options are attached to the returned MutationObserver instance for convenience.
When using a shared stylesheet across multiple components, scope your rules with :host(...):
:host(custom-element) .selector {
transform: rotate(180deg);
}
:host(custom-element) {
& .selector {
...;
}
&:hover .selector {
...;
}
}- Only works with open shadow DOMs. Closed roots cannot be styled this way.
- Runs in browsers (relies on
document).
MIT © Glowing Blue AG
Originally authored by exside