Support for non-trivial CSS Selectors
devknoll opened this issue · 2 comments
The polyfill can't currently handle each and every non-trivial CSS selector it might encounter. For example, consider the following rule:
#foo[data-bar] + div {
container-type: inline-size;
}
Today, the polyfill is only guaranteed to correctly update this style when div
is added, removed, or changed. It should also be updated when, for example, #foo
is added, removed, or changed, or any siblings after #foo
are added/removed/changed. The challenge, however, is that there's no simple way to detect when specific CSS property changes anywhere in the tree.
This is a performance trade-off. This issue could be resolved by revalidating the entire DOM after every mutation, but this would likely be prohibitively expensive in today's browsers for non-trivial documents. One promising optimization may be to instead keep track of just the selectors that change the properties we're interested in (e.g. #foo[data-bar] + div
) and revalidate the delta of elements before and after the change.
Note: The CSS contain
property doesn't help us here, as this relates to how CSS properties affect different parts of the tree, not the selectors that apply them. Here, the CSS properties affect the tree correctly, the polyfill is just unable to react to all of those changes.
Note: It's not sufficient to just invalidate the parent of a changed element, because you could write e.g. #foo:has(> #bar) + div
. Invalidating all of the parents would be equivalent to invaliding the entire DOM.
Would the pattern of creating a MutationObserver
per controller be a viable option for solving this? That pattern seemingly works well in the ShadowRootController
but I am not sure if there are any potential limitations/performance concerns with that approach.
The problem is more that when e.g. #foo
changes, we don't currently know that the sibling div
could also be affected.
The approach of keeping track of the selectors that affect container
or writing-mode
properties is probably the way forward. In addition to helping removing this limitation, using it to filter the set of elements we compute the state for would improve performance quite a bit on lower-end devices.