Scrollbars

  • A scrollbar appears when the content of a box exceeds the visible area of that box.

  • In HTML/CSS, every element can potentially become a scroll container if:

    • its content overflows its box

    • and its overflow behavior allows scrolling

  • The browser then creates a scrolling mechanism composed of:

    • scroll container (element)

    • scrollport (visible area)

    • scrollable content

    • scrollbars (UI controls)

    • scroll position (x/y offsets)

Requirements

  • Scrollbars only appear if the element has a constrained size.

  • Without a height/width limit, no overflow occurs.

  • Scrolling requires at least one of:

    • height / max-height

    • width / max-width

    • flex/grid constraints

    • viewport constraints (vh, vw)

    • parent layout limits

  • If the element can expand freely, it will not scroll.

overflow

  • This is the main rule that determines whether scrollbars exist.

  • visible  (default):

    • content spills out, no scrollbar.

  • hidden :

    • content clipped, no scrollbar.

  • scroll :

    • scrollbar always visible.

  • auto :

    • scrollbar appears only when needed.

  • clip :

    • like hidden, but cannot scroll programmatically.

Layout Impact

  • Scrollbars may:

    • take layout space (classic scrollbars)

    • overlay content (macOS, mobile)

    • auto-hide (overlay scrollbars)

  • This depends on OS and browser.

  • scrollbar-gutter: stable;

    • reserve space for scrollbar even when not visible

  • scrollbar-gutter: stable both-edges;

    • prevents layout shifting when scrollbars appear/disappear

  • Example problem:

    • container width = 100%

    • scrollbar appears → content shrinks → layout shifts

    • Solutions:

      1. scrollbar-gutter: stable;

      2. padding-right: 12px;

Scroll Propagation

  • Scrolling bubbles up when the container reaches its limit.

  • Example:

    • inner div scrolls until end

    • then page starts scrolling

  • overscroll-behavior: contain;

    • auto (default)

    • contain

    • none

Scroll Snapping

  • Optional behavior to align scroll positions:

    • scroll-snap-type: y mandatory;

    • scroll-snap-align: start;

Customization

Standard properties (Only option for Firefox)
  • scrollbar-width: auto | thin | none

    • scrollbar-width: thin;

  • scrollbar-color: thumb track

    • scrollbar-color: #888 #222;

  • Supports all  browsers.

  • You can use this rule to limit a style to only Firefox:

    @supports (-moz-appearance: none) {
        /* CSS */
    }
    
WebKit-based pseudo-elements (Chrome, Edge, Safari)
  • ::-webkit-scrollbar (whole scrollbar)

  • ::-webkit-scrollbar-track

  • ::-webkit-scrollbar-track-piece

    • track excluding thumb

  • ::-webkit-scrollbar-thumb

  • ::-webkit-scrollbar-button

    • Buttons (arrows)

  • ::-webkit-scrollbar-corner

    • (where x/y scrollbars meet)

  • ::-webkit-resizer

    • Resizer (rare). Resize handle in scrollable elements (e.g., <textarea> )

  • Pseudo-classes support :

    • Interaction states

      • :hover

      • :active

      • :window-inactive

    • Orientation

      • :horizontal

      • :vertical

    • Increment/decrement states (buttons)

      • :increment

      • :decrement

    • Enabled/disabled`

      • :enabled

      • :disabled

    • Visibility

      • :corner-present  (rare, mostly internal)

  • Important rules :

    • Works only in WebKit/Blink engines.

    • Firefox ignores  these selectors.

  • The ::-webkit-scrollbar  pseudo-elements do not appear in the HTML or DOM tree., because they are non-DOM pseudo-elements implemented at the rendering engine level.

    • ::before  / ::after  → part of CSS pseudo-element tree (inspectable)

    • ::-webkit-scrollbar  → engine-specific UI primitive (not inspectable)