A theoretically simple solution would be to simply invalidate position declarations inside rules where the selector subject includes the :stuck pseudo-class, but of course that might have issues in practice. AFAIK no other selectors impose restrictions on which declarations are valid.
I need to write a blog post for this, since I keep having to bring it up, but that doesn’t work. As soon as there is more than one instance of this kind of circularity, you can loop them together and run into the same problem:
:based-on-a {
b: on;
}
:based-on-b {
a: off;
}
No direct circularity - the rule with :based-on-a doesn’t contain the a property, and same for b, but the exact same loop nonetheless. You have to outlaw all selector-affected properties from appearing in rules using any property-affected selectors, which quickly starts wiping out large swathes of CSS and renders the whole thing useless.
Well @tabatkins the reason I’d say sticky over stuck is:
We have already position: sticky; Which were familiar with so no need of a different word
I’m kind of comparing to :active and :hover
The word :hover in future tense. Instead of past tense :hovered, meaning :stuck is like past tense. Now active because it’s the word active it could be used:
When it was active, when it’s active, it is active.
So yea idk what you wanna do we could use stuck which makes sense but we could also use sticky and not have two words sticky for position: sticky; and :stuck for the pseudo class
I disagree. If we’d allow only those properties that don’t affect layout to be redefined for the :stuck pseudoclass, we’ll get infinitely more control over what we have now (nothing).
And those properties that don’t affect layout are those that are used for sticky elements in real world use cases. I guess the most popular property to redefine on the stuck state would be a box-shadow.
The layout-changing properties could be useful too, but why can’t we go iteratively and allow just a subset of properties from the start, and think out the solutions to enhance it later?
Developers need position sticky already and need this pseudoclass for them too, saying “there are issues, so you won’t get it in any form” is not productive.
I’m having flashbacks to Web Pages for Dummies where they warn against using font-size for a:hover for this exact reason. Is it still an unsolved problem?
That’s not sufficient; or rather, it’s only sufficient once. As soon as you add a second selector linked to properties, even if relies on a disjoint set of properties, you can force a circularity by having :A set the B property, and have :B respond to that and set the A property. You have to exclude all properties that affect selectors from being used in a style rule using any selector affected by properties. That quickly rules out most/all of CSS, and requires breaking old content that (correctly at the time) used some property that affects the new selector.
The right thing is to just avoid the problem. Find tricksy ways to make it not screw with things, or just leave it and use JS.
No. :hover-based loops are “wide” - they start at style computation, move through layout and rendering, and get all the way to user interaction before they loop back around. The entire page is “done” by the time the loop spins around, so, while the flicker is annoying, it doesn’t prevent the rest of the page from working.
These kinds of property/selector loops are “tight” - they start and end within style computation, and prevent the browser from moving on to layout/rendering/etc at all.
How this (or any other external styles) could trigger any kind of circularity there? What do I miss?
Also, there is no way to avoid this using CSS only, and it far from trivial when trying to emulate using JS (btw, would there be/are there already any events in JS to tell when the element become stuck or not?).
Again, the issue is that we can’t ever introduce a second selector that’s affected by properties. (And we can’t ever add a layout-affecting value to one of the “safe” properties.)
Something that we can only do once, ever, and that will affect our ability to evolve CSS in the future, is probably a bad idea for the language.
we can’t ever introduce a second selector that’s affected by properties
I still think this could be handled in some way (like using only one pass (I don’t remember how this mechanism is called now), as we already do for fit-to-content blocks with more than one line). This looks like “this is hard, we won’t ever try”.
we can’t ever add a layout-affecting value to one of the “safe” properties.
We can, if we’d make those values not to work in this context.
All of the solutions I can think of start getting into procedural territory, and I doubt that’s a road the CSSWG wants to go down. Unless we can mark a declaration as “nonvital” or something, and even then I’m not sure that would actually accomplish the right thing.
What if :sticky selects elements which are within a position: sticky element that has been stuck, but does not match the position: sticky element itself?
If the main problem is creating tight loops, instead of a CSS class, we could have events. For example:
Element.onEnterSticky
Element.onLeaveSticky
Now javascript code can still create loops, but wide ones, that don’t block the style computation.
Adding and removing CSS classes on the event handlers would be trivial. Much simpler and therefore less error prone than the alternative of computing manually whether the element is stuck or not.
I’m wondering if we could perhaps also allow :stuck in the JS profile for use with querySelector. This wouldn’t have the tight loop issues of allowing it in a stylesheet and there’s precedent for allowing selectors in the JS only profile already (:matches() I believe).