w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.5k stars 665 forks source link

Simply sharing external stylesheets between DOM and Shadow DOMs #8112

Open mangelozzi opened 1 year ago

mangelozzi commented 1 year ago

This is a proposal.

Native Web components with the shadowRoot are a fantastic feature for encapsulation. Although some styles one wishes to encapsulate, there are some styles one would like to pierce the shadow DOM.

I have a shared external CSS stylesheet to ensure a constant look/feel of all components. I use an external stylesheet in my component, unfortunately that means every stamped out component must re-download the stylesheet. Say I have 3 x <my-button>, and 20 x <my-link> on a page, that means the stylesheet will be downloaded/parsed once for the main page, 3 times for the buttons, and 20 times for the links, a total of 24 times.

I have looked into constructable style sheets, but I don't think its as simple/perfomant as something like this (not proposing exactly this, just the concept, similar syntax to @layer):

@pierce {
   /* These styles apply to the usual DOM and pierce the shadow DOM */
  * {
      border-width: 2px;
  }
}

Some of my thoughts/assumptions about it:

Any thoughts on the matter?

tabatkins commented 1 year ago

The "multiple downloads" thing isn't problematic if you use appropriate caching headers - only the first request will actually download, and the rest will fetch from cache. (You'll want to do this anyway, so repeated visits to your page don't trigger unneeded downloads.)

Additionally, browsers have internal heuristics for avoiding repeated parsing work when given the same stylesheet multiple times, and definitely apply it in cases like this. (If you use an inline style element in your shadows, for example, it'll only get parsed the first time, and the result reused for later components. I think they even literally share the stylesheet object with copy-on-write semantics.)

That previous paragraph is heuristic, tho; if you want to ensure a single download and parse, yeah, using constructable stylesheets is currently the way to go.