Written by Fimber Elemuwa✏️
This guide will show you how to hide the scrollbar in popular web browsers by making use of modern CSS techniques.
The browser's scrollbar allows users to scroll up and down on the page without taking their hands off the keyboard or trackpad. However, to achieve a more streamlined appearance, certain websites alter, customize, or completely hide the scrollbar, either for the entire webpage or specific elements.
To get the most out of this article, you should have a basic understanding of HTML and CSS.
Why would I hide the scrollbar?
While it’s generally recommended to avoid altering or overriding default browser styles for accessibility reasons, there can be compelling justifications for hiding scrollbars.
Scrollbars appear automatically when web content exceeds the available space within the browser window. User agent styles, which are responsible for the default browser styling, manage this behavior.
A scrollbar provides a visual cue for scrolling using a mouse or keyboard. However, it’s unnecessary in specific layout patterns: particularly those that don’t require scrolling interactions, such as a slideshow, news tickers, image galleries, etc. In such patterns, hiding the scrollbar can create a smoother interaction and eliminate distractions from the overall feature.
By hiding scrollbars, you can reclaim the space they occupy, adding to your screen’s real estate. This not only streamlines the UI but also allows for a cleaner and more spacious design.
Another common motivation for hiding scrollbars is to enhance the mobile viewing experience. On mobile devices, especially smartphones, users typically expect vertical scrolling, with no need for horizontal movement, as screens are usually tall and narrow, and content flows from top to bottom. Keeping the horizontal scrollbar hidden creates a more natural feel and reduces attention to the technical aspects of browsing.
If you’re wondering how to hide or remove these scrollbars correctly, this tutorial covers everything you should know to accomplish that.
Editor’s note: This article was last updated by Alexander Godwin in March 2025 to include updated information on cross-browser compatibility, advanced use cases for custom scrollable divs, and additional interactive examples.
How to hide a scrollbar in CSS
There are two different methods to hide the scrollbar for a webpage or a specific element within it. The first method involves setting the overflow property to hidden
, which effectively hides the scrollbar:
.no-horizontal-scrollbar {
/* Keeps the horizontal scrollbar hidden */
overflow-x: hidden;
}
.no-vertical-scrollbar {
/* Keeps the vertical scrollbar hidden */
overflow-y: hidden;
}
.no-scrollbars {
/* Keeps both the horizontal and vertical
scrollbars hidden */
overflow: hidden;
}
However, this method also takes away the ability to scroll and greatly affects basic accessibility. This is where the scrollbar-specific CSS pseudo-selectors come into play, which we will briefly discuss in the next few sections.
Essential CSS properties to hide scrollbars
Apart from the overflow
CSS property, you primarily need just two more CSS features to manage the appearance of scrollbars:
-
-webkit-scrollbar
— To target scrollbars in all older versions of WebKit-based browsers -
scrollbar-width
— To target scrollbars in Modern browsers. This property is part of the new scrollbar properties and is currently supported in newer versions of most browsers.
Along with these two CSS features, we will employ additional presentational CSS properties to enhance the appearance of the upcoming examples in later sections.
Cross-browser compatibility
Each browser-rendering engine takes a unique approach to managing scrollbar visibility, leading to the use of various vendor-specific CSS pseudo-selectors and properties. Let’s briefly examine these and their usage.
Hiding the scrollbar on older Chrome, Edge, and other WebKit-based browsers
You can use the ::-webkit-scrollbar
pseudo-selector to hide the scrollbar in older Chrome, Edge, Opera, Safari, and other WebKit-based browsers. This is not currently the standard way; it’s a vendor-specific selector supported by a limited category of browsers.
The -webkit-scrollbar
pseudo-selector provides a wide range of options for customizing a scrollbar. You can adjust the appearance of the up and down arrows, modify the scrollbar thumb’s and track’s color, change the background, and more:
scrollable-content {
height: 150px;
}
.scrollable-content::-webkit-scrollbar {
display: none;
}
In this example, we’ll focus on how to hide the scrollbar without affecting the ability to scroll:
As you can see in the above demo, the scrollbar is hidden, but the page remains scrollable using both the mouse and keyboard. Note that this demo covers the hidden scrollbars in Chrome, Edge, and WebKit-based browsers only.
Microsoft web browsers
Browsers developed by Microsoft also support the ::-webkit-scrollbar
pseudo-selector for adjusting scrollbar visibility and other appearance properties.
If you prefer not to use the -webkit-scrollbar
pseudo-selector, you can use the -ms-overflow-style
property to control the scrollbar visibility. Note that this property is specific to Microsoft Edge and Internet Explorer, and won’t function in other browsers:
.scrollable-content {
-ms-overflow-style: none;
}
Newer versions of browsers (Webkit-based and Gecko Based)
For Modern versions of browsers like Firefox, Google Chrome, and Microsoft Edge, you have the option to use the scrollbar-width
property to control the scrollbar visibility. This CSS property is the standard method for controlling the visibility and width of scrollbars with CSS:
.scrollable-content {
scrollbar-width: none;
}
Here’s an implementation using all the pseudo-selectors and properties discussed above, which makes this example functional on all modern web browsers that implement WebKit, Edge, or Gecko rendering engines:
While this approach might appear sophisticated to developers, it doesn’t offer any visual cues or indications to users regarding the presence of additional content below the current view. This lack of clarity can potentially result in a significant accessibility issue.
overflow: hidden
vs. scrollbar-width: none
vs. -webkit-scrollbar
Method | Browser support | Scrolling behavior | Visual impact | Best for | Drawbacks |
---|---|---|---|---|---|
`overflow: hidden` | All browsers | Disables scrolling completely | Hides content overflow | Content that should never scroll | Content becomes inaccessible |
`scrollbar-width: none` | Modern browsers | Maintains scrolling | Hides only scrollbar | Modern browser UIs | Requires additional CSS for other browsers |
`-ms-overflow-style: none` | IE/Edge | Maintains scrolling | Hides only scrollbar | Legacy Microsoft browsers | Limited to Microsoft browsers |
`::-webkit-scrollbar` | Old Chrome, Safari, Opera browsers | Maintains scrolling | Hides only scrollbar | WebKit/Blink browsers | Requires vendor prefix |
overflow: hidden
vs. custom scrollable divs
overflow:hidden | custom scrollable divs |
---|---|
Simple to implement | Full content remains accessible |
Good for truncating content | Better user experience for long content |
Prevents layout shifts | Can be styled to match design |
Better performance since the browser doesn't need to handle scrolling | Maintains content context |
Advanced use cases for custom scrollable divs
When building modern web interfaces, basic scrollable divs are often insufficient. Let's explore some advanced patterns that enhance user experience and performance.
1. Infinite scrolling
Perfect for content feeds and long lists, infinite scrolling loads content as users scroll:
const observeScroll = (container) => {
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
loadMoreContent();
}
}, { root: container, threshold: 0.1 });
observer.observe(container.querySelector('.scroll-trigger'));
};
2. Virtual scrolling
Essential for handling large datasets efficiently by rendering only visible items:
class VirtualScroller {
constructor(container, items) {
this.visibleItems = Math.ceil(container.clientHeight / this.rowHeight);
this.totalHeight = items.length * this.rowHeight;
container.addEventListener('scroll', () => {
const startIndex = Math.floor(container.scrollTop / this.rowHeight);
this.renderVisibleItems(startIndex);
});
}
}
3. Synchronized scrolling
Useful for comparing content side by side, like code diffs:
const syncScroll = (containers) => {
containers.forEach(container => {
container.onscroll = (e) => {
containers
.filter(c => c !== e.target)
.forEach(other => other.scrollTop = e.target.scrollTop);
};
});
};
4. Scroll-based animations
Create engaging animations as users scroll through content:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = entry.intersectionRatio;
}
});
}, { threshold: Array.from({length: 100}, (_, i) => i / 100) });
Performance Tips
- Use
requestAnimationFrame
for smooth animations - Implement debouncing for scroll handlers
- Leverage CSS
will-change
for better performance - Consider using CSS
contain
property
These patterns should only enhance, and not hinder, the user experience. Always test performance on various devices and ensure accessibility isn't compromised. Each pattern serves specific use cases. Choose based on your needs while considering performance and user experience.
How to hide scrollbar in TailwindCSS
TailwindCSS can also be used to hide the scrollbar. To achieve the desired effect, the following CSS code is added to the stylesheet:
@layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-x: hidden;
scrollbar-width: none;
}
}
The CodePen demo below shows how to hide the scrollbar using TailwindCSS:
See the Pen Hiding the vertical scrollbar by oviecodes (@oviecodes) on CodePen.
Whenever you’re using Tailwind, you can choose to use its utilities. When using plain CSS, you can roll out your own custom CSS.
Conditionally hiding the scrollbar
If your website has a specific section with scrollable content, maintaining a visible scrollbar is advantageous for usability and accessibility. However, as discussed earlier, a constantly visible scrollbar can compromise the aesthetics of your site’s UI in certain cases.
In such situations, you can make the scrollbar visible only upon hovering. This implies that the scrollbar remains hidden if the target section is not in use.
Take the following implementation as an example, featuring a vertically scrollable element. The markup part is straightforward and doesn’t directly affect the presentation or functionality of the scrollable element:
<div class="scrollable-content">
...
<!-- Place some content here. -->
</div>
In the CSS part, constraining the height of the .scrollable-content
div and hiding its overflow establish the foundation for making it truly scrollable. While this may initially result in an unpolished appearance, we can enhance its visual appeal by incorporating additional CSS properties.
I’m focusing on the essential CSS properties in the code below:
.scrollable-content {
max-width: 450px;
max-height: 375px;
overflow-y: hidden;
/* More presentational CSS */
}
Now, changing the vertical overflow to scroll
upon hover will ensure that the scrollbar appears only when the user intends to use the .scrollable-content
section. To provide a seamless user experience, we should extend this functionality beyond just hovering.
By incorporating the :active
and :focus
pseudo-classes, users can utilize the mouse wheel to scroll up and down the scrollable element:
.scrollable-content:hover,
.scrollable-content:active,
.scrollable-content:focus {
overflow-y: scroll;
}
The CodePen demo shows how to conditionally hide the scrollbar:
See the Pen Scrollable Elements w/ CSS by Rahul (@_rahul) on CodePen.
As evident in the example above, hovering triggers the appearance of the vertical scrollbar but also introduces a slight text and layout shift within the scrollable element. This occurs because the browser adjusts the scrollable element to accommodate the vertical scrollbar. This adjustment may disrupt the overall visual flow.
To eliminate this shift and achieve a smoother scrollbar appearance, you can integrate the scrollbar-gutter
CSS property, which essentially prepares the element for potential layout adjustments caused by scrollbars.
By setting the value to stable
, the scrollbar-gutter
property will pre-adjust the element only from the edge where the scrollbar is intended to be added. Setting it to stable both-edges
will pre-adjust it from both edges to maintain a proportional appearance:
.scrollable-content {
...
scrollbar-gutter: stable both-edges;
}
For additional enhancements, you can go the extra mile and stylize the scrollbar using the scrollbar-specific pseudo-elements. Here’s a demo showcasing a scrollable element with a decorated scrollbar without any layout shifts:
Dynamically handling scrollbar visibility with JavaScript
Here’s a quick demonstration showcasing both scrollbars hinting and toggling to maintain visibility. The demo implements the previously covered code examples and uses a bit of JavaScript for toggling between two different scrolling functionalities:
Toggle Scrollbar visibility using keyboard shortcut
The CodePen demo below show how to toggle the scrollbar on a div by pressing a combination of keys on the keyboard, which can help to improve accessibility.
See the Pen Untitled by oviecodes (@oviecodes) on CodePen.
Note that hiding or showing scrollbars with CSS won’t significantly impact page load or rendering times. Using CSS to style scrollbars might require a bit more CSS, but it won’t noticeably affect load or rendering times. The same applies to hiding scrollbars with CSS.
If you’re using a JavaScript library to manage the scrollbar display, I recommend doing that with CSS to reduce the overall page size and load time.
Toggling a scrollbar with React’s useState
.
The codepen demo below shows how React’s useState
can be used to toggle the state of a scrollbar. This technique can apply to modals and other custom scrollable divs:
The hidden impact of scrollbars and web accessibility
Hidden scrollbars have become a common aesthetic choice in modern web interfaces. However, this seemingly simple design decision can significantly impact web accessibility. For more information, check out this guide to styling CSS scrollbars. Let's explore why scrollbars matter and how to implement them responsibly.
Why scrollbars matter
Scrollbars serve as crucial visual indicators that provide users with spatial awareness of content length and their current position. For users relying on screen readers, scrollbars offer essential context about navigable content and help maintain orientation.
The accessibility challenge
Hiding scrollbars can potentially create barriers to:
- Screen reader users who lose context about content length
- Keyboard users who might miss scrollable areas
- Users with motor impairments who rely on larger click targets
Implementing accessible scrollable content
Along with dynamically hiding the scrollbar as discussed above, the techniques discussed below also help to improve accessibility.
Here's a basic implementation that balances aesthetics with accessibility: using a thin and minimally styled scrollbar:
.scrollable-container {
/* Make container scrollable */
overflow-y: auto;
max-height: 500px;
/* Enhance keyboard accessibility */
outline: none;
/* Style scrollbar for modern browsers */
scrollbar-width: thin;
scrollbar-color: #888 #f1f1f1;
}
/* Webkit browsers */
.scrollable-container::-webkit-scrollbar {
width: 6px;
}
.scrollable-container::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 3px;
}
Add ARIA attributes for screen readers:
<div
class="scrollable-container"
role="region"
aria-label="Scrollable content"
tabindex="0"
>
<!-- Content here -->
</div>
The CodePen below shows how aria-hidden
and role="region"
can be used to ensure hidden scrollbars remain accessible to screen readers:
See the Pen Aria-hidden & role region by oviecodes (@oviecodes) on CodePen.
-
role="region"
— Added to the scrollable container to indicate it is a distinct section of content that users might want to navigate to directly -
aria-label="Scrollable content"
— Provides a descriptive name for the region that screen readers can announce -
aria-hidden={!showScrollbar}
— Tells screen readers whether the scrollable content is currently hidden. This matches the visual state of the scrollbar
On the button:
-
aria-controls="scrollable-content"
— Associates the button with the content it controls -
aria-expanded={showScrollbar}
— Indicates whether the controlled content is expanded (visible) or collapsed (hidden)
To address several WCAG guidelines and keyboard accessibility requirements:
- Focus indicators (WCAG 2.4.7 Focus Visible)
- Add visible focus styles for both the button and scrollable region
- Focus indicators use a high-contrast blue outline (#4c9aff)
- Focus remains visible even when scrollbars are hidden
- Keyboard navigation (WCAG 2.1.1 Keyboard)
- Add
tabIndex={0}
to make the scrollable region focusable - Users can navigate to the content using Tab key
- Arrow keys work for scrolling when focused
- Add
- Touch target size (WCAG 2.5.5 Target Size)
- Button has minimum dimensions of 44x44 pixels
- Ensures adequate touch target size for mobile users
- Visual contrast (WCAG 1.4.11 Non-text Contrast)
- Border colors meet 3:1 minimum contrast ratio
- Focus indicators exceed minimum contrast requirements
- Content structure (WCAG 1.3.1 Info and Relationships)
-
role="region"
identifies the scrollable area -
aria-label
provides context -
aria-control
s andaria-expanded
maintain relationships
-
Here’s a CodePen demo that shows the implementation:
Best practices for CSS scrollbars
- Keep scrollbars visible but style them minimally
- Add keyboard support for navigation
- Include ARIA labels to provide context
- Test with screen readers and keyboard navigation
Performance considerations when toggling scrollbars
When implementing scrollbar visibility toggling, developers often overlook the performance implications. The sudden appearance or disappearance of scrollbars can cause unexpected layout shifts, leading to poor user experience and affecting your site's Core Web Vitals scores.
Understanding layout shifts
Scrollbars take up space in the viewport. In most browsers, showing or hiding them changes the available content width, which can cause surrounding elements to shift. This creates what Google calls Cumulative Layout Shift (CLS), a key metric for measuring user experience.
Here's how to calculate and compensate for scrollbar width:
const getScrollbarWidth = () => {
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.overflow = 'scroll';
document.body.appendChild(outer);
const inner = document.createElement('div');
outer.appendChild(inner);
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
outer.parentNode.removeChild(outer);
return scrollbarWidth;
};
Preventing layout jank
To create a smooth scrollbar toggle experience, we need to compensate for the scrollbar width. Here's a solution:
:root {
--scrollbar-width: 0px;
}
.scroll-wrapper {
position: relative;
width: 300px;
padding-right: var(--scrollbar-width);
}
.content {
height: 200px;
overflow-y: auto;
transition: margin-right 0.2s ease;
}
The wrapper maintains a stable width while the content area adjusts smoothly. Using CSS Custom Properties allows for dynamic updates:
// Calculate once on load
const scrollbarWidth = getScrollbarWidth();
document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`);
A good design isn't just about aesthetics, it's about creating experiences that work for everyone.
Conclusion
You now have a good grasp of hiding scrollbars with CSS while maintaining smooth scrolling and accessibility. While hiding scrollbars may be suitable for certain UI and aesthetic considerations, it’s essential to remember that keeping scrollbars visible in scrollable sections helps users easily locate and navigate content, thereby enhancing accessibility.
I hope this article has been helpful to you. See you in the next one!
Is your frontend hogging your users' CPU?
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Top comments (0)