Scrollbar Styling
For most of CSS's history, scrollbars were entirely outside your control — every browser drew them with its own native look, and there was no standard way to change that. Two competing approaches have since emerged: a small set of standardized properties for simple recoloring, and a much older, still-unstandardized set of WebKit pseudo-elements for detailed custom scrollbars. Full cross-browser coverage today means using both.
The standardized properties: scrollbar-width & scrollbar-color
scrollbar-width and scrollbar-color are now supported across all major browsers. They're intentionally simple — a thickness keyword and a thumb/track color pair — with no control over corners, buttons, or individual pixel dimensions:.scroll-panel {
scrollbar-width: thin; /* auto | thin | none */
scrollbar-color: #888 #f0f0f0; /* thumb-color track-color */
}The WebKit pseudo-elements: ::-webkit-scrollbar
Chrome, Safari, and Edge (all WebKit/Blink-based) additionally expose the scrollbar as a set of styleable pseudo-elements, giving you much finer control — independent styling of the track, the thumb, the corner, and hover/active states:
.scroll-panel::-webkit-scrollbar {
width: 10px;
}
.scroll-panel::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 8px;
}
.scroll-panel::-webkit-scrollbar-thumb {
background: #888;
border-radius: 8px;
}
.scroll-panel::-webkit-scrollbar-thumb:hover {
background: #555;
}Worked example: a themed scroll panel
Combining both approaches gives every browser a consistent, thinner, themed scrollbar:
.scroll-panel {
overflow-y: auto;
max-height: 400px;
/* Firefox and other standards-based browsers */
scrollbar-width: thin;
scrollbar-color: #6366f1 #e5e7eb;
}
/* Chrome, Safari, Edge */
.scroll-panel::-webkit-scrollbar {
width: 8px;
}
.scroll-panel::-webkit-scrollbar-track {
background: #e5e7eb;
}
.scroll-panel::-webkit-scrollbar-thumb {
background: #6366f1;
border-radius: 4px;
}Approach | Standard status | Control level | Browsers |
|---|---|---|---|
scrollbar-width / scrollbar-color | W3C standard | Basic — thickness + two colors | Firefox, Chrome, Safari, Edge (modern versions) |
::-webkit-scrollbar family | Non-standard, WebKit-specific | Detailed — track, thumb, corner, button, states | Chrome, Safari, Edge (WebKit/Blink only) |
::-webkit-scrollbar, and the standardized properties can't express everything the WebKit pseudo-elements can (like separately styling the scroll buttons or corner). If you need custom scrollbars that look consistent everywhere, you must write both — the standardized properties as a baseline, and the WebKit pseudo-elements for finer detail in Chromium/WebKit browsers.scrollbar-width: none (or, for WebKit, ::-webkit-scrollbar { display: none; }) hides the visual scrollbar while the element remains fully scrollable by wheel, touch, or keyboard. Hiding the scrollbar entirely can hurt discoverability — users may not realize there's more content — so use it sparingly and only when there's another visual cue that content continues.