Skip to content
AgileLogics
6 min read

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: contain stops scrolling inside a panel from "chaining" to the page when the panel reaches its end.
  • scrollbar-gutter: stable reserves room for the scrollbar, so content doesn't jump when it appears.
  • scrollbar-color and scrollbar-width style 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-top stops fragment links (#section) from hiding the target under a sticky header.
  • :target matches 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 with min-width: auto. In DevTools, search the Elements panel or temporarily add * { outline: 1px solid red; } to find it.
  • overflow: hidden on an ancestor breaks position: 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.