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

:host(.foo, .bar) is styled differently in synthetic shadow and scoped light DOM vs native shadow #3225

Open
nolanlawson opened this issue Dec 15, 2022 · 3 comments
Labels
BUG P3 light-dom This label represents any issue that relates to the feature of Light DOM Synthetic Shadow Synthetic shadow DOM polyfill

Comments

@nolanlawson
Copy link
Collaborator

nolanlawson commented Dec 15, 2022

Consider this CSS:

:host(.foo, .bar) {
  color: red;
}

In Chrome and Firefox, this will render the text as red in synthetic shadow:

Screen Shot 2022-12-15 at 11 49 58 AM

But not in native shadow:

Screen Shot 2022-12-15 at 11 50 05 AM

That's because :host() actually accepts a compound selector, not a selector list. So :host(.foo, .bar) is an invalid selector.

Unfortunately, in the style compiler, we treat it as valid and convert it into a new selector (which really is valid):

/* output css */
[x-app_app-host].foo, [x-app_app-host].bar {
  color: red;
}

Here is the code that does that:

const contextualSelectors = hostNode.nodes.map((contextSelectors) => {
const clonedSelector = selector.clone({}) as Selector;
const clonedHostNode = clonedSelector.at(hostIndex) as Tag;
// Add to the compound selector previously containing the :host pseudo class
// the contextual selectors.
(contextSelectors as Selector).each((node) => {
trimNodeWhitespaces(node);
clonedSelector.insertAfter(clonedHostNode, node);
});
return clonedSelector;
});

In Safari the behavior is different, but I believe that may be a bug, so I filed a bug on WebKit.

@git2gus
Copy link

git2gus bot commented Dec 15, 2022

This issue has been linked to a new work item: W-12228170

@nolanlawson
Copy link
Collaborator Author

This also applies to scoped styles in light DOM, since we transform the :host() in that case using the same system we use for synthetic shadow.

@nolanlawson nolanlawson changed the title :host(.foo, .bar) is styled differently in synthetic vs native shadow :host(.foo, .bar) is styled differently in synthetic/scoped vs native shadow Dec 15, 2022
@nolanlawson nolanlawson changed the title :host(.foo, .bar) is styled differently in synthetic/scoped vs native shadow :host(.foo, .bar) is styled differently in synthetic shadow and scoped light DOM vs native shadow Dec 15, 2022
@nolanlawson
Copy link
Collaborator Author

There are actually some more buggy cases I found:

  • :host(*) is a valid selector, but synthetic compiles it to [x-host]*, which is invalid (should be *[x-host])
  • :host() is an invalid selector and fails in native shadow, but synthetic compiles it to [x-host] which works
  • :host(:host) is a valid selector in native shadow, but synthetic compiles it to [x-host]:host which doesn't work in synthetic shadow

@nolanlawson nolanlawson changed the title :host(.foo, .bar) is styled differently in synthetic shadow and scoped light DOM vs native shadow :host(.foo, .bar) is styled differently in synthetic shadow and scoped light DOM vs native shadow Mar 1, 2023
@nolanlawson nolanlawson added Synthetic Shadow Synthetic shadow DOM polyfill light-dom This label represents any issue that relates to the feature of Light DOM labels Mar 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BUG P3 light-dom This label represents any issue that relates to the feature of Light DOM Synthetic Shadow Synthetic shadow DOM polyfill
Projects
None yet
Development

No branches or pull requests

1 participant