-
Notifications
You must be signed in to change notification settings - Fork 688
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-position] Events for stickiness changes #1660
Comments
Agreed 100%. If a pseudoclass isn't feasible (and I agree it isn't for the reason Tab stated), there should still be some way of knowing. |
Couldn't you use an IntersectionObserver, narrowing your viewport to the area where the element will end up stuck (either top or bottom of the screen)? |
I tried, and was not able to use |
Seems like a bug. Do you have a test case? That would be super valuable! |
Unfortunately, i deleted the buggy code. So i tried to replicate the issue in a simpler setup, but then it actually worked! So maybe the bug is more specific than I thought, or maybe I simply made an error in my original code. I am sorry that I can't be of more help than that. The good part about this is that we can use it. And I am actually using it on a new small project. It's a slightly more advanced implementation, but if anyone wants to use it in their projects, they are very welcome to take a look at it here: [broken link]. |
Great to see that it's actually working for you! |
Agenda+ to close as NoChange if no one else has a strong opinion on this |
While the Sebastian |
The Working Group just discussed
The full IRC log of that discussion<dael> Topic: Events for stickiness changes<dael> github: https://github.com//issues/1660 <dael> Rossen_: Summary, issue is someone asked if we can have an event to be able to know when the element goes into a stuck state and if it transitions to unstuck. <dael> Rossen_: There were a few suggestions given, fremy pointed out if you use intersection observer everything works. After a little while people confirmed this is the case. They proposed to close no change. <dael> Rossen_: I want to hear if you agree with this. <dael> smfr: I agree <dael> Rossen_: Objections to close, no change? <dael> RESOLVED: Close issue 1660 no change. |
Unfortunately my comment was not addressed in the discussion. Could this be reconsidered? Sebastian |
I completely agree with @SebastianZ that using the And since this issue is very directly linked to any native sticky headline, i think something should be done to make a more native solution. |
I would say that I'm also for the native stickiness events and against using hacks or any non-trivial code for that. More than that, I also totally disagree with any arguments against the |
@kizu Regarding |
I'd start with whitelisting a certain set of properties that are guaranteed to be safe, that would allow developers to achieve most of the use cases for sticky elements (the changes in background, shadow etc.). CSS already has a similar mechanism for stuff like After that it would be possible to start thinking on more complex cases. But I'd say that instead of thinking about this particular pseudoclass and properties, it would be better to start thinking on how to fix the circularity/loops issue for the whole CSS. Its frustrating that so many must-needed for devs things like the .foo { toggle-states: 2; toggle-initial: 1; } /* makes it checked */
:checked { position: sticky; }
:stuck { toggle-states: none; } here we apply everything in the specificity order and at the moment something would create a contradiction, it just wouldn't be applied. So, in that case, the But even if that would be hard to implement, we still could at first allow the safe cases that would allow people to do stuff much easier already. That would so much more helpful than just discarding ideas completely. Upd: And another possible solution (if there are fears of using the selector like |
Yeah, I agree, @tabatkins, myself and so many others in the csswg really just haven't thought about this nearly enough, and that's why we have not found the obvious solution yet. All this time, the solution was to detect the problematic declarations and remove them. If we remove declarations one by one, we would eventually reach a stable layout in only 🙄 All the real-word usages of |
Previously posted from the wrong account, sorry I get that :stuck is problematic and it doesn't sound like things around selectors and infinite loops are about to change, so I'd like to add my support to what Chris has offered here - JS events would allow a very quick and simple workaround for devs, and hopefully won't be hard to implement. Pulling the Roman stressed that lots of times we just want to alter shadows, color etc. - Mix the browser support of sticky and IntersectionObserver and the code required and you get too much trouble to even touch the standard, I know I'd revert to scroll listeners, and it's a shame. Thanks for considering this and reading through. |
Wow, then we live in two entirely different worlds: I both saw and implemented myself in my practice a lot of sticky cases where the layout didn't change (or wasn't the most important part). The most common thing in a lot of projects I worked on was just adding a shadow and a solid background to make the sticky part visually distinctive from the content beneath. And anyway, if we'd add just a limited amount of supported properties, then, of course, the design possibilities of that subset would be smaller than what would be possible with all the properties supported. But that does not means in any way that those that can be implemented would be useless. Both developers and designers would find ways to use it in the most efficient way, and if there'd be also proper events for hacking around the layout changes, then more complex cases would be possible too. What I'm saying is that we don't need to have everything at once. I'm sure that most of the developers would be happy with just repaint-only styles available at the start instead of nothing. |
Going back to the other thread and Tab's comment 'wide' and 'tight' loops. it seems like the distinguishing factor is that because it's based on user interaction, the properties from :hover don't get applied until after the user interaction phase (where the page has been fully rendered). Wouldn't it be possible to just mimic this behaviour even if the specific pseudo selector wasn't dependent on user interaction? So basically just wait until everything is rendered, then compute whatever is in the :stuck declaration? Obviously the endless loop would still be there, but would this make it function just like :hover loop? |
While that is definitely better, we don't actually want to repeat the problems that :hover has. They're still bad, they just weren't killer, so we were able to live with them. |
I've cloned the most common usage of sticky header in my own way. I had to use 2 indicators with 2 Observer. Summary: I still vote to the :stuck pseudo, because this code is not my favorite, however works: https://jsfiddle.net/utasir/92L8L85q/12/ If someone knows how to make it simpler, I'll appreciate that. Actually my problem with my code if it is against the separation theory of style and html structure. I've reduced the code to 1 indicator only, but now no reverse animation effect. I think this the max we can do for it with intersectionObserver. Other stuff is: position sticky element has reserved space int he flowed content, so resize made a layout jump. Workaround adding a margin-bottom to :stuck styled header. |
So to summarize;
Why is #2 undesirable vs. having us infer that same thing in an indirect way? |
Sure you can use JS+DOM hacks (based on IntersectionObserver) to figure out when something started to stuck. The exact same argument could be given for position:sticky itself. Plenty of websites implement(ed) it with JS+DOM hacks. And yet, browsers decided to support position:sticky natively to make it more convenient, less hacky, and more robust. Does anyone have any better argument against the proposal in this issue than "it can be done with JS+DOM hacks"? Or at least one that is consistent with the decision to implement position:sticky in the first place? |
There is a comprehensive explanation about why |
It seems people have been aware of the FAQ item. Sorry for the noise. For the proposal in the issue itself, the event approach, I don't think that's infeasible. |
Thought about it a bit more, I guess even if we want something more convenient to get notified from stuck / unstuck, that's probably better also be an observer-like thing, rather than an event. I don't think we want to add more event into the layout pipeline, since event needs to be synchronous, which makes it easier to slow down pages, and it doesn't seem to me that the usecase here requires being synchronous. So using an asynchronous observer mechanism should be preferred over events. |
On the other hand, it seems adding one observer type for each thing we want to listen to feels heavier than adding an event, where we can just share the whole mechanism. Maybe we should invent a new LayoutObserver-ish thing and design an API similar to the event listener, but make it async. That way we can add new observing type easily. Some of the existing events can probably also be added there for performance etc. (Maybe there has been some idea like this proposed in WICG?) |
Re And I never heard any arguments why white-listing properties can't be used. There is a finite amount of properties that are used in most of the use cases for the Whitelisting some of the properties would be enough for start, and then we could start to think about the proper global solution for any circularity issues. |
Thanks for the details @upsuper What exactly happens when a layout event fires that slows down pages? Is it that the layout algorithm gets blocked until the event handler completes? I thought that event handlers had to run in tasks within the event loop, independently of the layout code of the browser. Or is this an implementation detail of some particular browser? |
I don't really get how does intersectionObserver with How to read |
Oh, I think I got it - minus means inwards, shrink bounding rectangle inwards.. But that doesn't work when sticky element is the very first inside it's root, and it has |
Hack with adding sentinel elements to the top and the bottom of the scrolling root like this one has limitations. In general this way adds cumbersome code and difficulties for other team member to reason about it. |
There is a problem with sentinel elements when we use |
IntersectionObserver is also non-compatible with IE. So any implementation with it will not be backward compatible with the relic browser. |
@tayloraucoin true, but any new spec also won't be compatible, and IE doesn't have support for the sticky position anyways. |
https://drafts.csswg.org/css-position/#sticky-pos
Since the suggestion in #1656 for a
:stuck
pseudo-class is not feasible, the next best alternative would be for browsers to fire events (e.g.stuck
,unstuck
), similar to those of CSS Transitions, whenever aposition: sticky;
element changes its stuckedness. Then the same styling abilities become possible at the cost of a teeny bit of JS and a teeny associated processing delay:For robustness, the relevant event also needs to be fired when the element changes between the
posititon: <anything but sticky>
and (position:sticky
-and-currently-stuck) states.The text was updated successfully, but these errors were encountered: