Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Stylesheet Observer #1041

Open
bahrus opened this issue Dec 21, 2023 · 4 comments
Open

[Proposal] Stylesheet Observer #1041

bahrus opened this issue Dec 21, 2023 · 4 comments

Comments

@bahrus
Copy link

bahrus commented Dec 21, 2023

It would be nice for a web component to be able to observe stylesheets as they are adopted or imported by the parent Shadow DOM scope or the root document, and pick and choose which ones to import.

So the basic shape would look like:

const observer = new StyleSheetObserver(options: StyleSheetObserverOptions);
observer.addEventListener('stylesheetadded', e => {
    console.log(e.stylesheet);
});
observer.addEventListener('stylesheetremoved', e => {
    console.log(e.stylesheet);
});
observer.observe(shadowRoot);
observer.observe(document);
@mayank99
Copy link

mayank99 commented Sep 30, 2024

Would it make sense to observe a StyleSheetList instead of a node (Document or ShadowRoot)?

const observer = new StyleSheetObserver();
observer.observe(document.styleSheets);
observer.observe(document.adoptedStyleSheets);
observer.observe(shadowRoot.adoptedStyleSheets);

A related point that I mentioned in w3c/csswg-drafts#10013, but is also worth repeating here. One of the main use-cases for observing stylesheets is to keep stylesheets synced between document and a shadowRoot. From an author perspective, it would be nice if we could just do this:

shadowRoot.adoptedStyleSheets.push(document.styleSheets);

Since document.styleSheets is a stable StyleSheetList reference, the browser could internally observe changes to it and automatically keep it in sync, without requiring authors to wire up the logic manually.

For other, more advanced cases, StyleSheetObserver could still be useful.

@Westbrook
Copy link
Collaborator

This feels like a missing piece to user land APIs for "open-stylable shadow roots"...

Does "observing" or a "live list" feel more natural here? If we can setting on the same one feeling more natural, it would serve to see an explainer/proposal brought to life on this so we could share it with the appropriate working groups.

Here's a link to the most recent one in our repo, as a start.

@keithamus
Copy link
Collaborator

I'm not sure the use cases warrant a sophisticated observer object like StyleSheetObserver, so one way we could solve this is to dispatch an event on the document or shadowroot whenever adoptedStyleSheets or stylesheets is changed. So for example:

document.addEventListener('stylesheetschanged', e => {
  console.log(document.styleSheets);
});
document.addEventListener('adoptedstylesheetschanged', e => {
    console.log(document.adoptedStyleSheets);
});
document.querySelector('my-element').shadowRoot.addEventListener('stylesheetschanged', e => {
  console.log(e.target.styleSheets);
});
document.querySelector('my-element').shadowRootaddEventListener('adoptedstylesheetschanged', e => {
    console.log(e.target.adoptedStyleSheets);
});

There are some tricky timing bits here though:

  • We'd probably need to queue an event for this, which means it would be Task timings (think setTimeout(..., 0). This would be a longer timing than a supposed StylesheetObserver which would probably borrow mutation timing.
  • adoptedStyleSheets wouldn't need to use a queued task but having different timing to styleSheets would be weird.

@bahrus
Copy link
Author

bahrus commented Feb 1, 2025

I'm not sure the use cases warrant a sophisticated observer object like StyleSheetObserver

The only benefits of a special observer class as proposed that I see are:

  1. If we want the ability to finesse how the observing should take place, including any filtering abilities that may become available, that could be better handled in the low level code
  2. Be able to specify to include monitoring for CSS rules adjusted via JavaScript via a single unified API.

But I think even if such needs become pressing in the future, we could add that on (a StyleSheetObserver).

The simplicity of the suggested alternative I think not only makes sense from the "baby steps" point of view, but even from a developer point of view, it is a simpler API, so if none of that finessing is needed, providing the developer a shorter path to what they need would always be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants