-
Notifications
You must be signed in to change notification settings - Fork 756
Description
The proposed snap events and styling in css-scroll-snap-2 expose the concept of snapped targets. Today, the developer can tell which element a browser is "snapped to" by moving them and seeing which one re-snapping after layout changes follows. The spec says the following about multiple snap aligned elements:
If multiple boxes were snapped before and their snap positions no longer coincide, then if one of them is focused or targeted, the scroll container must re-snap to that one and otherwise which one to re-snap to is UA-defined. (The UA may, for example, track which element is snapped as layout shifts align and de-align the snap positions of other elements.)
TLDR,
- Outside of focus or a target, the specific snapped element is not defined.
- When you have focus and target it's not defined which one takes precedence.
- Doesn't say which axis alignment to prefer if there is a different target in each axis.
Bringing this back to exposing the snap target, we have a two options:
- Treat all elements which are visually aligned as snapped.
- Standardize and expose the actually selected snap area in each axis.
Option 1 is relatively simple to understand, though requires extra work to compute (as it's not what's tracked internally) and may not be very useful. E.g. imagine a 2d grid of elements with snap-align: center, every element along the horizontal and vertical line through the center is snapped.
Option 2 would be more efficient to implement, as it is what the browser must already track internally, and if we are able to standardize on the snap point selection with multiple currently snap aligned elements would allow developers to know the element which will be tracked through layout shifts.
I propose we go with option 2, and update css-scroll-snap-1 4.1.3. Re-snapping After Layout Changes to always define an exact target in each axis. My proposal would be the following:
- Let inline be the set of boxes currently aligned on the inline axis.
- Let block be the set of boxes currently aligned on the block axis.
- If there is a focused element in either / both lists, remove all other elements from the list.
- If there is a targeted element in either / both lists, remove all other elements from the list.
- Remove any items from the block and inline lists which contain (nest) inner items in those lists. I.e. prefer snapping to innermost elements when nesting snap areas.
- If inline and block have elements in common, filter both lists to those elements they have in common.
- Select the first element in tree order from each of the block and inline list as the snapped target in each axis.
- When re-snapping, prefer to follow the axis that has the focused element, then the one which has the targeted element, then the block axis.