Jss: Support shadow roots as insertion points

Created on 17 Jul 2017  路  15Comments  路  Source: cssinjs/jss

Right now setting insertionPoint in options to a Shadow Root results in:

Warning: [JSS] Insertion point is not in the DOM.

See https://www.webpackbin.com/bins/-KpFbaOYG0kxqHAob_lP for replication (open the actual browser console and you should see it logged)

I think it's this line as a Shadow Root doesn't have a parent node.

IMO it'd be great to have the Shadow Root as an option for an insertionPoint, and just append it / prepend it in the top level of that shadow root?

feature request

Most helpful comment

That's fair enough - you're right, for me this is purely experimentation, and I agree I'm not sure if there's a use case for JSS in Shadow Roots.

Understand if you'd like to close this issue, I can come back and comment on it again when I think there's a production use case for JSS + Shadow DOM, and also with performance metrics / considerations.

All 15 comments

Huh, didn't know that an element inside of shadow root has no parent.

Ah you are using shadow root itself as an insertion point. Yeah you could use the first element inside. But yeah, its not optimal.

Using element option is fine though if you have just one style element. If we have real use case for having multiple style elements within one shadow root, we can add a container option, which is by default the head of the document and optionally can be a shadow root.

shadowRoot.isConnected seems to be the way to check if shadow root is in the DOM tree or not. But using it as an insertion point would result in style element inserted after the shadow root, not inside of it. We still would need a container option.

Thanks - yeah a container option sounds good 馃憤

But, as you say, using element works fine and I can't see a use case for having multiple stylesheets in the Shadow Root, but this is a relatively unexplored area so far anyway.

I think it would be interesting to see the performance overhead caused by shadow root.

Do you mean just attaching Shadow Roots in general? Or the performance of stylesheets inside Shadow Roots, particularly re: duplicating stylesheets across roots? If I can think of the right setup, I'd be happy to do some benchmarking.

Both, shadowRoot activation and also overhead when generating a sheet per element with shadowRoot vs reusing same sheet over global styles.

As of right now, I think this issue is all about an experiment and has no production application, so I am not even sure it is worth fixing. Especially considered that we have scoping in jss without using shadow root and we don't know any benefits of using shadow root for css besides of scoping.

That's fair enough - you're right, for me this is purely experimentation, and I agree I'm not sure if there's a use case for JSS in Shadow Roots.

Understand if you'd like to close this issue, I can come back and comment on it again when I think there's a production use case for JSS + Shadow DOM, and also with performance metrics / considerations.

no production application, so I am not even sure it is worth fixing

@kof I ran into this, for a production application. (PM me for WIP URL)

I am using react-shadow to wrap auto-generated SVGs (f.e. exported from illustrator or somewhere) in ShadowDOM roots for style encapsulation.

Otherwise the class names that these programs generate can cause name clashes, which destroy SVG rendering by cross-styling them with each other's <style>s.

But now that they are in Shadow roots, I can not use JSS-generated class names from the outside. :(


Basically, I want to wrap SVGs in shadow roots because it is easy to avoid name clashes that way, taking advantage of web standards without having to otherwise do a bunch of other work modifying the SVGs to not clash.

Then I want to be able to further style them from the outside.

I'm using react-jss. It would need to detect when a component is inside a shadow root somehow, then automatically inject style to that shadow root, not just global. Yes this sounds bad for performance, but in practice it will be fine in many cases.

You need to pass insertionPoint to every style sheet that you want to put into a specific shadow root.

I only have one JSS stylesheet normally, and I want to apply it to all roots.

The insertionPoint seems to map one sheet to one insertion point, so I'd have to create many JSS style sheets, one for each insertionPoint.

This could be a difficult if I'm using react-jss, as the JSS sheets are abstracted away and I'm using the decorator/HoC utility. Doesn't seem straight forward.

I think what I have to do is use insertRule on all of my ShadowDOM CSSStyleSheets, but if using react-jss I need to figure how to get the sheet made by injectSheet, and then get the CSSStyleSheet from it.

There are 2 options, one is implicit - rendering the same css string in every root and hoping the browser will be able to optimize it internally. Rumors say chrome is doing it.

Another is using the new api for constructable style sheet, which I haven't tried out, nor it is widely supported.

Support for Constructible Style Sheets landed in Chrome 73, and there are polyfills for it now too (the polyfills basically copy the style elements to the shadow roots, like the above idea, but triggered through use of the polyfilled adoptedStyleSheets API).

Can we re-visit this and think about how to make it easy to use JSS with adoptedStyleSheets?

EDIT: well, now that I think about it, I just need to assign my JSS style element to adoptedStyleSheets and we should be good to go. Let me experiment...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kof picture kof  路  6Comments

Telokis picture Telokis  路  3Comments

EugeneSnihovsky picture EugeneSnihovsky  路  4Comments

trusktr picture trusktr  路  6Comments

HenriBeck picture HenriBeck  路  4Comments