Skip to content

[ShadyCSS] Constructible Stylesheets and adoptedStyleSheets support for browsers with native shadow DOM #44

Open
@justinfagnani

Description

@justinfagnani

Constructible Stylesheets

We want to support and API as close as possible to native Constructible Stylesheets, so that this works:

const s = new CSSStyleSheet();
s.replaceSync(':host { display: block } ');

This may be achievable by overwriting the CSSStyleSheet constructor with one that creates a stylesheet in a shadow root. Something like:

const container = document.createElement('constructible-stylesheets');
container.attachShadow({mode: 'open'});
document.append(container);

const originalCSSStyleSheet = CSSStyleSheet;
CSSStyleSheet = class extends originalCSSStyleSheet {
  constructor() {
    this._styleElement = document.createElement('style');
    container.shadowRoot.append(this._styleElement);
    Object.setPrototypeOf(this, this._styleElement.sheet);
  }

  replaceSync(styleText) {
    this._styleElement.data = styleText;
  }
}

(I haven't tried this code)

adoptedStyleSheets

ShadowRoot.adoptedStyleSheets could be implemented with a setter that only accepts arrays of stylesheets created as above with a _styleElement property. It would then clone those style elements and insert them last into the shadow root.

To protect against mutations of the shadow root that remove the styles, we can put them in a custom element called <adopted-stylesheets> that adds itself back to the shadow root if it's ever removed.

const allAdoptedStylesheets = new Set();
class AdoptedStylesheetsElement extends HTMLElement {
  constructor() {
    super();
    allAdoptedStylesheets.add(this);
  }

  connectedCallback() {
    this._previousRoot = this.getRootNode();
  }

  disconnectedCallback() {
    this._previousRoot.append(this);
  }
}

allAdoptedStylesheets can be used to update cloned style tags incase replace or replaceSync is called on a CSSStyleSheet.

cc @azakus

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions