CSS scroll-snap-stop: always Explained

The CSS property scroll-snap-stop: always is a powerful tool designed to control pagination and scrolling velocity within scroll-snap containers. By default, users flicking or scrolling quickly can bypass multiple snap targets in a single gesture. Applying scroll-snap-stop: always forces the browser to halt at every single snap point, ensuring users view every item sequentially. This article explains how the property works, compares it to default scroll behavior, demonstrates its syntax, and outlines its best use cases.

The Problem with Default Scroll Snapping

When implementing CSS Scroll Snap using scroll-snap-type on a parent element and scroll-snap-align on child elements, the default value for snap stopping is normal.

Under scroll-snap-stop: normal, the browser calculates the trajectory and momentum of a user's swipe or mouse-wheel action. If the user flicks vigorously, the viewport will bypass several snap points and only settle on a distant snap point when momentum expires. While this is natural for long lists, it breaks the flow of experiences designed to be consumed one screen or slide at a time.

How scroll-snap-stop: always Works

The scroll-snap-stop property is applied directly to the snapped child elements, not the parent scroll container. When defined as always, it instructs the browser's scrolling engine to treat the element as an unavoidable stop point.

Even if a user executes a high-velocity scroll, the container will interrupt the momentum and lock directly onto the very next snap target in the direction of the scroll. The user must initiate a completely new scroll action to advance to subsequent items.

Syntax and Implementation

To implement this behavior, configure the scroll container as usual and add scroll-snap-stop: always to the child elements:

/* Parent scroll container */
.slider-container {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

/* Snapped child elements */
.slider-item {
  flex: 0 0 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

In this setup, each .slider-item takes up the full width of the container. Because scroll-snap-stop: always is declared, horizontal swipes will strictly advance or reverse one item at a time.

Practical Use Cases

  • Full-Page Presentations: Interactive storyboards, slide decks, or full-viewport narrative sites where skipping a section disrupts the context or structure.
  • Media Carousels: Image galleries or product carousels where each item contains critical information that should not be accidentally skipped.
  • Step-by-Step Wizards: Multi-step forms or onboarding sequences built using native scrolling mechanics that require user completion at each stage.

User Experience Considerations

While scroll-snap-stop: always is effective for single-item navigation, it should be used judiciously. Overusing this property on long lists or dense content feeds can cause frustration, as it artificially restricts user control and prevents fast navigation through large sets of data. Use it primarily when each snap point represents a distinct, self-contained view.