-
Notifications
You must be signed in to change notification settings - Fork 668
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-scroll-snap-1] Improve or clarify nested snap behaviors #9187
Comments
For the first issue, it seems like we should spec that there should be some friction in some way. E.g. maybe you have to be closer to the next snap point before it would be preferred over the end of the previous one? This would help make it easier to scroll to the end of a box / region that is larger than the scrollport without jumping to the next snap point. For the second part, I could see replacing the distance check with something like non-aligned scroll positions are only valid if there's not a visible snap region to snap to within the larger than the scrollport region. The goal is to conceptually divide the larger snap point into valid snap regions which are before and after inner snap points. |
I made a diagram to help discuss the behaviors: I think the expected behavior given this set of snap regions is the following:
I think that including range 3 and range 5 are a good idea to avoid accidental unreachable content within an element which was declared with scroll-snap-align. However, if the only reason for the gap between range 2 and range 4 is blank (e.g. maybe entirely due to margins on |
One other edge case to consider is what happens when the nested snap areas are not the full size of the viewport. I think that in these cases we may want to scale back the avoidance area of the ancestor snap by the inverse proportion the inner snap doesn't fill the viewport. This is to avoid situations where a small element could lead to a full page scroll to snap into view. E.g. You should be able to scroll such that x% of a scrollport is visible beyond the inner snap where x% = (100 - y)% with y% being the proportion of the scrollport the inner snap area covers. Probably with a minimum avoidance equivalent to the snappiness of proximity so that there still is a noticable snap point for the inner snap area. I've made a rough demo trying to show what this would look like by actually splitting up the outer snap area into smaller snap areas. |
The CSS Working Group just discussed The full IRC log of that discussion<fantasai> flackr: We've had many devs trying to use scroll-snap reach out to us regarding differen thing sthey're trying to build<fantasai> flackr: one common use case is nesting snap areas to have a large area you can scroll freely, and some mandatory areas <fantasai> flackr: paginated view within larger scroller <fantasai> flackr: the spec suggests that this should be supported <fantasai> flackr: but normative text doesn't explicitly define the expected outcome <fantasai> flackr: so wanted to get feedback on this proposal to add explicit text <fantasai> flackr: when yu're in overly large snap area, should avoid inter-snap areas <fantasai> flackr: this creates desired effect of screens within a larger snap area <fantasai> flackr: you either fully snap into view or avoid them <fantasai> flackr: so proposal for change <fantasai> flackr: a few cases to discuss, what do you do if those inter-snap areas aren't screen sized <fantasai> flackr: not want to introduce large jumps in scroll because of single-line snap area <fantasai> flackr: but I think we can define reasonable behaviors <fantasai> flackr: do we think this is reasonable to put in the spec? <fantasai> flackr: I can propose spec text, and have examples and diagrams <fantasai> Rossen_: Thanks for intro, indeed the diagrams in the issue and spec are making this very visual and easy to follow <fantasai> Rossen_: not seeing anyone in the queue, if interested in topic engage in issue and perhaps can return later |
The main resolution I'm looking for here is regarding overlapping / nested areas. I'd like to resolve that overflowing areas where a smaller nested snap area intersects the snap port should not allow snapping to the outer / larger area. In effect, the larger area is split into regions before and after the inner area. For inner areas smaller than the scrollport, we expand the before valid area by |
Looking at your example in #9187 (comment) I think the most sensible behavior might be to extend the snap areas for #b and #c to extend through to the next snap position. So you'd have one snap position at the top of #a, which allows scrolling freely to the top of #b. Then another position starting at the top of #b which scrolls freely to the top of #c. And a third one from the top of #c to the bottom of #a. |
I don't think that this will be what authors want if they have a long #a and short #b and #c (e.g. inline images or diagrams similar to my demo). It's asymmetric, coming from below there is only a snap effect on leaving the image but not entering it. Coming from above you snap on entering but not leaving. We could do this only when the gap between #b and #c is shorter than a scrollport but that would result in a strange change in behavior when content sizes are sometimes just below / just above one scrollport. |
The CSS Working Group just discussed
The full IRC log of that discussion<bramus> flackr: brought up a few weeks ago and got some comments<bramus> … situation right now is that if snap area b inside of snap area a, there is almost no effect as ??? is a valid snap position. <astearns> s/???/anywhere in a/ <bramus> … proposed to snap to inner element (b) or snap to position that avoids showing inner elem on the outer element <bramus> … there is a linked demo with example <astearns> ack fantasai <bramus> … this came up as best way to implement desired snap behavior that search was exploring, or some free scrolling on some region and than mandatory in nested sections <bramus> fantasai: if you end up snapping to margin in between things … which would not be … its a tricky situation but I am OK … <bramus> … I trust Rob with poking around at this. <bramus> … main concern if we are creating snap areas in segments in between child elements (eg margin) <bramus> flackr: agree and that is where more complicated part of proposal gets into it <bramus> … might need some better formulation <bramus> … there are situation where innner area should be necessary as well <bramus> … but i have same concern <bramus> fantasai: agree that inner area should be accessible <bramus> astearns: at moment spec say nothing about nested snap areas? <bramus> flackr: it says something but its not … <bramus> fantasai: it doesnt handle the interleaved case <bramus> … we dont say what happens when you have content in between snappable areas <bramus> flackr: so it sounds we are generally in favor but we need to define the edge conditions? <bramus> astearns: PROPOSED RESOLUTION: Better define this behavior when you have nested snap areas and children with interleaved content from the parent <bramus> … comments or concerns? <bramus> … objections? <bramus> RESOLVED: Better define this behavior when you have nested snap areas and children with interleaved content from the parent <bramus> astearns: given complexity of this, might be good to have explainer with these demos <bramus> flackr: yep |
I've updated the demo: The demo html now has examples of all of:
Also I've implemented snapping in javascript following the various strategies using the
All of the strategies provide a reasonable outcome, though there are some particularly interesting edge cases:
I have not (yet) implemented a strategy which switches behavior based on the size / contentfulness of the area. While this could let us have a single behavior that provides the best of both ideas 2/3 and 4, if implemented poorly (e.g. join previous area if size is less than some size) it could lead to subtle differences in behavior on the same site based on screen size. Perhaps it's possible for us to detect when the gap between two inner areas has meaningful content which would avoid the degenerate behavior of strategies 2/3. |
I added a new option which is a switch between the two behaviours (2 and 4):
@fantasai WDYT of going with this option 5? This is basically saying that you should have a separate snap are for the outer range if it's large enough to view without seeing any of the inner range. It's not great to have a size threshold as it will result in a flip of behavior at a particular size but I feel like the better experience for cases like the starting slide or inner diagrams is worth trying to support. Also the spec already has size dependent behavior:
This would be in line with that existing text. |
We probably also want to join with a subsequent inner range if the first section before the nested area is short. E.g. consider the following example: <style>
.outer, .inner {
scroll-snap-align: center;
}
.outer {
padding: 50px;
}
</style>
<div class=outer>
<div class=inner>
</div>
</div> It's probably not desirable to snap to the 50px of
|
@flackr Wrt your last example, suppose .outer had |
Wouldn't having two snap positions cause the gaps issue we're trying to avoid, or are gaps at the start / end special? If we want to preserve I could see an option 7, added to the demo: |
I've been trying out each of the examples over and over, really feeling them out for UX, and find option 7 to be the most natural feeling. Snapping on gaps that are smaller than the viewport isnt desirable and I like the conditional workaround Robert has laid out. Optimizes content visibility, is minimal and takes into account multiple viewport scenarios for proper responsive handling. |
The CSS Working Group just discussed
The full IRC log of that discussion<dael> flackr: Previously discussed this. Use case is when you have nested snap points want to respect inner ones as descrete stops that are separate.<dael> flackr: Previously suggest avoiding inner, but that mad tiny gaps. fantasai had alternate that joined inner with outer that follows. Had some concerns about asymmetrical <dael> flackr: Comprimise is when the gap between the inner snap areas is larger than viewport it's a discrete area you can snap to. When it's smaller it joins with previous inner snap area <TabAtkins> I haven't been able to experiment with this myself, but Adam has and likes flackr's suggestion, and it does sound pretty reasonable. <TabAtkins> So +1 <dael> flackr: Already have a condition for length between snap areas. And I think it satisfies both use cases. Made a demo page with all the various proposals. Adam tried it out and voted his support <dael> flackr: Hoping we can go with this. <dael> fantasai: Compare to scrollport or snapport? <dael> flackr: Snapport <dael> fantasai: Sounds like a good direction. Not sure how final we'll be until there's a prototype, but happy to go in this direction. Wondering if we want to spec it out now or spec as you could do this but it's technically undefined <dael> flackr: I'm in favor of spec out and pushing for this to be the direction. We already have browser differences. It feels like spec will bring more attention <astearns> +1 to specifying behavior <dael> fantasai: Yeah, I think we put algo in spec. Just if we should require or if it's an example <dael> florian: This will be fiddly, so we shouldld w write it with intent that it's normative so we get same behavior <dael> fantasai: Okay <dael> flackr: +1 <dael> astearns: I didn't read all the options <dael> flackr: I did make prototype so we can play with it <dael> astearns: Is it option 7 or option 7 plus other things? <dael> flackr: Just option 7 <dael> florian: I wouldn't be surprised if we have to revisit once people play with it, but until then this is areasonable to start <dael> astearns: Prop: Specify option 7 as normative behavior <dael> astearns: Obj? <dael> RESOLVED: Specify option 7 as normative behavior <dael> astearns: Thanks flackr for doing the demo and going through options |
Friction to leaving larger than viewport area
example 8 suggests that there should be some resistance when leaving a snap area larger than the viewport (e.g. from section 1 to section 2).
This seems like good behavior however it's not clear that it's specified by any normative behavior and it seems too easy on all browsers today to accidentally scroll into the next section.
Prefer descendant snap point when visible
example 9 suggests that the intention is to allow scrolling freely within larger sections while still snapping when smaller nested sections are encountered.
The normative text 5.2.2.,
I've created a page similar to example 9 from css-scroll-snap 5.2.2. Snapping Boxes that Overflow the Scrollport, where we have nested sections within section 2 at https://flackr.github.io/web-demos/css-scroll-snap/nested/sections.html
The second requirement seems like it may not correctly capture the intention - for example when scrolling within section 2 before we reach section 2.1 example 9 would suggest we should prefer either being before section 2.1 or snapped to section 2.1, however the spec text would suggest that since the distance between the previous snap point (section 1) and the subsequent snap point (section 2.1) is larger than the size of the viewport that we still consider arbitrary scroll within section 2 (with section 2.1 in view) to be snap aligned. Browsers indeed seem to not force snapping to section 2.1 until it's very near the top.
If my understanding of the spirit of the requirement is correct, I think that this body scroll snap region example (based on a developer request in crbug.com/1420439) resolves the developer issue by having the
<body>
(an ancestor of the mandatory scroll snap regions) also be a snap region.The text was updated successfully, but these errors were encountered: