mayank99 / open-styleable

experimental server+client "polyfill" for openly styling shadow-roots
https://open-styleable.mynk.app/
MIT License
2 stars 1 forks source link

[polyfill] how to handle implicitly `@scope`d light DOM styles? #4

Open mayank99 opened 6 months ago

mayank99 commented 6 months ago

Preludeless @scope only makes sense when used inline with the markup that is being styled. But currently it will also be applied to shadow-roots.

<body>
  <div>
    <style>
      @scope {
        p { color: hotpink; }
      }
    </style>

    <p>This will be hotpink (yay!)</p>
  </div>

  <my-component>
    <template shadowrootmode="open" adopthoststyles>
      <p>This will also be hotpink (oh no!)</p>
    </template>
  </my-component>
</body>

Maybe only <head> styles should be adopted into shadow-roots? But that could be risky if there are any useful styles in <body>.

(Personally I think the correct answer is to bring back <style scoped>)

bkardell commented 6 months ago

Can you explain how scoped fits in/helps here?

mayank99 commented 6 months ago

Assuming you're asking how <style scoped> helps, it helps by making the intent clear at the HTML level. The exact syntax is not important, it could even be something like <style type="scoped">.

A <style> tag can contain any arbitrary CSS, including multiple @scopes, some of which may be applicable for shadow-roots and others not so much. Whereas an HTML attribute has zero ambiguity: "This entire style tag belongs to this DOM element, regardless of what CSS rules it contains."

That being said, maybe I shouldn't be thinking from a polyfill perspective. If the browser can manage to resolve the ambiguity in a performant way, then I'm perfectly content with the polyfill needing to do extra work.

There is also a cool potential pattern here, where implicit @scope can be used to specify styles for both light DOM and shadow DOM within an element.

<my-component>
  <style>
    @scope {
      p { color: hotpink; }
    }
  </style>
  <template shadowrootmode="open" adopthoststyles>
    <p>hotpink</p>
    <slot></slot>
  </template>

  <p>hotpink</p>
</my-component>

<div>
  <template shadowrootmode="open" adopthoststyles>
    <p>not hotpink</p>
    <slot></slot>
  </template>

  <p>not hotpink</p>
</div>
mayank99 commented 6 months ago

Actually, i thought about this more and tested it too. Implicit @scope should not be a problem in practice, because it has no meaning when used in a .css file. It only does something when used in a <style> tag inside a DOM element (including DSD templates).

So while it is currently a problem to be fixed in the HTML transform (because it copies <style> tags), it should be totally fine in the platform because it would be copied into an adopted stylesheet instead.

bkardell commented 5 months ago

So you are saying you want to keep this open but not about the ultimate proposal, just about the script/transform/polyfill or something? Maybe it would be helpful to try to add a [category] in the subject to make that clear? You could also use labels, but it's less clear imo at a scan