The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Use platform scrollbar colors.panel { scrollbar-color: auto; }View examples
Set thumb then track.panel { scrollbar-color: #475569 #e2e8f0; }View examples
Use platform thickness.panel { scrollbar-width: auto; }View examples
Request a thinner scrollbar.compact { scrollbar-width: thin; }View examples
Hide scrollbar chrome.carousel { scrollbar-width: none; }View examples
Style viewport scrollbars:root { scrollbar-color: #475569 #f8fafc; }View examples
Reserve scrollbar space.shell { scrollbar-gutter: stable; }View examples
Balance both gutter edges.reader { scrollbar-gutter: stable both-edges; }View examples
Create a scroll container.panel { max-block-size: 20rem; overflow: auto; }View examples
Make a region focusable<div class="panel" tabindex="0" role="region" aria-label="Build log">View examples
Offer explicit scroll controlsbutton.addEventListener("click", () => panel.scrollBy( { left: 240, behavior: "smooth"; }View examples
Preserve touch panning.carousel { touch-action: pan-x; overflow-x: auto; }View examples
Adapt native UI to schemes:root { color-scheme: light dark; }View examples
Restore system scrollbar colors@media (forced-colors: active) { .panel { scrollbar-color: auto; }; }View examples
Use a scoped legacy thumb.panel::-webkit-scrollbar-thumb { background: #475569; }View examples
Use a scoped legacy track.panel::-webkit-scrollbar-track { background: #e2e8f0; }View examples
Prefer standard styling@supports (scrollbar-color: auto) { .panel { scrollbar-color: #475569 #e2e8f0; }; }View examples
Remove smooth scrolling@media (prefers-reduced-motion: reduce) { .panel { scroll-behavior: auto; }; }View examples

Standard scrollbar styling deliberately exposes only color and thickness hints because scrollbars are essential platform controls. This guide uses scrollbar-color and scrollbar-width conservatively, separates scrollbar space reservation from appearance, and keeps every scroll region discoverable and operable when overlay scrollbars, forced colors, touch, or mouse-only input change the result.

Step by step

Detailed examples

01

Treat standard scrollbar styles as user-interface hints

scrollbar-color accepts auto or two colors in thumb-then-track order. scrollbar-width accepts auto, thin, or none; it does not accept lengths, and thin is platform-defined. These properties apply to scroll containers, while the root affects viewport scrollbars under specified propagation rules. Platforms may use overlay scrollbars or omit parts, so never assume exact geometry or styling fidelity.

Conservative themed log
.log { max-block-size: 18rem; overflow: auto; scrollbar-width: thin; scrollbar-color: #475569 #e2e8f0; }
Back to quick reference ↑
02

Separate visual styling from reserved layout space

Classic scrollbars consume layout space while overlay scrollbars do not. scrollbar-gutter controls whether room is reserved; it does not force a scrollbar to render and does not style it. stable reserves a gutter when overflow is auto, and both-edges mirrors it. Test both LTR and RTL because the scrollbar side and inline edge depend on platform and writing direction.

Stable centered reading column
.reader { overflow: auto; scrollbar-gutter: stable both-edges; max-inline-size: 70ch; margin-inline: auto; }
Back to quick reference ↑
03

Keep hidden scrollbars discoverable and operable

scrollbar-width:none leaves the element scrollable, but mouse-only users without a wheel may lose their main mechanism and everyone may lose the visual clue that more content exists. Use it only with visible previous/next controls, clipped-edge cues, keyboard focus, touch panning, and status text. If direct user scrolling should be disabled, overflow:hidden is the appropriate mechanism rather than merely hiding chrome.

Named carousel with explicit controls
<section aria-label="Featured projects"><button class="previous">Previous</button><div class="carousel" tabindex="0"><article>Alpha</article><article>Beta</article></div><button class="next">Next</button></section>
Back to quick reference ↑
04

Honor platform schemes and contrast preferences

Default scrollbars follow the element color scheme. If author colors are set, thumb and track need enough contrast for the control to be identifiable, including hover and inactive states the UA may derive. In forced colors, scrollbar-color normally computes to auto; do not opt out with forced-color-adjust:none. System settings can enlarge controls, so avoid layouts that depend on a thin width.

Scheme negotiation and forced-color reset
:root { color-scheme: light dark; }
@media (forced-colors: active) { * { scrollbar-color: auto; } }
Back to quick reference ↑
05

Confine non-standard pseudo-elements to optional decoration

::-webkit-scrollbar and its part pseudo-elements are non-standard, expose more visual details, and differ by engine and platform. Keep standard declarations as the contract and scope legacy rules to a particular component. When standard scrollbar-color or scrollbar-width is non-auto, supporting browsers can override legacy pseudo styling. Never make hit targets smaller than a user can operate.

Layered legacy decoration
.panel::-webkit-scrollbar { inline-size: .75rem; }
.panel::-webkit-scrollbar-thumb { background: #475569; border: 2px solid #e2e8f0; border-radius: 999px; }
@supports (scrollbar-color: auto) { .panel { scrollbar-color: #475569 #e2e8f0; } }
Back to quick reference ↑
06

Test real input hardware and dynamic content

Test classic and overlay scrollbars, high DPI, zoom, touch, trackpads, mouse drag, wheel, keyboard arrows, Page Up and Page Down, RTL, forced colors, and reduced motion. Scroll regions need visible focus indicators and sensible scroll chaining. Avoid JavaScript-driven repaint loops for decorative scrollbars; native scrolling and standard CSS preserve compositor optimizations and accessibility hooks.

Visible focus and motion-safe scrolling
.panel:focus-visible { outline: 3px solid CanvasText; outline-offset: 3px; }
.panel { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { .panel { scroll-behavior: auto; } }
Back to quick reference ↑

Local code tester

Test a discoverable custom scrollbar

Switch standard width and color choices while keyboard focus, explicit controls, and overflow cues remain available.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. CSS Working GroupCSS Scrollbars Styling Module Level 1drafts.csswg.org
  2. CSS Working GroupCSS Overflow Module Level 3drafts.csswg.org
  3. CSS Working GroupCSS Color Adjustment Module Level 1drafts.csswg.org
  4. Web Accessibility InitiativeUnderstanding WCAG 2.2 Success Criterion 1.4.11w3.org
  5. MDN Web DocsCSS scrollbars stylingdeveloper.mozilla.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback