Csswg-drafts: [css-scoping-1] Dynamic changes of state and attributes referenced by :host-context rules are pretty hard to handle efficiently.

Created on 28 Oct 2017  路  10Comments  路  Source: w3c/csswg-drafts

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...

css-scoping-1 shadow

Most helpful comment

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.

All 10 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 https://github.com/w3c/csswg-drafts/issues/1915#issuecomment-467590316 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.

Added separate use counters for live and snapshot profiles in Chromium M75.

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.
<html class="darktheme dir="rtl">...</html>
:host-context(".darktheme") <selector> { /*make it dark*/ } :host-context([dir="rtl"]) { /invert the margin for sides, etc./ }
Beyond that, it would be nice to be able to sandbox a theme or text direction somewhere inside the body of a page, similar to what using an iframe can give you.

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 <html>, <body>, or the <shadowHostElement>. Introducing a limited implementation will go much farther in identifying usage numbers than simply checking how many people use it in Chrome today, because in professional sites browser support heavily impacts usage of any features - especially if it's not possible to polyfill them (please provide a polyfill if one exists but I've found none). This would eliminate the need to search the entire domTree for a valid selector in favor of a few targeted look ups.

The directionality use case is best served by :dir pseudo selector. The dark theme case is best served via CSS custom variables. Note there is no guarantee that your component isn't used where the theme is defined so :host-context is awfully unsuited for theming purposes.

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 -- :host-context([dir=rtl]) means "any ancestor with dir == 'rtl' above, even if that's not the effective directionality[1]" (which is why :dir exists). I get that it's better than nothing, but it's not bulletproof (and you can use a CSS var instead).

re: theming -- i think recent @media (prefers-color-scheme: light/dark) {...} is fine to embed inside of a component such that it adapts to system UI theme. I think you're able to specify your own themes as well, but it generally reduces the generic nature of web components the more you make them aware of their housing/surroundings. it's better to expose "parts" which can be styled externally, IMO.

[1] it'd be easy for a closer [dir="ltr"] ancestor to be ignored, as would be a direction: rule in CSS.

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.

Was this page helpful?
0 / 5 - 0 ratings