32

I have a div that may overflow as content is added or removed.

However the UI designer does not want a visible, but inactive scrollbar (as with overflow: scroll), and they don't want the content layout to change when one is added and remove (as with overflow: auto).

Is there a means to get this behavior, and considering the different scrollbars on different platforms and browsers.

enter image description here https://jsfiddle.net/qy9a2r00/1/

Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
  • 2
    There are plugins to replace the native scrollbar, means using javascript. – Stickers Jul 08 '16 at 12:02
  • 1
    http://manos.malihu.gr/jquery-custom-content-scroller/ will help, examples here: http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/scrollbar_themes_demo.html – Suresh Karia Jul 08 '16 at 12:06

8 Answers8

14

No browser support this property yet (2021), but scrollbar-gutter is a suggested solution for this.

Update: 2022 - all modern browsers except Safari support the property.

olejorgenb
  • 1,203
  • 14
  • 25
  • Now supported in Chrome/Edge/Opera. Firefox bug waiting for implementors: https://bugzilla.mozilla.org/show_bug.cgi?id=1715112 – 1j01 Nov 15 '21 at 20:27
  • 1
    yes, please check this answer! https://stackoverflow.com/a/69966304/2601507 – Lex Jul 23 '22 at 18:33
6

The only way to do this is to make the width of the items in the container fixed. And you'll have to be conservative with the width of the scrollbar.

   .container { 
       width: 200px;
       height: 200px;
       overflow: auto;
       overflow-x: hidden;
       border: 1px solid black;
   }
   .item {
       width: 200px;
...

https://jsfiddle.net/fr1jnmn6/1/

Sean
  • 337
  • 2
  • 7
4

overflow-y:overlay would be a partial solution to this as in, it solves the problem of not wanting the content layout to change when a scrollbar is added or removed. Extra padding or margin can be added so that scrollbar doesn't obfuscate the div behind

Here's the jsfiddle for the same https://jsfiddle.net/kitwradr/2qcsj6hw/

Kitwradr
  • 1,986
  • 3
  • 18
  • 32
2

You can setup overflow: scroll to reserve space for scrollbar and add a class that makes scrollbar hidden

body {
 overflow-y: scroll;
}

Hide the scrollbar by adding class to div (or to body) that will make your scrollbar transparent

.scroll-hidden::-webkit-scrollbar
{
    background-color: transparent;
}

.scroll-hidden::-webkit-scrollbar-track
{
    background-color: transparent;
}

To check if you have content overflow you can use this lines:

  const { body } = document
  const overflow = body.scrollHeight > body.clientHeight

If there are no overflow issue we will hide scrollbar and with reserve space

body.classList.add('scroll-hidden')  

If content overflow we will show scrollbar

body.classList.remove('scroll-hidden')  

Try the solution here https://jsfiddle.net/ycharniauski/y0pwftmq/

It's a bit hacky solution. Hope in future css will have some property to reserve space

1

One cannot know how thick the scrollbar is, using only HTML & CSS and thus do not know the width of the (blue) placeholder.

You might solve such a task using scripting. Force a scrollbar in a hidden container and measure the inner and outer width. The difference being the scrollbar-width. Set this width (e.g. as CSS) to the placeholder element. And in the tricky part hide this element whenever a scrollbar is shown.

The usual solution to this problem is the one you do not want.

feeela
  • 29,399
  • 7
  • 59
  • 71
  • Usual solution being, living with "auto" or "scroll" style, replace the entire scrollbar from scratch, or using JS to measure a scrollbar and detect it being added and remove, such that I can adjust the blue bar styles? – Fire Lancer Jul 09 '16 at 10:57
0

You need to have a parent div with a fixed width (the final total width) and a child div with a width 16px smaller. Then the scrollbar will have 16px free in the parent div.

The width should always be a number (can't be relative value). In the child div, you need to use a number as well. You can't do calc(100%-16px).

<div className="user-list">
  <div className="user-list__content">
    {content}
  </div>    
</div>

.user-list {
  width: 500px;  /* total width */
  height: 1000x;
  overflow-y: auto;
}

.user-list__content {
  width: 484px;  /* must be 16px smaller */
  height: 100%;
}
0

This is an ancient question, but in case anyone comes looking.

Detect the scrollbar and show/hide your blue section based on the scrollbar being visible. If scrollbar is visible, HIDE your blue sections (apply a style). If not visible, show your blue padding section.

When the scrollbar becomes visible your padding hides, so the red and green sections will not change size or position.

This article below discusses detecting the scrollbar. You will want to set up a div somewhere to detect the current scrollbar width ahead of time in order to set your blue boxes to the same width.

How can I check if a scrollbar is visible?

Max
  • 1
-3

Maybe append a div at the bottom will soft your problem ?

https://jsfiddle.net/moongod101/k7w574mw/1/

Felix Fong
  • 969
  • 1
  • 8
  • 21