Question
How can CSS be used to hide the scrollbar on an HTML page? In particular, how can the scrollbar be visually hidden while allowing users to continue scrolling the page?
Short Answer
You will learn the difference between removing scrolling and hiding the scrollbar, how to apply scrollbar-hiding CSS to a page or a specific container, and when keeping a visible scroll indicator is the better choice.
Concept
A scrollbar is a browser interface element that shows whether content extends beyond a scrollable area and lets users move through that content.
There are two distinct CSS goals that are often confused:
- Hide the scrollbar but keep scrolling: Content can still be scrolled with a mouse wheel, trackpad, keyboard, touch gesture, or script.
- Disable scrolling: Overflowing content cannot be reached by normal scrolling.
To disable scrolling, use overflow: hidden. To hide the scrollbar while preserving scrolling, use browser-specific scrollbar properties:
scrollbar-width: nonefor Firefox.::-webkit-scrollbarfor Chromium-based browsers and Safari.
Hiding scrollbars can make a minimal interface look cleaner, but it also removes an important visual clue that more content is available. Use it deliberately and ensure users can still discover and operate the scrollable region.
Mental Model
Think of a scrollable page as a long document inside a window.
- The content is the document.
- Scrolling is the ability to slide the document up and down.
- The scrollbar is the small handle at the window edge that shows your position.
Using overflow: hidden locks the document so it cannot slide. Hiding the scrollbar styles removes the handle but leaves the document able to slide. Those are different actions.
Syntax and Examples
Use a reusable class when you want to hide the scrollbar on a particular scrolling element:
.hide-scrollbar {
overflow: auto;
scrollbar-width: none; /* Firefox */
}
.hide-scrollbar::-webkit-scrollbar {
display: none; /* Chrome, Edge, Safari */
}
<div class="hide-scrollbar messages">
<p>Message 1</p>
<p>Message 2</p>
<p>Message 3</p>
<p>More messages...</p>
</div>
.messages {
height: 180px;
border: 1px solid #ccc;
padding: 12px;
}
The .messages element has a fixed height, so it becomes scrollable when its content is taller than 180px. The .hide-scrollbar rules keep that scrolling behavior but hide the visible scrollbar.
To apply this to the entire page, target the root scrolling element:
html {
scrollbar-width: none;
}
html::-webkit-scrollbar {
display: none;
}
Avoid setting overflow: hidden if users need to access content below the viewport.
Step by Step Execution
Consider this scrollable feed:
<div class="feed hide-scrollbar">
<p>First update</p>
<p>Second update</p>
<p>Third update</p>
<p>Fourth update</p>
<p>Fifth update</p>
<p>Sixth update</p>
</div>
.feed {
height: 100px;
overflow-y: auto;
}
.hide-scrollbar {
scrollbar-width: none;
}
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
Execution flow:
- The browser renders all six paragraphs inside
.feed. .feedis only100pxhigh, so the paragraphs do not all fit.overflow-y: autoallows vertical scrolling because there is vertical overflow.- Firefox reads
scrollbar-width: noneand does not paint a scrollbar. - Chromium-based browsers and Safari match
::-webkit-scrollbarand do not paint a scrollbar. - The feed still responds to wheel, trackpad, touch, keyboard, and programmatic scrolling inputs.
Real World Use Cases
Common uses include:
- Image carousels: A horizontal row of cards can be swiped or scrolled without a permanent bar.
- Mobile-style panels: Chat lists, navigation drawers, and feeds may use a cleaner scrollbar-free appearance.
- Embedded widgets: A small activity feed or preview panel may need scrolling without visual clutter.
- Full-screen presentations: A site may hide the page scrollbar as part of a controlled visual design.
- Custom scroll indicators: An application may replace the native scrollbar with progress dots, a mini-map, or another clear indicator.
For long articles, forms, settings pages, and data tables, a visible scrollbar is usually helpful because it communicates that more content exists.
Real Codebase Usage
In production code, developers usually apply scrollbar hiding to a specific component rather than globally. This limits accessibility and usability trade-offs to the part of the interface that needs it.
A typical component pattern is:
.horizontal-list {
display: flex;
gap: 1rem;
overflow-x: auto;
scroll-snap-type: x mandatory;
scrollbar-width: none;
}
.horizontal-list::-webkit-scrollbar {
display: none;
}
.horizontal-list > * {
scroll-snap-align: start;
}
This is useful for a horizontally scrollable card list. In a real interface, developers also provide an alternative way to discover movement, such as:
- Partially showing the next card.
- Adding previous/next buttons.
- Showing a fade at the container edge.
- Including instructions such as “Swipe to see more.”
When content is conditionally scrollable, keep overflow: auto instead of overflow: scroll. auto shows or enables scrolling only when content actually overflows.
Common Mistakes
Using overflow: hidden by mistake
This hides overflow and prevents users from scrolling to it:
/* Usually wrong when content must remain reachable */
body {
overflow: hidden;
}
Use scrollbar styling instead when the goal is visual hiding.
Targeting only one browser family
This works in Firefox but not Chromium-based browsers or Safari:
.panel {
scrollbar-width: none;
}
Use both scrollbar-width: none and ::-webkit-scrollbar rules for broader support.
Removing the only hint that content scrolls
A scrollbar-free panel can look like all its content is already visible. Avoid this by showing a clipped next item, adding controls, or using a visible scrollbar for important content.
Forgetting to create a scrollable area
Scrollbar rules do nothing useful if the element has no constrained size or no overflow:
.panel {
scrollbar-width: none;
}
Give the element a height, max-height, width, or max-width when appropriate, and use overflow: auto or overflow-x: auto.
Applying page-level rules to the wrong element
Browser scrolling may be associated with html, body, or both depending on the browser and layout. For page-level styling, start with html and test in the browsers you support.
Ignoring keyboard accessibility
A scrollable <div> is not always keyboard-focusable. If users must interact with a standalone scrolling region, consider making it focusable and labeling it:
<div class="feed hide-scrollbar" tabindex="0" aria-label="Recent messages">
<!-- scrollable content -->
</div>
Comparisons
| CSS approach | What it does | Can the user still scroll? | Best use |
|---|---|---|---|
overflow: auto | Enables scrolling only when content overflows | Yes | Normal scrollable containers |
overflow: scroll | Reserves or shows scrollbars even when they may not be needed | Yes | Cases requiring stable layout space |
overflow: hidden | Clips overflow | No, usually | Cropping decorative content or locking page scroll |
scrollbar-width: none | Hides scrollbar rendering in Firefox | Yes | Firefox scrollbar hiding |
::-webkit-scrollbar { display: none; } | Hides scrollbar rendering in Chromium-based browsers and Safari | Yes | WebKit-style scrollbar hiding |
overflow controls whether overflow can be scrolled. Scrollbar styling controls whether the scrollbar is drawn. In most scrollbar-hiding cases, you need both a scroll-capable overflow value and browser-specific styling.
Cheat Sheet
/* Hide a container scrollbar while keeping it scrollable */
.scroll-area {
overflow: auto;
scrollbar-width: none; /* Firefox */
}
.scroll-area::-webkit-scrollbar {
display: none; /* Chrome, Edge, Safari */
}
/* Horizontal-only scrolling */
.card-row {
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: none;
}
.card-row::-webkit-scrollbar {
display: none;
}
/* Disable page scrolling: different from hiding the bar */
body {
overflow: hidden;
}
Rules to remember:
- Use
overflow: autoto preserve scrolling. - Use
overflow: hiddenonly when content should not be scrollable. scrollbar-width: noneis for Firefox.::-webkit-scrollbarcovers Chromium-based browsers and Safari.- Provide another visual or functional cue when hidden content is important.
- Test with mouse, touch, keyboard, and multiple browsers.
FAQ
Can I hide a scrollbar with CSS and still scroll?
Yes. Use a scroll-capable overflow value such as overflow: auto, then hide scrollbar rendering with scrollbar-width: none and ::-webkit-scrollbar rules.
Does overflow: hidden hide only the scrollbar?
No. It generally prevents normal scrolling and clips content that extends outside the element.
How do I hide only the horizontal scrollbar?
Use overflow-x: auto for horizontal scrolling and apply the same scrollbar-hiding rules. If vertical overflow should be clipped, set overflow-y: hidden.
Is ::-webkit-scrollbar standard CSS?
It is a widely used browser-specific pseudo-element, primarily supported by Chromium-based browsers and Safari. Pair it with scrollbar-width for Firefox.
Why is my element not scrolling after I hide its scrollbar?
Check that it has overflow and a constrained dimension, such as height, max-height, width, or max-width. Also verify that you did not use overflow: hidden.
Is it a good idea to hide the page scrollbar?
Not always. It can make it harder for users to notice that a page continues. It is generally safer to hide scrollbars on focused, clearly scrollable components than on long document pages.
Can users scroll a hidden-scrollbar area with the keyboard?
They may need to focus the area first. For an independent scrollable region, tabindex="0" can make it focusable; test the experience and provide an accessible label when appropriate.
Mini Project
Description
Build a horizontally scrollable product-card row. The row hides its native scrollbar, but it still makes additional cards obvious by leaving part of the next card visible. This mirrors a common mobile storefront or media-browsing pattern.
Goal
Create a swipe- and wheel-scrollable card row with a hidden native scrollbar and snap-to-card behavior.
Requirements
Create at least five product cards. Make the card row scroll horizontally when it does not fit. Hide the native scrollbar while preserving scrolling. Use scroll snapping so cards align neatly after scrolling. Make it clear that additional cards are available.
Keep learning
Related questions
Add a Favicon to a Static HTML Page
Learn how to add a favicon to static HTML pages, use correct paths and icon formats, and troubleshoot browser caching and local-file issues.
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.