-
Notifications
You must be signed in to change notification settings - Fork 689
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
[css-scoping-1] Dynamic changes of state and attributes referenced by :host-context rules are pretty hard to handle efficiently. #1914
Comments
FWIW, this was discussed in the F2F, and the conclusion was that Blink will add counters and try to drop it, and that we should get feedback from other Apple people more familiar with Shadow DOM. I guess given #3699 the second part is already there, and given it only has support from one implementation it doesn't really have a good reason to be in the spec. |
Ah, apparently the IRC logs went to #1915 (comment) instead of here. |
Anyhow, I'm in favor of dropping it. |
To repeat myself once again, Apple's WebKit team doesn't think changing the style of an element based on where it appears is a good practice to design a re-usable element in general, and this particular feature poses a significant implementation complexity & cost as pointed out by @emilio. Support dropping this feature from the specification as we've previously requested. |
Adding use counters for both snapshot and live in case we can remove from one profile and not the other. This was discussed at a CSSWG F2F. See [1]. [1] w3c/csswg-drafts#1914 Bug: 936225 Change-Id: Ide3cd3991026a350711beca225da4a49a532e952 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1508456 Commit-Queue: Rune Lillesveen <futhark@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/master@{#639469}
Added separate use counters for live and snapshot profiles in Chromium M75. |
Adding use counters for both snapshot and live in case we can remove from one profile and not the other. This was discussed at a CSSWG F2F. See [1]. [1] w3c/csswg-drafts#1914 Bug: 936225 Change-Id: Ide3cd3991026a350711beca225da4a49a532e952 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1508456 Commit-Queue: Rune Lillesveen <futhark@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#639469} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: f05f986577028beff63900afab89704c5441aca3
2 use cases I'd like to suggest this supports is high level theming of a suite of components, and high level right-to-left or left-to-right localization detection. The most basic example would be setting text-direction or a theme on the html element. I'd advocate that a performant implementation of this selector could be viable if we limit the legal parents this could go on. For example, it could be limited to |
The directionality use case is best served by |
A lot of its use cases could be replaced more efficiently by having a pseudo-class which tests whether an inherited (to avoid cycles) variable has a particular value. |
I agree with @rniwa on this specific matter -- re: theming -- i think recent [1] it'd be easy for a closer [dir="ltr"] ancestor to be ignored, as would be a |
Is there anything blocking this being removed from the spec? Given that Gecko and WebKit don't intend to implement, I don't think there's a path forward for this. |
Directionality and theming given as examples above are special cases, which have dedicated support in CSS (pseudo-selector and variables) already. But what would you suggest for specialising a style of a web component depending on its ancestor when both web components are in a single library? This has been addressed by cascading before Shadow DOM and ExampleLet us have three levels of heading (block) elements: <e-h1>Heading 1</e-h1>
<e-h2>Heading 2</e-h2>
<e-h3>Heading 3</e-h3> Styled by following stylesheets in their shadow roots: /* e-h1, e-h2 and e-h3 */
:host {
display: block;
line-height: 1.2;
margin: 0.75rem 0.5rem;
font-weight: 500;
}
:host { font-size: 1.9rem } /* e-h1 only */
:host { font-size: 1.6rem } /* e-h2 only */
:host { font-size: 1.3rem } /* e-h3 only */ And rendered like this: Then, let us have an inline element for a small text: <p>This is a normal text. <e-small>This is a small text.</e-smalll></p> Styled by following stylesheet in its shadow root: :host { font-size: 0.75em } /* e-small */ And rendered like this: Finally, let us have a subheading for each of the three levels of heading elements, implemented by specialising the small-text element: <e-h1>Heading 1 <e-small>Subheading</e-small></e-h1>
<e-h2>Heading 2 <e-small>Subheading</e-small></e-h2>
<e-h3>Heading 3 <e-small>Subheading</e-small></e-h3> Styled by adding the following styles to its shadow root: /* e-small */
:host { font-size: 0.75em }
:host-context(e-h1), :host-context(e-h2), :host-context(e-h3) {
display: block;
margin-top: -0.25rem;
} And rendered like this: AlternativesIf Dedicated ElementsInstead of overriding the style for a specific ancestor, dedicated descendants can be introduced, for example: <e-h1>Heading 1 <e-sub-h1>Subheading</e-sub-h1></e-h1>
<e-h2>Heading 2 <e-sub-h2>Subheading</e-sub-h2></e-h2>
<e-h3>Heading 3 <e-sub-h3>Subheading</e-sub-h3></e-h3> Increases the web component count unnecessarily, because Additional AttributesInstead of overriding the style for a specific ancestor, the specifics can be represented by attributes, for example: <e-h1>Heading 1 <e-small heading=1>Subheading</e-small></e-h1>
<e-h2>Heading 2 <e-small heading=2>Subheading</e-small></e-h2>
<e-h3>Heading 3 <e-small heading=3>Subheading</e-small></e-h3> Increases the verbosity unnecessarily, because Extra StylesheetInstead of overriding the style for a specific ancestor, the style override can be applied from the outer document, if it affects only the host element for example: <e-h1>Heading 1 <e-small>Subheading</e-small></e-h1>
<e-h2>Heading 2 <e-small>Subheading</e-small></e-h2>
<e-h3>Heading 3 <e-small>Subheading</e-small></e-h3> e-h1 e-small, e-h2 e-small, e-h3 e-small {
display: block;
margin-top: -0.25rem;
} Unexpected, requiring a global stylesheet to be imported in addition to the encapsulated stylesheets within the web components. |
Seconding @prantlf, the use case of styling a component descendants based on the parent is a pretty big one. If it's only one level you can use E.g. suppose you have |
I think However, in the intervening years, CSS at large has attained a componentization pattern that mimics this in the form of complex Thinking in this way, @prantlf's example might look like the following: https://codepen.io/Westbrook/pen/wvqWJrK
As opposed to the similar no custom elements approach which is possible today via: https://codepen.io/Westbrook/pen/YzxWZjb
I'd really like to see |
If the host and the elements in nested trees are coordinated (as in both the "chart" and the "subheading" use cases) the outer component can definitely pass the relevant information to the inner components, right? Or what am I missing? For the first example in thread it would look like: --sub-heading-display: {inline, block};
--sub-heading-margin: <something>; On the heading elements, then |
Also, in that case, the |
@emilio Definitely a fair point and in a design system it would make sense for the authors to make a sharable "context" between nested components. The downside is that you're recreating CSS cascading in javascript. Components would be required to tie into a shared context/provider API. For example, our color context in Patternfly Elements. Our components are responsible for telling child components what background context they reside on. We do this by providers adding the <pfe-band color="dark">
<section>
<pfe-clipboard on="dark"></pfe-clipboard>
</section>
</pfe-band> pfe-clipboard.css :host([on="dark"]) {
--pfe-clipboard--icon--Color: #fff;
--pfe-clipboard--icon--Color--hover: #fafafa;
} If pfe-clipboard had access to the parent context, it would eliminate the need for a proprietary context provider/consumer. We could target a parent attributes and inherit all of the cascading goodness: pfe-clipboard.css :host-context([color="dark"]) {
--pfe-clipboard--icon--Color: #fff};
--pfe-clipboard--icon--Color--hover: #fafafa;
} |
These are not always about setting the same property to different values, but one may need to set entirely different properties. I suppose you could pass down values for the union of all properties that may need to be set, but it gets awkward fast, and if you have multiple interesecting variations you could get a combinatorial explosion. |
What happens when the parent element cannot be informed about the child element? In the case of the In the case that this sort of location based property setting was customizable, documenting a Custom Property for a consumer to leverage could definitely be a possibility, but if it were meant to only be enumerable (possessing a fixed number of values) then documenting a class or |
This would indeed be valuable. Has there been any consensus and progress on this? |
Another solution to replace host-context maybe Browsers:
|
@woody-li I was indeed able to implement a dark mode scenario (i needed to manually enable dark/light mode in a Shadow DOM based component) using container style queries, by adding a CSS variable to an ancestor. This removed a need for However the lack of support of other vendors is somewhat worrying. |
Agenda+ to discuss removing this from the spec, given opposition from Gecko and WebKit and the potential for style queries to address the use cases. |
In particular, there's no way to look into which shadow host is affected by a host-context selector without actually going through all the descendant shadow hosts of the element where the change is detected (and that'd be slow).
Blink supports this correctly restyling the whole subtree, link below, but I think that's pretty unfortunate, because that means that every change to any class, attribute, or any other state referenced in a host-context selector needs to do very expensive work that would otherwise be unnecessarily.
Additionally, you need to store the host-context rules out of band (outside of the shadow host style), because of the same reason, which is also not great, I think. This means that stylesheet data in shadow trees is no longer self-contained.
I was looking into implementing this (and other bits of Shadow DOM / CSS scoping) in Gecko, and I'm not opposed to taking the same approach, but I'm not sure if this is intentional or not, and I'd want it to discuss it before...
The text was updated successfully, but these errors were encountered: