Overflow and Scrolling
Prerequisites: Sizing elements
overflow
.code-block { overflow-x: auto; }
.avatar { overflow: hidden; border-radius: 50%; }
.panel { max-height: 20rem; overflow-y: auto; overscroll-behavior: contain; }
.clip { overflow: clip; }
| Value | Behavior |
|---|---|
visible |
Content spills out (default) |
hidden |
Clipped; still scrollable by script, and creates a scroll container |
clip |
Clipped, no scroll container (doesn't break position: sticky) |
scroll |
Always shows scrollbars |
auto |
Scrollbars only when needed — usually what you want |
overscroll-behavior: containstops scrolling inside a panel from "chaining" to the page when the panel reaches its end.scrollbar-gutter: stablereserves room for the scrollbar, so content doesn't jump when it appears.scrollbar-colorandscrollbar-widthstyle scrollbars in the standard way.
Scroll snapping
.carousel {
display: flex;
gap: 1rem;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-padding-inline: 1rem;
}
.carousel > * {
flex: 0 0 80%;
scroll-snap-align: start;
}
Swiping or scrolling the carousel settles each item neatly at the start — no JavaScript. Make carousels usable with the keyboard too (the scroll container should be focusable, or the items contain links).
Smooth scrolling and anchor offsets
html {
scroll-padding-top: 5rem;
}
@media (prefers-reduced-motion: no-preference) {
html { scroll-behavior: smooth; }
}
:target {
scroll-margin-top: 5rem;
outline: 3px solid gold;
}
scroll-padding-topstops fragment links (#section) from hiding the target under a sticky header.:targetmatches the element the URL fragment points to.
Measuring overflow
<style>
.box { width: 200px; height: 50px; overflow: auto; }
.content { width: 500px; height: 120px; }
</style>
<div class="box"><div class="content"></div></div>
<script>
const box = document.querySelector(".box");
console.log("scroll size:", box.scrollWidth, "x", box.scrollHeight);
box.scrollTop = 1000;
console.log("max scrollTop:", box.scrollTop, "=", box.scrollHeight, "-", box.clientHeight);
</script>
scroll size: 500 x 120
max scrollTop: 70 = 120 - 50
The box is 200 × 50 but can scroll to reveal 500 × 120 of content;
the maximum scrollTop is scrollHeight − clientHeight. (This ran with
overlay scrollbars; with classic scrollbars, the horizontal scrollbar
takes part of the 50px, clientHeight shrinks, and the maximum grows.)
Common overflow bugs
- Horizontal scrolling on phones: something is wider than the
viewport — a fixed width, a long URL,
100vw(which includes the scrollbar on desktops), or a flex item withmin-width: auto. In DevTools, search the Elements panel or temporarily add* { outline: 1px solid red; }to find it. overflow: hiddenon an ancestor breaksposition: sticky.
What's next
Try the Intermediate Projects, then continue to Level 3 — Advanced: the full cascade and layers, nesting, modern color, architecture, tooling, performance, and accessibility.