Is there a way to inherit :host element css styles into shadow DOM? The reason is if we start developing web components, each web component style must be consistent on a page.
The page can have global css, and this global css styles can be inherited to shadow DOM. There was ::shadow
and /deep/
, but it's deprecated now.
Or, is this against pattern? If so, why?
I found this Q/A, but seems outdated for me. Can Shadow DOM elements inherit CSS?
http://plnkr.co/edit/qNSlM0?p=preview
const el = document.querySelector('my-element');
el.attachShadow({mode: 'open'}).innerHTML = `
<!-- SEE THIS 'red' is not red -->
<p class="red">This is defined in Shadow DOM. I want this red with class="red"</p>
<slot></slot>
`;
.red {
padding: 10px;
background: red;
font-size: 25px;
text-transform: uppercase;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<!-- web components polyfills -->
<script src="//unpkg.com/@webcomponents/custom-elements"></script>
<script src="//unpkg.com/@webcomponents/webcomponentsjs"></script>
<script src="//unpkg.com/@webcomponents/shadydom"></script>
<script src="//unpkg.com/@webcomponents/[email protected]/apply-shim.min.js"></script>
</head>
<body>
<div>
<p class="red">I'm outside the element (big/white)</p>
<my-element>
<p class="red">Light DOM content is also affected.</p>
</my-element>
<p class="red">I'm outside the element (big/white)</p>
</div>
</body>
</html>
Using the same <link> tag both in your outer document and inside your component's Shadow DOM is currently the best way to share styles across your components without code duplication, while CSS custom properties provide a well supported, albeit somewhat limited, way of dynamically updating shared styles.
Shadow DOM is very important for web components because it allows specific sections of the HTML document to be completely isolated from the rest of the document. This means CSS styles that are applied to the DOM are not applied to the Shadow DOM, and vice versa.
Shadow DOM (V1) on Android Browser is fully supported on 97-103, partially supported on None of the versions, and not supported on 2.3-4 Android Browser versions. Shadow DOM (V1) on Opera Mobile is fully supported on 64-64, partially supported on None of the versions, and not supported on 10-12 Opera Mobile versions.
Inheritable styles Taking color as an example, if there is a color: green set on the body (which is a container for every element on the page), this will be inherited by all elements on the page, including Web Components, unless overriden by another more specific rule.
As supersharp pointed out it's very simple but not obvious from the examples you can find on the internet. Take this base class as an example. Alternatively, you could make two different ones (e.g. Component and ShadowComponent). There is also the option to use adoptedStyleSheets
or the ::part
selector.
class HtmlComponent extends HTMLElement {
static ModeShadowRoot = 0;
static ModeRoot = 1;
static styleSheets = [];
static mode = HtmlComponent.ModeShadowRoot;
#root = null;
constructor() {
super();
if (this.constructor.mode === HtmlComponent.ModeShadowRoot) {
const shadowRoot = this.attachShadow({ mode: 'closed' });
shadowRoot.adoptedStyleSheets = this.constructor.styleSheets;
this.#root = shadowRoot;
} else {
this.#root = this;
}
}
get root() {
return this.#root;
}
init() {
this.root.innerHTML = this.render();
}
render() {
return '';
}
}
class Test extends HtmlComponent {
static mode = HtmlComponent.ModeRoot;
constructor() {
super();
super.init();
}
render() {
return `
<div>
<x-nested-component></x-nested-component>
</div>
`;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With