CSS scroll-snap-align Property

This property specifies where an element aligns itself within its scroll container when snapping occurs. Think of it like choosing which part of a photo frame should stick to the center of a viewing window.

selector { scroll-snap-align: [ none | start | end | center ]{1,2}; }
none The element does not define a snap position on the scroll axis.
start Aligns the start edge of the element with the snap port of the scroll container.
end Aligns the end edge of the element with the snap port of the scroll container.
center Aligns the center of the element with the center of the snap port of the scroll container.

Code Examples

A basic horizontal slider where each item snaps to the center of the container view.

<style>
.container {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  width: 300px;
  border: 2px solid #333333;
}
.item {
  flex: 0 0 100%;
  height: 200px;
  scroll-snap-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: #ffffff;
}
.item:nth-child(odd) { background-color: #ff5722; }
.item:nth-child(even) { background-color: #00bcd4; }
</style>
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

An advanced vertical scroll layout using sections that snap to the start, with a JavaScript snippet showing how to manipulate alignment dynamically.

<style>
.scroll-box {
  height: 400px;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  border: 5px solid #222222;
}
section {
  height: 400px;
  scroll-snap-align: start;
  padding: 20px;
  box-sizing: border-box;
}
#sec1 { background: #eeeeee; }
#sec2 { background: #dddddd; }
#sec3 { background: #cccccc; }
</style>
<div class="scroll-box" id="scroller">
  <section id="sec1"><h1>Section 1</h1></section>
  <section id="sec2"><h1>Section 2</h1></section>
  <section id="sec3"><h1>Section 3</h1></section>
</div>
<script>
const scroller = document.getElementById("scroller");
// Dynamically change snap alignment via JS
// This would change all sections to snap to center instead of start
const sections = scroller.querySelectorAll("section");
sections.forEach(s => {
  s.style.scrollSnapAlign = "center";
});
</script>

Pro Tip

You can use scroll-margin on the child elements to create a gap between the snap point and the edge of the container. This is great for keeping some breathing room or 'white space' around your snapped elements without messing up your actual layout padding.

Deep Dive

The scroll-snap-align property is applied to the child elements, not the parent container. For it to work, the parent must have scroll-snap-type enabled. When a user stops scrolling, the browser looks for the nearest snap point defined by this property. If you provide one value, it applies to both the block and inline axes. If you provide two, the first is for the block axis (vertical in most cases) and the second is for the inline axis (horizontal). It effectively tells the browser, "When you stop here, make sure this specific edge of mine is flush with the container's edge."

Best Practices

Always use this property in tandem with scroll-snap-type on the parent element. For horizontal carousels, "center" is usually the most user-friendly setting so the active item is focused. For vertical article-style snapping, "start" ensures the reader begins at the top of the next section. Use it to create a more "app-like" feel for web galleries and slideshows.

Common Pitfalls

The most common mistake is applying this property to the scroll container itself; it must be applied to the items inside the container. Another issue is forgetting that scroll-padding on the parent or scroll-margin on the child can shift where the alignment actually lands. If your child element is larger than the container, "start" and "end" alignment might make parts of the content inaccessible.

Accessibility

Snap points can be frustrating for users with certain motor impairments or those who use specialized input devices. Sudden jumping movements can also trigger vestibular disorders. Always ensure that content remains reachable and that snapping doesn't skip over important information. Don't force a snap if it breaks the natural flow of reading.

Dev Data Table: scroll-snap-align property

default none
animatable no
inherited no
experimental no
year_intro 2016
year_standard 2018
js_syntax_1 element.style.scrollSnapAlign = "center";
js_syntax_2 element.style.setProperty("scroll-snap-align", "center");
js_note When manipulating this via JavaScript, ensure the parent container has a valid scroll-snap-type set or the alignment change will have no visible effect.
browsers { "Chrome": 69, "Edge": 79, "Firefox": 68, "Safari": 11, "Opera": 56, "Chrome Android": 69, "Safari on iOS": 11, "Samsung Internet": 10.1, "Opera Mobile": 48 }
results render here...