css property
`scroll-snap-stop` CSS property
The scroll-snap-stop CSS property defines whether or not the scroll container is allowed to “pass over” possible snap positions.
scroll-snap-stop: normal;
scroll-snap-stop: always;
<section class="default-example" id="default-example">
<p class="explanation">
The effect of this property can be noticed on devices with a touchpad. Try
to scroll through all items with a single swing. Value
<b class="keyword">'normal'</b> should pass through all pages, while
<b class="keyword">'always'</b> will stop at the second page.
</p>
<div class="snap-container">
<div>1</div>
<div id="example-element">2</div>
<div>3</div>
</div>
<div class="info">Scroll »</div>
</section>
.default-example {
flex-direction: column;
}
.explanation {
margin-top: 0;
}
.keyword {
color: darkorange;
}
.default-example .info {
width: 100%;
padding: 0.5em 0;
font-size: 90%;
}
.snap-container {
text-align: left;
width: 250px;
height: 250px;
overflow-x: scroll;
display: flex;
box-sizing: border-box;
border: 1px solid black;
scroll-snap-type: x mandatory;
}
.snap-container > div {
flex: 0 0 250px;
width: 250px;
background-color: rebeccapurple;
color: white;
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
scroll-snap-align: start;
}
.snap-container > div:nth-child(even) {
background-color: white;
color: rebeccapurple;
}
Syntax
/* Keyword values */
scroll-snap-stop: normal;
scroll-snap-stop: always;
/* Global values */
scroll-snap-stop: inherit;
scroll-snap-stop: initial;
scroll-snap-stop: revert;
scroll-snap-stop: revert-layer;
scroll-snap-stop: unset;
Values
This property is specified as one of the following keyword values:
normal- : When the visual viewport of this element’s scroll container is scrolled, it may “pass over” possible snap positions.
always- : The scroll container must not “pass over” a possible snap position; and must snap to the first of this elements’ snap positions.
Formal definition
Formal syntax
Examples
Setting different snap stops
The example below demonstrates the contrast between the always and normal values of scroll-snap-stop. The difference in the two scroll-snap-stop values is more noticeable when the scroll-snap-type property is set to mandatory, which is what is used in this example.
HTML
<p>scroll-snap-stop: always (X Mandatory)</p>
<div class="x mandatory-scroll-snapping always-stop">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>scroll-snap-stop: always (X Mandatory) on odd child elements</p>
<div class="x mandatory-scroll-snapping always-stop-odd">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>scroll-snap-stop: always (X Mandatory) on even child elements</p>
<div class="x mandatory-scroll-snapping always-stop-even">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>scroll-snap-stop: normal (X Mandatory)</p>
<div class="x mandatory-scroll-snapping normal-stop">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>scroll-snap-stop: always (Y Mandatory)</p>
<div class="y mandatory-scroll-snapping always-stop">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>scroll-snap-stop: normal (Y Mandatory)</p>
<div class="y mandatory-scroll-snapping normal-stop">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
CSS
/* setup */
body {
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
flex-flow: column nowrap;
font-family: monospace;
text-align: center;
}
div[class] {
font-size: 3rem;
display: flex;
overflow: auto;
flex: none;
}
.x {
width: 50%;
min-width: 15rem;
height: 6rem;
flex-flow: row nowrap;
}
.y {
width: 30%;
min-width: 12rem;
height: 12rem;
flex-flow: column nowrap;
}
div > div {
flex: none;
outline: 1px solid #333333;
}
.x > div {
width: 90%;
height: 100%;
}
.y > div {
width: 100%;
height: 80%;
}
/* coloration */
div > div:nth-child(even) {
background-color: #87ea87;
}
div > div:nth-child(odd) {
background-color: #87ccea;
}
/* setting up mandatory scroll-snap on parent */
.x.mandatory-scroll-snapping {
scroll-snap-type: x mandatory;
}
.y.mandatory-scroll-snapping {
scroll-snap-type: y mandatory;
}
/* defining scroll-snap alignment on children */
div > div {
scroll-snap-align: center;
}
/* defining scroll-snap stop on children */
.always-stop > div {
scroll-snap-stop: always;
}
.always-stop-odd > div:nth-of-type(odd) {
scroll-snap-stop: always;
}
.always-stop-even > div:nth-of-type(even) {
scroll-snap-stop: always;
}
.normal-stop > div {
scroll-snap-stop: normal;
}
Result
Scroll from left to right and from top to bottom in the X and Y boxes below, respectively. In the X and Y boxes where the scroll-snap-stop property is set to always, the scrolling is forced to stop at the snap point even when you scroll fast. However, in the boxes where the scroll-snap-stop property is set to normal, the snap points are skipped when you scroll fast.
If required, you can be selective about the items that are always stopped at inside the scroll container. This is demonstrated in the example below by targeting odd and even items; you can choose a different strategy based on your requirement. In the example below, scrolling does not “pass over” odd and even items in the second and third boxes, respectively.
Specifications
Browser compatibility
See also
scroll-snap-alignscroll-initial-target- CSS scroll snap module
- Well-controlled scrolling with CSS scroll snap on web.dev (2018)