Gecko:CSSScrollSnapping
Proposal
scroll-snap-type: none | proximity | mandatory (shorthand setting both x and y)
scroll-snap-type-y: none | proximity | mandatory
scroll-snap-type-x: none | proximity | mandatory
These properties apply to scrollable elements. Values are defined similar to the Microsoft scroll-snap-type property. The default value is "none".
A scrollable element is one for which 'overflow-x' or 'overflow-y' is 'scroll' or 'auto'.
scroll-snap-edges: none | margin-box | border-box | center
This property defines which (if any) CSS boxes for the element contribute to the allowable snapping positions for the nearest scrollable ancestor.
Scroll snapping is applied at the end of each complete scroll gesture (e.g. after releasing the finger at the end of a touch panning gesture, after pressing an arrow key) to potentially adjust the final scroll destination. At the end of a scroll gesture which scrolls an element E, the UA determines a set of potential snapping opportunities:
- For each descendant D of E for which E is the nearest scrollable ancestor, where D's value of 'scroll-snap-edge' is 'margin-box', let B be D's first fragment's margin-box. If B exists, then each edge of B can be snapped to the corresponding edge of E's scroll-port.
- For each descendant D of E for which E is the nearest scrollable ancestor, where D's value of 'scroll-snap-edge' is 'border-box', let B be D's first fragment's border-box. If B exists, then each edge of B can be snapped to the corresponding edge of E's scroll-port.
- For each descendant D of E for which E is the nearest scrollable ancestor, where D's value of 'scroll-snap-edge' is 'center', let B be D's first fragment's border-box. If B exists, then the center of B can be snapped to the center of E's scroll-port.
These definitions implicitly require transforming a box rectangle up to the coordinate space of the element E. When CSS transforms are present, preserve axis-alignment by using the smallest axis-aligned rectangle that contains the transformed box.
The algorithm for computing which snapping opportunity (if any) to take is gesture and UA dependent. However the following constraints should be honored:
- When scrolling along an axis for which 'scroll-snap-type' is 'mandatory', the UA should settle on a scroll position which matches one of the snapping opportunities for that axis. However this requirement is lifted if one or more of the snapping opportunities' boxes B is larger than the scroll-port.
- When 'scroll-snap-type' is 'none' for some axis, no scroll snapping occurs along that axis.
UAs should apply scroll snapping to all user scroll gestures (including keyboard, scrollbars, etc). Script-driven scrolling (e.g. setting scrollLeft or scrollTop) is never affected by scroll snapping. Layout changes that affect the positions of elements with 'scroll-snap-edges', or dynamic changes to values of 'scroll-snap-edges', do not trigger snapping in the absence of a scroll gesture, even if 'mandatory' snapping is requested.