785

Can CSS be used to hide the scroll bar? How would you do this?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ANP
  • 13,969
  • 21
  • 53
  • 78

21 Answers21

1039

WebKit supports scrollbar pseudo elements that can be hidden with standard CSS rules:

#element::-webkit-scrollbar {
    display: none;
}

If you want all scrollbars hidden, use

::-webkit-scrollbar {
    display: none;
}

I'm not sure about restoring - this did work, but there might be a right way to do it:

::-webkit-scrollbar {
    display: block;
}

You can of course always use width: 0, which can then be easily restored with width: auto, but I'm not a fan of abusing width for visibility tweaks.

Firefox 64 now supports the experimental scrollbar-width property by default (63 requires a configuration flag to be set). To hide the scrollbar in Firefox 64:

#element {
    scrollbar-width: none;
}

To see if your current browser supports either the pseudo element or scrollbar-width, try this snippet:

.content {
  /* These rules create an artificially confined space, so we get
     a scrollbar that we can hide. They are not directly involved in
     hiding the scrollbar. */

  border: 1px dashed gray;
  padding: .5em;

  white-space: pre-wrap;
  height: 5em;
  overflow-y: scroll;
}

.content {
  /* This is the magic bit for Firefox */
  scrollbar-width: none;
}

.content::-webkit-scrollbar {
  /* This is the magic bit for WebKit */
  display: none;
}
<div class='content'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris eu
urna et leo aliquet malesuada ut ac dolor. Fusce non arcu vel ligula
fermentum sodales a quis sapien. Sed imperdiet justo sit amet venenatis
egestas. Integer vitae tempor enim. In dapibus nisl sit amet purus congue
tincidunt. Morbi tincidunt ut eros in rutrum. Sed quam erat, faucibus
vel tempor et, elementum at tortor. Praesent ac libero at arcu eleifend
mollis ut eget sapien. Duis placerat suscipit eros, eu tempor tellus
facilisis a. Vivamus vulputate enim felis, a euismod diam elementum
non. Duis efficitur ac elit non placerat. Integer porta viverra nunc,
sed semper ipsum. Nam laoreet libero lacus.

Sed sit amet tincidunt felis. Sed imperdiet, nunc ut porta elementum,
eros mi egestas nibh, facilisis rutrum sapien dolor quis justo. Quisque
nec magna erat. Phasellus vehicula porttitor nulla et dictum. Sed
tincidunt scelerisque finibus. Maecenas consequat massa aliquam pretium
volutpat. Duis elementum magna vel velit elementum, ut scelerisque
odio faucibus.
</div>

(Note that this is not really a correct answer to the question, because it hides the horizontal bars as well, but that's what I was looking for when Google pointed me here, so I figured I'd post it anyway.)

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Peter
  • 24,684
  • 4
  • 36
  • 46
  • 13
    Just what I was looking for since I really wanted to hide the scrollbars but have the elements still scrollable (e.g. up/down keys) – Mathias Jan 25 '13 at 20:35
  • 7
    this should be the best answer since other solutions don't let you scroll – nuway Apr 04 '13 at 20:53
  • 7
    Does this support other browsers apart from webkit? Because it does not work in mozilla. – Rupam Datta Apr 08 '13 at 06:25
  • 2
    It's webkit only. Hence the vendor prefix. – Peter Apr 08 '13 at 08:36
  • 12
    There is a [feature request](https://bugzilla.mozilla.org/show_bug.cgi?id=77790) on the Mozilla tracker though. You may be able to speed up the implementation by voting for it over there :) – Peter May 28 '13 at 07:14
  • The Mozilla feature request has really little votes! Wish more people voted for this :/ – Xethron Jun 03 '13 at 21:43
  • its not working on mozilla.but i liked it ty for answer. – erginduran Dec 25 '15 at 19:32
  • I believe that this is the correct way to reset this. ::-webkit-scrollbar { display: initial; } – Dennis Bartlett Oct 18 '16 at 15:47
  • Tried it in IE11 and it does not work, all the scrollbars are shown. I tried it in Opera and Google Chrome, it worked perfectly fine. This is great answer though. Thanks! – almost a beginner Dec 06 '16 at 01:29
  • 3
    THIS IS THE CORRECT ANSWER! As others are missing. The problem is not just hiding the scrollbar, but how the overflow affects other styles. I ran into this exact same problem in our app. We do NOT want overflow auto on 99% of the app, however there is a help section where you want the user to be able to scroll down. Since the body has overflow:hidden, the only wan to handle this was an ng-class on the root, or thanks to this guys, just using some CSS. – Leon Gaban Dec 15 '16 at 17:03
  • 1
    I tried all kinds of stuff for a very long time now, ended up using [perfect-scrollbar](https://www.npmjs.com/package/ngx-perfect-scrollbar) – zed Feb 24 '19 at 16:17
  • Try out `display: unset` instead of `display: block` – KTibow Oct 17 '20 at 17:49
540

Yes, sort of..

When you ask the question, "Can the scroll-bars of a browser be removed in some way, rather than simply hidden or camouflaged", everyone will say "Not possible" because it is not possible to remove the scrollbars from all browsers in a compliant and cross-compatible way, and then there's the whole argument of usability.

However, it is possible to prevent the browser from ever having the need to generate and display scrollbars if you do not allow your webpage to overflow.

This just means that we have to proactively substitute the same behavior that the browser would typically do for us and tell the browser thanks but no thanks buddy. Rather than try to remove scrollbars (which we all know is not possible) we can avoid scrolling (perfectly feasible) and scroll within the elements that we make and have more control over.

Create a div with overflow hidden. Detect when the user attempts to scroll, but is unable to because we've disabled the browsers ability to scroll with overflow: hidden.. and instead move the content up using JavaScript when this occurs. Thereby creating our own scrolling without the browsers default scrolling or use a plugin like iScroll.

---

For the sake of being thorough; all the vendor specific ways of manipulating scroll-bars:

Internet Explorer 5.5+

*These properties were never part of the CSS specification, nor were they ever approved or vendor prefixed, but they work in Internet Explorer and Konqueror. These can also be set locally in the user style sheet for each application. In Internet Explorer you find it under the "Accessibility" tab, in Konqueror under the "Stylesheets" tab.

body, html { /* These are defaults and can be replaced by hexadecimal color values */
    scrollbar-base-color: aqua;
    scrollbar-face-color: ThreeDFace;
    scrollbar-highlight-color: ThreeDHighlight;
    scrollbar-3dlight-color: ThreeDLightShadow;
    scrollbar-shadow-color: ThreeDDarkShadow;
    scrollbar-darkshadow-color: ThreeDDarkShadow;
    scrollbar-track-color: Scrollbar;
    scrollbar-arrow-color: ButtonText;
}

As of Internet Explorer 8 these properties were vendor prefixed by Microsoft, but they were still never approved by W3C.

-ms-scrollbar-base-color
-ms-scrollbar-face-color
-ms-scrollbar-highlight-color
-ms-scrollbar-3dlight-color
-ms-scrollbar-shadow-color
-ms-scrollbar-darkshadow-color
-ms-scrollbar-base-color
-ms-scrollbar-track-color

Further details about Internet Explorer

Internet Explorer makes scroll available which sets whether or not to disable or enable scroll bars; it can also be used to get the value of the position of the scroll bars.

With Microsoft Internet Explorer 6 and later, when you use the !DOCTYPE declaration to specify standards-compliant mode, this attribute applies to the HTML element. When standards-compliant mode is not specified, as with earlier versions of Internet Explorer, this attribute applies to the BODY element, NOT the HTML element.

It's also worth noting that when working with .NET the ScrollBar class in System.Windows.Controls.Primitives in the Presentation framework is responsible for rendering the scrollbars.

http://msdn.microsoft.com/en-us/library/ie/ms534393(v=vs.85).aspx


WebKit

WebKit extensions related to scroll-bar customization are:

::-webkit-scrollbar {}             /* 1 */
::-webkit-scrollbar-button {}      /* 2 */
::-webkit-scrollbar-track {}       /* 3 */
::-webkit-scrollbar-track-piece {} /* 4 */
::-webkit-scrollbar-thumb {}       /* 5 */
::-webkit-scrollbar-corner {}      /* 6 */
::-webkit-resizer {}               /* 7 */

Enter image description here

These can each be combined with additional pseudo-selectors:

  • :horizontal – The horizontal pseudo-class applies to any scrollbar pieces that have a horizontal orientation.
  • :vertical – The vertical pseudo-class applies to any scrollbar pieces that have a vertical orientation.
  • :decrement – The decrement pseudo-class applies to buttons and track pieces. It indicates whether or not the button or track piece will decrement the view’s position when used (e.g., up on a vertical scrollbar, left on a horizontal scrollbar).
  • :increment – The increment pseudo-class applies to buttons and track pieces. It indicates whether or not a button or track piece will increment the view’s position when used (e.g., down on a vertical scrollbar, right on a horizontal scrollbar).
  • :start – The start pseudo-class applies to buttons and track pieces. It indicates whether the object is placed before the thumb.
  • :end – The end pseudo-class applies to buttons and track pieces. It indicates whether the object is placed after the thumb.
  • :double-button – The double-button pseudo-class applies to buttons and track pieces. It is used to detect whether a button is part of a pair of buttons that are together at the same end of a scrollbar. For track pieces it indicates whether the track piece abuts a pair of buttons.
  • :single-button – The single-button pseudo-class applies to buttons and track pieces. It is used to detect whether a button is by itself at the end of a scrollbar. For track pieces it indicates whether the track piece abuts a singleton button.
  • :no-button – Applies to track pieces and indicates whether or not the track piece runs to the edge of the scrollbar, i.e., there is no button at that end of the track.
  • :corner-present – Applies to all scrollbar pieces and indicates whether or not a scrollbar corner is present.
  • :window-inactive – Applies to all scrollbar pieces and indicates whether or not the window containing the scrollbar is currently active. (In recent nightlies, this pseudo-class now applies to ::selection as well. We plan to extend it to work with any content and to propose it as a new standard pseudo-class.)

Examples of these combinations

::-webkit-scrollbar-track-piece:start { /* Select the top half (or left half) or scrollbar track individually */ }
::-webkit-scrollbar-thumb:window-inactive { /* Select the thumb when the browser window isn't in focus */ }
::-webkit-scrollbar-button:horizontal:decrement:hover { /* Select the down or left scroll button when it's being hovered by the mouse */ }

Further details about Chrome

addWindowScrollHandler public static HandlerRegistration addWindowScrollHandler(Window.ScrollHandler handler)

  Adds a Window.ScrollEvent handler Parameters:   handler - the handler Returns:   returns the handler registration [source](http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/Window.html#addWindowScrollHandler(com.google.gwt.user.client.Window.ScrollHandler) )


Mozilla

Mozilla does have some extensions for manipulating the scroll-bars, but they are all recommended not to be used.

  • -moz-scrollbars-none They recommend using overflow:hidden in place of this.
  • -moz-scrollbars-horizontal Similar to overflow-x
  • -moz-scrollbars-vertical Similar to overflow-y
  • -moz-hidden-unscrollable Only works internally within a users profile settings. Disables scrolling XML root elements and disables using arrow keys and mouse wheel to scroll web pages.

  • Mozilla Developer Docs on 'Overflow'

Further details about Mozilla

This is not really useful as far as I know, but it's worth noting that the attribute which controls whether or not scrollbars are displayed in Firefox is (reference link):

  • Attribute:       scrollbars
  • Type:              nsIDOMBarProp
  • Description:  The object that controls whether or not scrollbars are shown in the window. This attribute is "replaceable" in JavaScript. Read only

Last but not least, padding is like magic.

As has been previously mentioned in some other answers, here is an illustration which is sufficiently self-explanatory.

Enter image description here


History lesson

Scroll bars

Just because I'm curious, I wanted to learn about the origin of scrollbars, and these are the best references I found.

Miscellaneous

In an HTML5 specification draft, the seamless attribute was defined to prevent scroll-bars from appearing in iFrames so that they could be blended with surrounding content on a page. Though this element does not appear in the latest revision.

The scrollbar BarProp object is a child of the window object and represents the user interface element that contains a scrolling mechanism, or some similar interface concept. window.scrollbars.visible will return true if the scroll bars are visible.

interface Window {
  // The current browsing context
  readonly attribute WindowProxy window;
  readonly attribute WindowProxy self;
           attribute DOMString name;
  [PutForwards=href] readonly attribute Location location;
  readonly attribute History history;
  readonly attribute UndoManager undoManager;
  Selection getSelection();
  [Replaceable] readonly attribute BarProp locationbar;
  [Replaceable] readonly attribute BarProp menubar;
  [Replaceable] readonly attribute BarProp personalbar;
  [Replaceable] readonly attribute BarProp scrollbars;
  [Replaceable] readonly attribute BarProp statusbar;
  [Replaceable] readonly attribute BarProp toolbar;
  void close();
  void focus();
  void blur();
  // Truncated

The History API also includes features for scroll restoration on page navigation to persist the scroll position on page load.

window.history.scrollRestoration can be used to check the status of scrollrestoration or change its status (appending ="auto"/"manual". Auto is the default value. Changing it to manual means that you as the developer will take ownership of any scroll changes that may be required when a user traverses the app's history. If you need to, you can keep track of the scroll position as you push history entries with history.pushState().

---

Further reading:

Examples

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
davidcondrey
  • 29,530
  • 14
  • 105
  • 129
  • 28
    This answer would apply to significantly more browsers (namely IE) rather than the currently upvoted answer. – Matt Jensen Sep 25 '14 at 17:15
  • Great addition. Actually implemented that same solution today! May be worth mentioning that the other element should be overflow: hidden; – Matt Jensen Sep 25 '14 at 22:51
  • 2
    This is the correct, full featured answer. I explains that if you simply want to stop a user from scrolling you can use the overflow rule. You can also implement your own home built scrolling feature. If that is not enough you can set scroll bar properties directly using different rules for different browsers. – newshorts Jul 12 '16 at 17:19
  • 1
    while this is an incredibly well-thought out answer, and very detailed, and many resources linked, there are massive problems for assistive technology users when you disable scroll and use javascript to handle all the scrolling. If you do not also set focus to an element every time you scroll for the user, then your AT user will be completely lost. Also, your user has now lost all fine-tuned control over what (s)he sees. Very poor UX to take over scrolling for your user. – ShiningLight Sep 25 '18 at 17:47
  • Firefox Quantum 63.0.1 on MacOS High Sierra, doesn't hide the scrollbar even with the 'overflow: -moz-scrollbars-none' rule. Anyone knows solution for this? All the other browser seem to work with the suggested solutions. – Simona Adriani Nov 07 '18 at 11:52
  • Dude! How? It boggles my mind how could anyone write an answer like this. A complete handbook on scrollbars! Congratulations! – Omar Omeiri Apr 18 '21 at 05:41
441

Set overflow: hidden; on the body tag like this:

<style type="text/css">
    body {
        overflow: hidden;
    }
</style>

The code above hides both the horizontal and vertical scrollbar.

If you want to hide only the vertical scrollbar, use overflow-y:

<style type="text/css">
    body {
        overflow-y: hidden;
    }
</style>

And if you want to hide only the horizontal scrollbar, use overflow-x:

<style type="text/css">
    body {
        overflow-x: hidden;
    }
</style>

Note: It'll also disable the scrolling feature. Refer to the below answers if you just want to hide the scroll bar, but not the scroll feature.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
jao
  • 17,118
  • 13
  • 58
  • 92
  • 4
    There is no "none" option for overflow property. Available options include: visible, hidden, scroll, auto, inherit. – Sergiy Sokolenko Jul 21 '10 at 06:16
  • 1354
    Actually, this is not completely the right answer : overflow:hidden doesn't "hide" the scrollbar. It also stop scrolling feature on the page. That's not exactly what we ask for. – adriendenat Mar 13 '13 at 21:41
  • 18
    In Chrome, when body overflow is set to `hidden` scrolling will work with a mouse scroller wheel. In Firefox, scrolling will not work with a mouse scroller wheel, it took me a while to figure this out. – Doug Molineux Aug 19 '13 at 20:17
  • 4
    Just a heads up, designers for firefox, chrome, and others say that The scrollbar is a touchy subject, it "crosses" the page's boundary into the window manager's domain. Technically speaking, web pages aren't supposed to be able to modify the user's windowing widgets, just like you cant tell a web page to use different graphics for buttons of a titlebar for a window or have a different dialog colors, etc... some extensions do let you do this, but its a pretty big debate, look on **MDN** for now 'depreciated' section of -moz extensions that were considered intrusive on users' operating systems. – osirisgothra Nov 30 '13 at 03:38
  • Not working in Chrome v31. I don't think this is the intended use case for overflow:hidden. – Trevor Dec 13 '13 at 01:06
  • 2
    Technically a correct answer, but the desired behavior is only accomplished as a side effect of enabling a behavior not necessarily desired. – Jackson Oct 02 '14 at 20:53
  • 15
    I don't see the point in asserting that `overflow: hidden` disables scrolling. If someone wants to hide the scrollbar, then presumably they deem the control unnecessary because *there is no content to scroll in the first place*. Or perhaps *they just don't want to allow scrolling altogether*. – BoltClock Nov 24 '14 at 16:33
  • 1
    Besides, the assertions aren't entirely correct. You can still scroll the element through unconventional means such as tabbing through any focusable descendants, or by using JavaScript to force a scroll. If you still want the user to have the ability to scroll the element somehow, you can always wire up a new scrolling mechanism using JavaScript. Or, you know, you could just not hide the default scrollbar - which the browser draws for you, automatically and completely for free! - to begin with. – BoltClock Nov 24 '14 at 16:34
  • 42
    To me the assertion is perfectly valid, as the question is to *hide the scrollbar*, not to *disable scrolling*. – sboisse Nov 25 '14 at 19:42
  • @BoltClock An example use case of this being valid is for responsive sites, on mobiles the it is clear to use your finger, where as on a desktop it wouldn't be required but would still show. – tim.baker Feb 12 '16 at 14:20
  • 2
    @tim.baker: Most mobile platforms draw scrollbars only on scroll, so I don't see a problem there. On desktop you can set overflow: auto if you want the scrollbar to show only when necessary. Unless I misunderstand you... – BoltClock Feb 12 '16 at 15:22
  • 2
    @sboisse: You can't hide the only visual cue to a desktop user that scrolling is possible and still expect them to be able to scroll (this isn't a problem on mobile, as I've just now stated in reply to a recent comment). Even if you don't believe my claim that overflow: hidden does not in fact disable scrolling, Googling `javascript scrollbar` turns up dozens of solutions including [this example](http://baijs.com/tinyscrollbar/examples/nojquery) where you can clearly see that the .viewport element has overflow: hidden, and yet it can be scrolled (with a UX far worse than the default, no less). – BoltClock Feb 12 '16 at 15:39
  • @BoltClock: Overflow: hidden does disable scrolling, else the mousewheel would work in both boxes in the fiddle: https://jsfiddle.net/cjko9ryz/ and onscroll events would trigger as well. Of course workarounds exist with Javascript, but are never as robust, and sometimes, the same behaviour just can't be met as with the native scrollbar. – sboisse Feb 12 '16 at 19:37
  • 1
    @sboisse: I think we have to be clear what disabling scrolling actually entails in this context - let's agree that it means "disabling scrolling UI". That is, overflow: hidden prevents the *user* from scrolling an element, and it does that by 1) preventing the mousewheel from scrolling the element 2) hiding the scrollbars, the only visual cue to the user that they can scroll. It's hard to glean from the original question, but if the requirement *is* to hide the scrollbar while still allowing the user to scroll, then I can only point readers back to my very first comment here. – BoltClock Feb 13 '16 at 01:54
  • 2
    @BoltClock: There are so many situations why a developer might want to have a scrollable element without the native scrollbar. For example, implementing another visual cue to replace the native scrollbar because the native scrollbar cannot be styled in a harmonious way with a website theme is probably the most obvious use case where this would be useful, and probably why so many people came here on that page, looking for a way to do this. By saying this, you are saying the native scrollbar should be the only acceptable visual cue for a scrollable element. It does not make sense to me. – sboisse Feb 16 '16 at 16:39
  • ANP wants to hide scroll-bar not text. This disables scrolling. – Ani Menon Apr 22 '16 at 14:59
  • 2
    @BoltClock this is ages old, but im gonna throw an example out there. I have a card of fixed height, with content that overflows. Scrollbar looks terrible with my design. I want to hide the scrollbar and create my own visual cue without having to develop or use a third party js function that people would need to have downloaded, and could be blocked by disabling javascript. Its much easier to use a little CSS to hide the scroll bar, use the default scroll behavior, and add a small down arrow at the bottom of the pane holding overflow content. – Drew Major May 11 '16 at 16:17
  • 2
    http://stackoverflow.com/a/23771140/1616697 this should be the correct answer by thgaskell – Lahiru Jul 06 '16 at 04:37
  • 1
    Check Peter answer for this question (Below. It is the most up voted one). That one should be the accepted answer. – Ruben Jan 26 '17 at 02:32
  • 1
    The reason that I want to hide the scrollbar is because the browsers make such ugly scrollbars these days. – quemeful Feb 08 '17 at 14:35
  • This does not work to hide scroll bars for certain dynamic elements like resizeable textarea. – Dshiz Mar 19 '17 at 05:50
  • You need to also set height: 100vh as well as overflow: hidden, this hides the scrollbar but desn't stop scrolling – Danielle Davis Jun 09 '18 at 22:11
  • I hate this answer. – dawn Jan 30 '19 at 20:40
110

You can accomplish this with a wrapper div that has its overflow hidden, and the inner div set to auto.

To remove the inner div's scroll bar, you can pull it out of the outer div's viewport by applying a negative margin to the inner div. Then apply equal padding to the inner div so that the content stays in view.

JSFiddle

###HTML

<div class="hide-scroll">
    <div class="viewport">
        ...
    </div>
</div>

###CSS

.hide-scroll {
    overflow: hidden;
}

.viewport {
    overflow: auto;

    /* Make sure the inner div is not larger than the container
     * so that we have room to scroll.
     */
    max-height: 100%;

    /* Pick an arbitrary margin/padding that should be bigger
     * than the max scrollbar width across the devices that 
     * you are supporting.
     * padding = -margin
     */
    margin-right: -100px;
    padding-right: 100px;
}
thgaskell
  • 11,608
  • 5
  • 30
  • 36
  • 8
    This should be the accepted answer imo. Only thing i had to add was `height: inherited` in the `.viewport` css. – Post Impatica Oct 27 '15 at 14:38
  • 4
    The only problem with this answer is the "dead" space left by the moved scrollbar, because we don't know actually the scrollbar width, in order to subtracts it from the padding. – Frondor Apr 26 '16 at 23:13
  • 3
    Plus, you don't need to use fixed values for the padding and margins. `100%` is more versatile and does the job. – Frondor Apr 26 '16 at 23:29
  • Worked in IE11, Operah and Chrome, haven't tested Firefox yet. This is great answer, +1. – almost a beginner Dec 06 '16 at 01:39
  • why `-100px` and `100px`?? – oldboy Jun 21 '19 at 02:07
  • @BugWhisperer the child `.viewport` element is pushing its sidebar _outside_ of the `.hide-scroll` (which is then hidden). Here's an example fiddle: https://jsfiddle.net/x4uom12h/ – thgaskell Jun 21 '19 at 10:13
  • i know why it works. im just wondering why those specific values? do you also use box-sizing or? – oldboy Jun 21 '19 at 17:27
  • As the comment in the code mentions. the choice of `100px` is arbitrary. It just needs to be larger than the width of the scrollbar across all browser scrollbars you're supporting. This answer doesn't use `box-sizing`. However, if your `.viewport` component has the width set and `box-sizing: border-box` is set, this answer wouldn't work. You may have to do something like: `width: calc(100% + 100px)` in order for it to extend outside of the `.hide-scroll` container. – thgaskell Jun 22 '19 at 23:48
91

Here's my solution, which theoretically covers all modern browsers:

html {
    scrollbar-width: none; /* For Firefox */
    -ms-overflow-style: none; /* For Internet Explorer and Edge */
}

html::-webkit-scrollbar {
    width: 0px; /* For Chrome, Safari, and Opera */
}

html can be replaced with any element you want to hide the scrollbar of.

Note: I've skimmed the other 19 answers to see if the code I'm posting has already been covered, and it seems like no single answer sums up the situation as it stands in 2019, although plenty of them go into excellent detail. Apologies if this has been said by someone else and I missed it.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Wilf
  • 1,069
  • 10
  • 11
66

This works for me with simple CSS properties:

.container {
    -ms-overflow-style: none;  // Internet Explorer 10+
    scrollbar-width: none;  // Firefox
}
.container::-webkit-scrollbar { 
    display: none;  // Safari and Chrome
}

For older versions of Firefox, use: overflow: -moz-scrollbars-none;

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Hristo Eftimov
  • 9,403
  • 11
  • 44
  • 71
  • 2
    Unfortunately, this doesn't work in FireFox 48.0.2 on macOS Sierra. If you do `overflow: -moz-scrollbars-none;` then you successfully remove the scrollbar, but you also remove the ability to scroll. You might as well just set `overflow: hidden` to the `.container`. – Martyn Chamberlin Oct 19 '16 at 20:27
  • 1
    Oh, and from https://developer.mozilla.org/en-US/docs/Web/CSS/overflow, we read this about `-moz-scrollbars-none`: "This is an obsolete API and is no longer guaranteed to work." – Martyn Chamberlin Oct 19 '16 at 20:30
  • 1
    I have updated my answer with the latest support for Firefox :) – Hristo Eftimov Apr 01 '19 at 06:48
21

I think I found a workaround for you guys if you're still interested. This is my first week, but it worked for me...

<div class="contentScroller">
    <div class="content">
    </div>
</div>

.contentScroller {overflow-y: auto; visibility: hidden;}
.content {visibility: visible;}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ben Yo
  • 227
  • 2
  • 2
  • Works for me in chrome and firefox, haven't tested IE or any other browser. http://jsfiddle.net/8xtfk729/ – Ben Davis Jan 19 '15 at 04:31
  • 1
    On chrome (v54 at least), this disables scrolling via scroll wheel for some reason. Scroll via arrow keys, home/end/pg down/pg up, touch flick, and mouse 3 click n drag still works. – House3272 Dec 06 '16 at 00:26
  • This answer is legit, it actually works and appears to work across browsers. – Sam Jan 09 '18 at 21:06
  • That hides the whole div on my side – Jonny Feb 13 '18 at 22:48
16

If you're looking for a solution to hide a scrollbar for mobile devices, follow Peter's answer!

Here's a jsfiddle, which uses the solution below to hide a horizontal scrollbar.

.scroll-wrapper{
    overflow-x: scroll;
}
.scroll-wrapper::-webkit-scrollbar { 
    display: none; 
}

It was tested on a Samsung tablet with Android 4.0.4 (Ice Cream Sandwich, both in the native browser and Chrome) and on an iPad with iOS 6 (both in Safari and Chrome).

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Alex
  • 2,245
  • 3
  • 23
  • 33
13

As the other people already said, use CSS overflow.

But if you still want the user to be able to scroll that content (without the scrollbar being visible) you have to use JavaScript.

Se my answer here for a solution: Hide scrollbar while still being able to scroll with mouse/keyboard

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Peter Örneholm
  • 2,831
  • 18
  • 24
  • 2
    This is the correct answer and should be first. Everything above this does not answer the question at hand. OP does not ask for scrolling disabled, zhe wants to hide the scrollbar. – pixelpax Mar 27 '17 at 21:31
11

In addition to Peter's answer:

#element::-webkit-scrollbar {
    display: none;
}

This will work the same for Internet Explorer 10:

 #element {
      -ms-overflow-style: none;
 }
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
JoshW
  • 141
  • 1
  • 2
11

Use the CSS overflow property:

.noscroll {
  width: 150px;
  height: 150px;
  overflow: auto; /* Or hidden, or visible */
}

Here are some more examples:

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Sergiy Sokolenko
  • 5,398
  • 31
  • 35
10

Cross browser approach to hiding the scrollbar.

It was tested on Edge, Chrome, Firefox, and Safari

Hide scrollbar while still being able to scroll with mouse wheel!

Codepen

/* Make parent invisible */
#parent {
    visibility: hidden;
    overflow: scroll;
}

/* Safari and Chrome specific style. Don't need to make parent invisible, because we can style WebKit scrollbars */
#parent:not(*:root) {
  visibility: visible;
}

/* Make Safari and Chrome scrollbar invisible */
#parent::-webkit-scrollbar {
  visibility: hidden;
}

/* Make the child visible */
#child {
    visibility: visible;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Blake Plumb
  • 5,667
  • 2
  • 28
  • 49
  • 1
    an explanation as to how this works would be appreciated – playing with parent/child visibility to hide the scroll bar is horrible – JackyJohnson Nov 07 '16 at 12:23
  • 1
    @believesInSanta I added comments and codepen to explain better. I don't agree with your assessment that playing with visibility is a horrible way to hide the scrollbar. I understand that it is a hack, but the proper way to achieve this effect would be if all the browsers supported a way to style the scrollbar separately like chrome and safari allow. – Blake Plumb Nov 10 '16 at 19:32
  • 2
    I just felt in love with your solution. It perfectly works (used in apps which are design to be used by modern browsers). Thank you so much! – Maxime Lafarie Aug 01 '17 at 22:36
7

I just thought I'd point out to anyone else reading this question that setting overflow: hidden (or overflow-y) on the body element didn't hide the scrollbars for me.

I had to use the html element.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Brad Azevedo
  • 321
  • 2
  • 8
  • 3
    I can't remember exactly since it was a couple of months ago, but I believe setting the overflow on the body was working in Chrome, but not Firefox (or vice-versa). Using the HTML tag worked on both, though. – Brad Azevedo Oct 08 '12 at 16:30
  • From memory this may be a quirks mode difference. – thomasrutter Sep 21 '13 at 01:43
7

If you want scrolling to work, before hiding scrollbars, consider styling them. Modern versions of OS X and mobile OS's have scrollbars that, while impractical for grabbing with a mouse, are quite beautiful and neutral.

To hide scrollbars, a technique by John Kurlak works well except for leaving Firefox users who don't have touchpads with no way to scroll unless they have a mouse with a wheel, which they probably do, but even then they can usually only scroll vertically.

John's technique uses three elements:

  • An outer element to mask the scrollbars.
  • A middle element to have the scrollbars.
  • And a content element to both set the size of the middle element and make it have scrollbars.

It must be possible to set the size of the outer and content elements the same which eliminates using percentages, but I can't think of anything else that won't work with the right tweaking.

My biggest concern is whether all versions of browsers set scrollbars to make visible overflowed content visible. I have tested in current browsers, but not older ones.

Pardon my SASS ;P

%size {
    // set width and height
}

.outer {
    // mask scrollbars of child
    overflow: hidden;
    // set mask size
    @extend %size;
    // has absolutely positioned child
    position: relative;
}

.middle {
    // always have scrollbars.
    // don't use auto, it leaves vertical scrollbar showing
    overflow: scroll;
    // without absolute, the vertical scrollbar shows
    position: absolute;
}
// prevent text selection from revealing scrollbar, which it only does on
// some webkit based browsers.
.middle::-webkit-scrollbar {
    display: none;
}

.content {
    // push scrollbars behind mask
    @extend %size;
}

Testing

OS X is 10.6.8. Windows is Windows 7.

  • Firefox 32.0 Scrollbars hidden. Arrow keys don't scroll, even after clicking to focus, but mouse wheel and two fingers on trackpad do. OS X and Windows.
  • Chrome 37.0 Scrollbars hidden. Arrow keys work after clicking to focus. Mouse wheel and trackpad work. OS X and Windows.
  • Internet Explorer 11 Scrollbars hidden. Arrow keys work after clicking to focus. Mouse wheel works. Windows.
  • Safari 5.1.10 Scrollbars hidden. Arrow keys work after clicking to focus. Mouse wheel and trackpad work. OS X.
  • Android 4.4.4 and 4.1.2. Scrollbars hidden. Touch scrolling works. Tried in Chrome 37.0, Firefox 32.0, and HTMLViewer on 4.4.4 (whatever that is). In HTMLViewer, the page is the size of the masked content and can be scrolled too! Scrolling interacts acceptably with page zooming.
Seth W. Klein
  • 163
  • 2
  • 5
  • 1
    Unrelated note (as far as the question goes). In this instance, you should be using @extend versus @include. So instead of `@mixin{}`, you'd do `%size{}` then in the css selectors, call `@extend %size;`. Mixins are typically used when your pulling in variables to return an result. Placeholders (aka @extend) are meant for simple repeated code like this - where no "function" is needed. – Mike Barwick Dec 12 '14 at 04:24
  • 1
    I edited to use @extend. The result is probably less understandable to people who don't know SCSS, but well enough. – Seth W. Klein Mar 12 '15 at 20:35
6

Copy this CSS code to the customer code for hiding the scroll bar:

<style>

    ::-webkit-scrollbar {
       display: none;
    }

    #element::-webkit-scrollbar {
       display: none;
    }

</style>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Huu Phong Nguyen
  • 719
  • 6
  • 10
5

My HTML is like this:

<div class="container">
  <div class="content">
  </div>
</div>

Add this to your div where you want to hide the scrollbar:

.content {
  position: absolute;
  right: -100px;
  overflow-y: auto;
  overflow-x: hidden;
  height: 75%; /* This can be any value of your choice */
}

And add this to the container

.container {
  overflow-x: hidden;
  max-height: 100%;
  max-width: 100%;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Timo
  • 81
  • 1
  • 5
5

I wrote a WebKit version with some options like auto hide, little version, scroll only-y, or only-x:

._scrollable{
    @size: 15px;
    @little_version_ratio: 2;
    @scrollbar-bg-color: rgba(0,0,0,0.15);
    @scrollbar-handler-color: rgba(0,0,0,0.15);
    @scrollbar-handler-color-hover: rgba(0,0,0,0.3);
    @scrollbar-coner-color: rgba(0,0,0,0);

    overflow-y: scroll;
    overflow-x: scroll;
    -webkit-overflow-scrolling: touch;
    width: 100%;
    height: 100%;

    &::-webkit-scrollbar {
        background: none;
        width: @size;
        height: @size;
    }

    &::-webkit-scrollbar-track {
        background-color:@scrollbar-bg-color;
        border-radius: @size;
    }

    &::-webkit-scrollbar-thumb {
        border-radius: @size;
        background-color:@scrollbar-handler-color;
        &:hover{
            background-color:@scrollbar-handler-color-hover;
        }
    }

    &::-webkit-scrollbar-corner {
      background-color: @scrollbar-coner-color;
    }

    &.little{
        &::-webkit-scrollbar {
            background: none;
            width: @size / @little_version_ratio;
            height: @size / @little_version_ratio;
        }
        &::-webkit-scrollbar-track {
            border-radius: @size / @little_version_ratio;
        }
        &::-webkit-scrollbar-thumb {
            border-radius: @size / @little_version_ratio;
        }
    }

    &.autoHideScrollbar{
        overflow-x: hidden;
        overflow-y: hidden;
        &:hover{
            overflow-y: scroll;
            overflow-x: scroll;
            -webkit-overflow-scrolling: touch;
            &.only-y{
                overflow-y: scroll !important;
                overflow-x: hidden !important;
            }

            &.only-x{
                overflow-x: scroll !important;
                overflow-y: hidden !important;
            }
        }
    }

    &.only-y:not(.autoHideScrollbar){
        overflow-y: scroll !important;
        overflow-x: hidden !important;
    }

    &.only-x:not(.autoHideScrollbar){
        overflow-x: scroll !important;
        overflow-y: hidden !important;
    }
}

http://codepen.io/hicTech/pen/KmKrjb

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marco Allori
  • 2,874
  • 29
  • 24
3

My answer will scroll even when overflow:hidden;, using jQuery:

For example, scroll horizontally with the mouse wheel:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type='text/javascript' src='/js/jquery.mousewheel.min.js'></script>
<script type="text/javascript">
    $(function() {

       $("YourSelector").mousewheel(function(event, delta) {

          this.scrollLeft -= (delta * 30);
          event.preventDefault();
       });
    });
</script>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Rasel
  • 4,555
  • 3
  • 26
  • 35
  • 2
    Scrolljacking works, but is almost always a poor user experience. – Brandon Anzaldi Jan 03 '15 at 19:04
  • 1
    while this is possible, with a good example, there are massive problems for assistive technology users when you disable scroll and use javascript to handle scrolling. If you do not also set focus to an element every time you scroll for the user, then your AT user will be completely lost. Also, every user has now lost all fine-tuned control over what (s)he sees. Very poor UX to take over scrolling for your user. Besides mousewheel, you also have to handle up/down keys, screen reader rotors, mouse clicks, and touchpad controls. This becomes unwieldy for the developer and awful for the user. – ShiningLight Sep 25 '18 at 17:50
3

To disable the vertical scroll bar, just add overflow-y:hidden;.

Find more about it: overflow.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Pranay Rana
  • 164,177
  • 33
  • 228
  • 256
2

I believe you can manipulate it with the overflow CSS attribute, but they have limited browser support. One source said it was Internet Explorer 5 (and later), Firefox 1.5 (and later), and Safari 3 (and later) - maybe enough for your purposes.

Scrolling, Scrolling, Scrolling has a good discussion.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Stefan Mohr
  • 2,128
  • 2
  • 24
  • 35
  • 1
    Good link. It is nice to know how the result on multi browsers. Unfortunately the figure for a screenshot of the finished results are broken – Chetabahana Sep 03 '15 at 07:25
0

Can CSS be used to hide the scroll bar? How would you do this?

If you wish to remove vertical (and horizontal) scrollbars from a browser viewport, add:

style="position: fixed;"

to the <body> element.


Javascript:

document.body.style.position = 'fixed';

CSS:

body {
  position: fixed;
}
Rounin
  • 21,349
  • 4
  • 53
  • 69