AI CSS Scroll Behavior — Smooth Scrolling for Modern Web Navigation
Clicking an anchor link and having the page teleport instantly to the target section feels jarring. Users lose their sense of position on the page, and the abrupt jump breaks the flow of reading. The CSS scroll-behavior property fixes this with a single line of code, turning harsh jumps into smooth, animated scrolls that help users maintain spatial awareness.
Before scroll-behavior existed, smooth scrolling required JavaScript libraries or custom animation code. Today, one CSS declaration handles it natively in every modern browser — no dependencies, no bundle size increase, and no JavaScript execution cost.
Enabling Smooth Scrolling with One Line
The simplest implementation applies smooth scrolling to the entire page:
html {
scroll-behavior: smooth;
}
That is it. Every anchor link click, every element.scrollIntoView() call, and every navigation to a URL with a hash fragment now scrolls smoothly instead of jumping. The browser handles the animation timing, easing curve, and duration automatically.
The property accepts two values:
auto— the default instant jump behaviorsmooth— animated scrolling with browser-determined easing and duration
You can apply it to any scrollable container, not just the root html element:
/* Smooth scroll on the whole page */
html {
scroll-behavior: smooth;
}
/* Smooth scroll inside a specific container */
.scrollable-panel {
overflow-y: auto;
scroll-behavior: smooth;
max-height: 500px;
}
/* Smooth scroll for a horizontal carousel */
.carousel {
overflow-x: auto;
scroll-behavior: smooth;
display: flex;
gap: 16px;
}
scroll-behavior: smooth to the html element, not body. The scrolling container for the main document is the viewport, which is controlled by the html element in most browsers.Fixing the Sticky Header Problem with scroll-margin
If your site has a fixed or sticky navigation bar, smooth scrolling to an anchor will scroll the target element behind the header. The content you wanted to see is hidden under the nav. This is the most common complaint about anchor navigation, and scroll-margin solves it elegantly:
/* Fixed header height is 64px */
.sticky-nav {
position: sticky;
top: 0;
height: 64px;
z-index: 100;
}
/* Add scroll margin to all section targets */
section[id] {
scroll-margin-top: 80px; /* header height + 16px breathing room */
}
/* Or target specific heading elements */
h2[id], h3[id] {
scroll-margin-top: 80px;
}
The scroll-margin-top property creates invisible spacing above the element that the scroll position accounts for. When the browser scrolls to a section with scroll-margin-top: 80px, it stops 80 pixels before the element's top edge — exactly where you want it when a sticky header is present.
Dynamic Header Heights
If your header height changes between breakpoints, use CSS custom properties to keep the scroll margin in sync:
:root {
--header-height: 64px;
--scroll-offset: calc(var(--header-height) + 16px);
}
@media (max-width: 768px) {
:root {
--header-height: 48px;
}
}
section[id] {
scroll-margin-top: var(--scroll-offset);
}
This pattern ensures your scroll targets always clear the header regardless of screen size. For more techniques on managing responsive layouts, see our CSS media query breakpoints guide.
Building a Table of Contents with Smooth Scroll
A table of contents with smooth scrolling is one of the most user-friendly navigation patterns for long-form content. Here is a complete implementation:
<!-- Table of contents -->
<nav class="toc" aria-label="Table of contents">
<h2>On this page</h2>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#getting-started">Getting Started</a></li>
<li><a href="#advanced">Advanced Techniques</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</nav>
<!-- Content sections -->
<section id="introduction">...</section>
<section id="getting-started">...</section>
<section id="advanced">...</section>
<section id="conclusion">...</section>
html {
scroll-behavior: smooth;
}
section[id] {
scroll-margin-top: 80px;
}
.toc {
position: sticky;
top: 80px;
}
.toc a {
display: block;
padding: 8px 16px;
color: #8888a0;
border-left: 2px solid transparent;
transition: all 0.2s;
}
.toc a:hover,
.toc a.active {
color: #00cec9;
border-left-color: #00cec9;
}
For generating table of contents markup automatically, check out our AI table of contents generator guide.
Scroll Behavior with JavaScript
While CSS scroll-behavior handles anchor links automatically, JavaScript gives you more control for programmatic scrolling. The scrollIntoView() method respects the CSS scroll-behavior setting, but you can also override it per call:
// Uses CSS scroll-behavior setting
document.getElementById('target').scrollIntoView();
// Explicitly smooth, regardless of CSS setting
document.getElementById('target').scrollIntoView({
behavior: 'smooth',
block: 'start', // vertical alignment
inline: 'nearest' // horizontal alignment
});
// Scroll to top button
document.querySelector('.back-to-top').addEventListener('click', () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
The block parameter controls vertical alignment: start aligns the element's top with the viewport top, center centers it vertically, and end aligns the bottom. The inline parameter does the same for horizontal scrolling.
Scroll to Top Button Pattern
A back-to-top button that appears after scrolling down is a natural companion to smooth scrolling:
.back-to-top {
position: fixed;
bottom: 24px;
right: 24px;
width: 48px;
height: 48px;
border-radius: 50%;
background: rgba(108, 92, 231, 0.9);
backdrop-filter: blur(8px);
color: white;
border: none;
cursor: pointer;
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s, transform 0.3s;
z-index: 50;
}
.back-to-top.visible {
opacity: 1;
transform: translateY(0);
}
The button uses backdrop-filter: blur() for a frosted glass look that matches modern dark mode interfaces. For more on backdrop-filter techniques, see our frosted glass UI patterns guide.
Accessibility and Reduced Motion
Smooth scrolling animations can cause discomfort for users with vestibular disorders or motion sensitivity. The prefers-reduced-motion media query lets you disable smooth scrolling for users who have requested reduced motion in their operating system settings:
html {
scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
/* Also disable other scroll-related animations */
*,
*::before,
*::after {
scroll-behavior: auto !important;
}
}
prefers-reduced-motion override when using scroll-behavior: smooth. Approximately 25-30% of users have motion sensitivity settings enabled on their devices. Respecting this preference is not optional — it is a core accessibility requirement.For JavaScript-triggered scrolling, check the preference programmatically:
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
element.scrollIntoView({
behavior: prefersReducedMotion ? 'auto' : 'smooth'
});
Combining scroll-behavior with scroll-snap
The scroll-behavior and scroll-snap properties work together to create polished scrolling experiences. While scroll-behavior controls the animation style, scroll-snap controls where scrolling stops:
.fullpage-sections {
overflow-y: auto;
scroll-behavior: smooth;
scroll-snap-type: y mandatory;
height: 100vh;
}
.fullpage-sections section {
scroll-snap-align: start;
height: 100vh;
scroll-margin-top: 0;
}
This creates a full-page scrolling experience where each section snaps into place with a smooth animation. For a deep dive into scroll-snap techniques, read our CSS scroll-snap guide.
Performance and Browser Support
CSS scroll-behavior: smooth has excellent browser support in 2026, working in all modern browsers including Chrome, Firefox, Safari, and Edge. The browser handles the animation on the compositor thread, so it does not block the main thread or cause jank.
A few performance considerations to keep in mind:
- Smooth scrolling is free in terms of JavaScript execution — the browser handles everything natively
- Long scroll distances (thousands of pixels) may feel slow with smooth scrolling; consider instant jumps for very long pages
- Nested smooth-scrolling containers can create confusing UX — limit smooth scrolling to one axis per container
- The scroll duration is browser-determined and cannot be customized with CSS alone; use the Web Animations API if you need precise control
Smooth Scrolling as a Foundation
CSS scroll-behavior is one of those properties that delivers outsized UX improvement for minimal code investment. One line of CSS transforms every anchor link on your page from a jarring teleport into a smooth, oriented navigation experience. Pair it with scroll-margin for sticky headers, scroll-snap for section-based layouts, and prefers-reduced-motion for accessibility, and you have a complete scrolling system built entirely in CSS.
- CSS Scroll Snap Guide for snap-to-section scrolling patterns
- CSS Media Query Breakpoints for responsive scroll-margin values
- AI CSS Animation Generator for scroll-triggered animations
- AI Table of Contents Generator for automatic navigation markup
Design scroll-snap containers with smooth scrolling, configure snap points and alignment, and export production-ready CSS for carousels, galleries, and full-page sections.
Try AI CSS Scroll Snap Generator →
The AI CSS Scroll Snap Generator lets you visually configure scroll-snap containers with smooth scrolling behavior. Set snap points, alignment, and scroll-margin offsets, then export the complete CSS with accessibility-friendly prefers-reduced-motion overrides included automatically.