Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shadow DOM global css inherit possible?

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>
like image 809
allenhwkim Avatar asked Oct 13 '17 18:10

allenhwkim


People also ask

Which is a way to add global styling to shadow DOM?

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.

What is the advantage of shadow DOM?

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.

Is shadow DOM supported?

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.

Can Web components inherit styles?

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.


1 Answers

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>
        `;
    }
}
like image 167
gad dsfd Avatar answered Nov 12 '22 16:11

gad dsfd