18

I'm using a fixed width body and auto margins to center my content in the middle of the page. When the content exceeds the page's height and the browser adds a scrollbar, the auto margins force the content to jump half the width of the scrollbar left.

Is comparing outerHeight with window.innerHeight an appropriate way of solving this? Is there another way to solve this?

I think this should be enough info for the problem, but let me know if I can answer anything else.

Edit for clarification: I don't want to force the scrollbar to appear.

Nick Bergseng
  • 193
  • 1
  • 2
  • 7

7 Answers7

29

I'll just leave this link here because it seems an elegant solution to me:

https://aykevl.nl/2014/09/fix-jumping-scrollbar

What he does is add this css:

@media screen and (min-width: 960px) {
    html {
        margin-left: calc(100vw - 100%);
        margin-right: 0;
    }
}

This will move the content to the left just the size of the scrollbar, so when it appears the content is already moved. This works for centered content with overflow: auto; applied to the html tag. The media query disables this for mobile phones, as its very obvious the difference in margin widths.

You can see an example here:

http://codepen.io/anon/pen/NPgbKP

xabitrigo
  • 1,341
  • 11
  • 24
  • 5
    Excellent! I didn't want *both* margins, so I applied a negative right margin instead: margin-right: calc(-100vw + 100%); In addition, I had to kill the bottom scroll: overflow-x: hidden; – ulu Jul 01 '17 at 10:47
  • 2
    Note that this only works if there is an existing whitespace margin to the left of your content. – dwjohnston Sep 05 '18 at 01:20
  • 1
    Good answer @ulu you should post it. – dwjohnston Sep 05 '18 at 01:21
  • This is great. Now how can I do it on a div which has `overflow: auto`? Is there an equivalent to `100vw` for elements which are not themselves the full width of the viewport? – poshest Feb 07 '19 at 14:04
8

Use this CSS:

body { overflow-y: scroll; }
Sam Starling
  • 5,298
  • 3
  • 35
  • 52
7

I've run into this problem myself and I've found two ways to solve it:

  1. Always force the scrollbar to be present: body { overflow-y: scroll; } Setting it on the html doesn't work in all browsers or might give double scroll bars if the scrollbar does appear.

  2. Add a class that adds ~30 pixels to the right margin of your page if there is no scrollbar.

I've chosen option 1 but I'm not sure if it works in all browsers (especially the older ones).

Facebook uses option 2.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • Option 1 works on all browsers, older browsers include the scroll on all pages by default. Facebook does #2 because they don't want the scroll bar to show if it's not necessary. – thenetimp Feb 08 '12 at 21:52
  • I think it gives the problem of _double_ scroll bars on some browsers (the scrollbar will be in the `body`). It's been a while, I really don't want to test this again :P – Halcyon Feb 08 '12 at 21:54
  • Ah yes... but what if I don't want to force scrollbars? What if I want the browser to not have a scrollbar when it doesn't need one? – Nick Bergseng Feb 08 '12 at 21:58
3

You can force the scrollbar to always appear:

http://www.mediacollege.com/internet/css/scroll-always.html

Mikey G
  • 3,473
  • 1
  • 22
  • 27
1

The process is :

html {
   overflow-y: scroll !important;
}

This will show the scrollbar even there no need any scroll bar.

Sanjib Debnath
  • 3,556
  • 2
  • 22
  • 16
1

For me, the solution was to add this rule to the body:

body {
  overflow-anchor: none;
}

This rule was added recently, and aims to reduce the variability of browsers having different default assumptions about how they should react to overflowing. Chrome, for example, has overflow anchoring enabled by default, whereas Firefox does not. Setting this property will force both browsers to behave the same way.

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor

0

Best possible way through CSS, It will show/hide Scrollbar accordingly, will solve jump problem, works on every browser

html {
    overflow: hidden;
 }

body {
    overflow-y: auto;
    -webkit-overflow-scrolling:touch;
}
Suman
  • 1
  • 2
  • 4
    "overflow: hidden" on the html node prevents the browser from remembering the scoll state when using the navigation buttons – alternize Jan 02 '19 at 23:07