DEV Community

Cover image for How to use CSS to hide scrollbars without impacting scrolling
Megan Lee for LogRocket

Posted on • Originally published at blog.logrocket.com

How to use CSS to hide scrollbars without impacting scrolling

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
} 
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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'));
};
Enter fullscreen mode Exit fullscreen mode

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);
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

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);
    };
  });
};
Enter fullscreen mode Exit fullscreen mode

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) });
Enter fullscreen mode Exit fullscreen mode

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; 
  } 
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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 */
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Add ARIA attributes for screen readers:

<div 
  class="scrollable-container"
  role="region"
  aria-label="Scrollable content"
  tabindex="0"
>
  <!-- Content here -->
</div>
Enter fullscreen mode Exit fullscreen mode

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.

  1. role="region"— Added to the scrollable container to indicate it is a distinct section of content that users might want to navigate to directly
  2. aria-label="Scrollable content" — Provides a descriptive name for the region that screen readers can announce
  3. aria-hidden={!showScrollbar} — Tells screen readers whether the scrollable content is currently hidden. This matches the visual state of the scrollbar

On the button:

  1. aria-controls="scrollable-content"— Associates the button with the content it controls
  2. 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
  • 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-controls and aria-expanded maintain relationships

Here’s a CodePen demo that shows the implementation:

Best practices for CSS scrollbars

  1. Keep scrollbars visible but style them minimally
  2. Add keyboard support for navigation
  3. Include ARIA labels to provide context
  4. 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;
};
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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`);
Enter fullscreen mode Exit fullscreen mode

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 CSS Demo

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)