ChatGPT解决这个技术问题 Extra ChatGPT

Prevent scroll-bar from adding-up to the Width of page on Chrome

I have a small issue trying to keep my .html pages at a consistent width on Chrome, For example I have a page (1) with lots of contents that overflows the viewport's (right word?) height, so there's a vertical scroll-bar on that page (1). On page (2) i have the same layout (menus, divs,...etc) but less content, so no vertical scroll-bars in there.

The problem is that on page (1) the scroll-bars seem to push elements slightly to the left (adding-up to the width?) while everything appears well centered on page (2)

I'm still a beginner on HTML/CSS/JS, and I'm fairly convinced that this isn't so difficult, but i had no luck figuring out the solution. It does work as intended on IE10, and FireFox (non-interfering scroll-bars), I only encountered this on Chrome.

This is a very anoying issue, that i've never ran into until I switched to coding in Windows where scrollbars are persitent and take up screen realestate. Mac scrollbars disapear and don't add to the width.

s
simonDos

DISCLAIMER: overlay has been deprecated. You can still use this if you absolutely have to, but try not to.

This only works on WebKit browsers, but I like it a lot. Will behave like auto on other browsers.

.yourContent{
   overflow-y: overlay;
}

This will make the scrollbar appear only as an overlay, thus not affecting the width of your element!


It's not working for IE11. Is there any work around for overlay value to work in IE.
not as far as i know, you will have to make do with the other options proposed in this thread for IE
Much required! I took more than half an hour to just see what the hell did I do wrong with my markup. What styles did I overuse? This should be default too.
But it is deprecated
I updated the solution to reflect that. Kinda sad :P
H
Hive7

All you need to do is add:

html {
    overflow-y: scroll;
}

In your css file as this will have the scroller whether it is needed or not though you just won't be able to scroll

This means that the viewport will have the same width for both


so, i'm obliged to add scroll-bars to both ? isn't there a way to just ignore the width of the vertical scroll-bar ? Thank you !
Therer is no way to ignore it that I am aware of but what I said works a treat @Rockr90
@d3c0y this is true and I have mentioned it in the answer but its the easiest method to do so. I do not know if that has changed in the past 3 years however
@aks. it forces the browser to think you can scroll so enables to scrollbar and scroll y is the side scroller
overflow-y: scroll; will add/show the scrollbar in all viewport even there are no scrollable elements.
N
Neurotransmitter

Probably

html {
    width: 100vw;
}

is just what you want.


This worked great for my usecase: gist.github.com/bmcminn/1ab50da18bde75f39bc88e8292a5a847 I'm using calc() to determine the width of the main content view so that the fixed offscreen nav can occupy the left side of the screen on desktop, all while preserving native scroll on mobile.
I have been messing around with my scrollbars for the past 36 hours. I have had a few different solutions that worked, but raised other issues. This is the first solution that both works and allows me to use a normal scrollbar elsewhere. Thank you.
This worked great, can someone explain how this works ?
Well, it just sets the root HTML node's (<html>) width to 100 viewport width units. That is 100% width of the browser window.
Solution not bad, but it could add horizontal scrolling.
L
Lwyrn

You can get the scrollbar size and then apply a margin to the container.

Something like this:

var checkScrollBars = function(){
    var b = $('body');
    var normalw = 0;
    var scrollw = 0;
    if(b.prop('scrollHeight')>b.height()){
        normalw = window.innerWidth;
        scrollw = normalw - b.width();
        $('#container').css({marginRight:'-'+scrollw+'px'});
    }
}

CSS for remove the h-scrollbar:

body{
    overflow-x:hidden;
}

Try to take a look at this: http://jsfiddle.net/NQAzt/


Clever solution, I don't understand the condition in the 'if' though !
The scrollHeight is the total height of an element. What you see and what is hidden. An example: Your window is like 500px in height, the body have a content for 900px. 500px are shown but the other 400px is hidden and the scroll bar will appear to show this remaning pixel. So the condition is like "if the height of all content is greater then the viewpoint height, add the margin to the body". Sorry for my bad english
I've added a little piece of css to prevent it in the reply :)
This solution disables scrolling
Man you save me with this piece of code, I've lost 20 hours trying to figure out what should i do! Thanks buddy!
K
Kyle Dumovic

Webkit browsers like Safari and Chrome subtract the scroll bar width from the visible page width when calculating width: 100% or 100vw. More at DM Rutherford's Scrolling and Page Width.

Try using overflow-y: overlay instead.


Please don't post identical answers to multiple questions. Post one good answer, then vote/flag to close the other questions as duplicates. If the question is not a duplicate, tailor your answers to the question.
This should work, but overlay is not yet standard neither it is supported in all browsers.
Quick hiccup: in Safari this caused the page to stop scrolling
C
Christian

The 2021 solution is to use scrollbar-gutter, which adds the space, a scrollbar would use, permanently to an element.

Use

.element-class {
   scrollbar-gutter: stable both-edges;
}

both-edges is optional.

See also https://caniuse.com/mdn-css_properties_scrollbar-gutter and https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-gutter

overflow: overlay is deprecated.

Here is a codepen for clarification on the different possibilities: https://codepen.io/waxolunist/pen/ExweBMz


Very nice, finally a better solution than all these hacks. 👍 both-edges caused a padding on the left of my textarea. So I just justed scrollbar-gutter: stable;
f
fuzzy_logic_77

I found I could add

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

directly to my css and it would make the scrollbar invisible, but still allow me to scroll (on Chrome at least). Good for when you don't want a distracting scrollbar on your page!


It is somewhat risky and not cross-browser solution though stackoverflow.com/questions/9251354/…
R
Robbendebiene

For containers with a fixed width a pure CSS cross browser solution can be accomplished by wrapping the container into another div and applying the same width to both divs.

#outer {
  overflow-y: auto;
  overflow-x: hidden;
  /*
   * width must be an absolute value otherwise the inner divs width must be set via
   * javascript to the computed width of the parent container
   */
  width: 200px;
}

#inner {
  width: inherit;
}

Click here to see an example on Codepen


C
CSS FTW
body {
    width: calc( 100% );
    max-width: calc( 100vw - 1em );
}

works with default scroll bars as well. could add:

overflow-x: hidden;

to ensure horizontal scroll bars remain hidden for the parent frame. unless this is desired from your clients.


H
Hashbrown

It doesn't seem my other answer is working quite right at the moment (but I'll continue to try to get it operational).

But basically what you'll need to do, and what it was trying to do dynamically, is set the contents' width to slightly less than that of the parent, scrollable pane. So that when the scrollbar appears it has no affect on the content.

This EXAMPLE shows a more hacky way of attaining that goal, by hardcoding widths instead of trying to get the browser to do it for us via padding.
If this is feasible this is the most simplest solution if you don't want a permanent scrollbar.


That's a good solution, however i'm working on a responsive website using Bootstrap, and it's important to automate width and all, what do you say ?
well unless (in order of decending likelyhood) either: someone figures out how to get my other answer to work (with either padding or margin); you can somehow use media queries to apply padding selectively; or css expressions are implemented in modern browsers to selectively apply padding. I think only a permanent scrollbar or using JS to detect scrollbar is the way to go
H
Hashbrown

EDIT: this answer isn't quite right at the moment, refer to my other answer to see what I was attempting to do here. I'm trying to fix it up, but if you can offer assistance do so in the comments, thanks!

Using padding-right will mitigate the sudden appearance of a scrollbar

EXAMPLE

https://i.stack.imgur.com/fKp0z.png

As you can see from the dots, the text makes it to the same point in the page before wrapping, regardless of whether or not a scrollbar is present. This is because when a scrollbar is introduced the padding hides behind it, so the scrollbar doesn't push on the text!


The scrollbar width can change depends on what OS and Browser you are using. It can measure 20px as well as 40px
well you'd use the maximum of all possible values
Some devices/OS browser`s scrolls don't even have a width.
P
Piotr Siatkowski
.modal-dialog {
   position: absolute;
   left: calc(50vw - 300px);
}

where 300 px is a half of my dialog window width.

This is actually the only thing that worked for me.


N
NatD

I had the same issue on Chrome. It only happened for me when the scroll bar is always visible. (found in the general settings) I have a modal and when I open the modal I noticed that...

body {
    padding-left: 15px;
}

is added to the body. To stop this from happening I added

body {
    padding-left: 0px !important;
}

j
jeremy

I can't add comment for the first answer and it's been a long time... but that demo has a problem:

if(b.prop('scrollHeight')>b.height()){
    normalw = window.innerWidth;
    scrollw = normalw - b.width();
    $('#container').css({marginRight:'-'+scrollw+'px'});
}

b.prop('scrollHeight') always equals b.height(),

I think it should be like this:

if(b.prop('scrollHeight')>window.innerHeight) ...

At last I recommend a method:

html {
 overflow-y: scroll;
}

:root {
  overflow-y: auto;
  overflow-x: hidden;
}

:root body {
  position: absolute;
}

body {
 width: 100vw;
 overflow: hidden;
}

A
Arash Esmaeili

I solved a similar problem I had with scrollbar this way:

First disable vertical scrollbar by setting it's:

overflow-y: hidden;

Then make a div with fixed position with a height equal to the screen height and make it's width thin to look like scrollbar. This div should be vertically scroll-able. Now inside this div make another div with the height of your document (with all it's contents). Now all you need to do is to add an onScroll function to the container div and scroll body as the div scrolls. Here's the code:

HTML:

<div onscroll="OnScroll(this);" style="width:18px; height:100%;  overflow-y: auto; position: fixed; top: 0; right: 0;">
    <div id="ScrollDiv" style="width:28px; height:100%; overflow-y: auto;">
    </div>
</div>

Then in your page load event add this:

JS:

$( document ).ready(function() {
    var body = document.body;
    var html = document.documentElement;
    var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
    document.getElementById('ScrollDiv').style.height = height + 'px'; 
});

function OnScroll(Div) {
    document.body.scrollTop = Div.scrollTop;
}

Now scrolling the div works just like scrolling the body while body has no scrollbar.


Ok, and for browsers that show classic scroll bars, how would a user know there's more content to scroll to ?
S
Sargsian

If you have some container that you're using as a wrapper over your website content, like for navigation and footer for example, you can add the following:

min-height: 101vh;

This will 'Lengthen' your page by 1vh to make sure the scrollbar never disappears and the width stays the same.