80

I am working on a site using Bootstrap 3.1.0.

You'll notice when the modal window opens, the browser scroll bar just disappears for a split second, then comes back. It does the same when you close it.

How can I make it so that it just open and closes with no browser scroll bar interaction. I have seen posts on stack where people were having problems, but I can't find an answer specific to my problem, so if someone else has made this request and someone knows about it and wants to link me to it, I'd appreciate it. I've searched for about 2 hours for this before posting up.

lowtechsun
  • 1,915
  • 5
  • 27
  • 55
Daniel White
  • 3,337
  • 8
  • 43
  • 66
  • Apparently this issue was fixed in version 3.2.0 of Bootstrap. – devius Dec 11 '15 at 11:48
  • 3
    Apparently not (2016). Future Readers should sort answers by Votes as the accepted answer is not the best answer. See [this answer](http://stackoverflow.com/questions/19960162/bootstrap-3-modal-fires-and-causes-page-to-shift-to-the-left-momentarily-brows#answer-25952508) and possibly also [this one](http://stackoverflow.com/questions/19960162/bootstrap-3-modal-fires-and-causes-page-to-shift-to-the-left-momentarily-brows#answer-19962780) – cssyphus Feb 12 '16 at 03:28
  • Still not fixed 3.3.6, so thanks for the heads up @gibberish! – arjs Jun 18 '16 at 17:12
  • Works [just fine](https://getbootstrap.com/javascript/#modals) in 2017. – lowtechsun Mar 02 '17 at 21:58

25 Answers25

93
.modal {
 overflow-y: auto;
}

.modal-open {
 overflow: auto;
}

Will get rid of it. This was added to make the modals work more responsively, so you could scroll down and see a modal if the screen was too short. It also stops the background from being scrollable while a modal is up. If you don't need that functionality, then you can use that css I posted.

Some more info: They are setting .modal-open on the body, which prevents all scrolling on the body and hides the body scrollbar. Then, when the modal comes up it has the dark background that takes up the whole screen, and that has overflow-y: scroll which forces the scrollbar to come back so if the modal extended passed the bottom of the screen you can still scroll the dark background and see the rest of it.

cjd82187
  • 3,468
  • 3
  • 15
  • 19
  • 11
    You may want to include that CSS in a media query for desktop only, so you have the better boostrap 3 styling for when you are on mobile. – cjd82187 Nov 13 '13 at 20:25
  • 1
    the page now doesnot shift to the left, but now we have more vertical scroll bars!!!. – Laxman Jun 19 '14 at 10:47
  • 1
    Works, but adds a second scroll bar. – empz Jul 23 '14 at 16:59
  • Perfect. Quick and easy. Thanks – coggicc Jul 02 '15 at 00:07
  • 5
    **Also add padding** , `.modal-open { overflow: auto; padding-right: 0px !important; }` as @ben.kaminski said, which gets rid of shifting left issue completely. Hope helps. – Shaiju T Nov 01 '16 at 09:51
  • This is combination with ben answer makes a smooth modal – Sagive Mar 04 '17 at 11:18
  • You may have accesibility problems with this approach (for the tools like Supernova), as the scrollbar still shows up and movable. The rule is "after the modal is closed, the user must be exactly there where the page was left". But i am not 100% sure... – akcasoy Aug 08 '18 at 09:08
77

Fixing the shifting left issue is easily done using CSS alone.

.modal-open[style] {
padding-right: 0px !important;
}

You're just overwriting an inline style that exists in the code. I am using mine in a WordPress build and the inline style was being applied to the body. Looked like this:

<body class="home blog logged-in modal-open" style="padding-right: 15px;">

Hope this helps someone!

ben.kaminski
  • 986
  • 3
  • 13
  • 24
40
.modal {
    overflow-y: auto;
}

.modal-open {
    overflow: auto;
}

.modal-open[style] {
    padding-right: 0px !important;
}

Thanks to ben and cjd.

The above code seems to work for me.

maracuja-juice
  • 994
  • 2
  • 14
  • 33
Tony S
  • 604
  • 6
  • 8
22

this is what i found in github when i search about this problem and for me it works fine

js:

    $(document).ready(function () {
    $('.modal').on('show.bs.modal', function () {
        if ($(document).height() > $(window).height()) {
            // no-scroll
            $('body').addClass("modal-open-noscroll");
        }
        else {
            $('body').removeClass("modal-open-noscroll");
        }
    });
    $('.modal').on('hide.bs.modal', function () {
        $('body').removeClass("modal-open-noscroll");
    });
})

css use this css if you have nav-fixed-top and navbar-fixed-bottom:

body.modal-open-noscroll
{
    margin-right: 0!important;
    overflow: hidden;
}
.modal-open-noscroll .navbar-fixed-top, .modal-open .navbar-fixed-bottom
{
    margin-right: 0!important;
}

or user this css if you have navbar-default

body.modal-open-noscroll 
{
  margin-right: 0!important;
  overflow: hidden;
}
.modal-open-noscroll .navbar-default, .modal-open .navbar-default 
{
  margin-right: 0!important;
}
Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79
user4314713
  • 236
  • 2
  • 2
  • 4
    Worked for me but I had to change the margin-right to padding-right – GhostRider Mar 08 '15 at 13:08
  • @GhostRider: Thanks. I had to chance the margin to padding. – Brian Kates May 13 '15 at 18:16
  • Plus one for the fixed-top/fixed bottom fix, none of the other answers worked for this scenario. – tinmac Aug 25 '15 at 07:45
  • 1
    @FutureReaders [ben.kaminski's answer](http://stackoverflow.com/questions/19960162/bootstrap-3-modal-fires-and-causes-page-to-shift-to-the-left-momentarily-brows#answer-25952508), below,has a single-line css solution that should be the accepted answer. – cssyphus Feb 12 '16 at 03:22
8

This is a reported issue to bootstrap: https://github.com/twbs/bootstrap/issues/9855

And this is my temporary quick fix and it's also work using fixed top navbar, only using javascript. Load this script along with your page.

$(document.body)
.on('show.bs.modal', function () {
    if (this.clientHeight <= window.innerHeight) {
        return;
    }
    // Get scrollbar width
    var scrollbarWidth = getScrollBarWidth()
    if (scrollbarWidth) {
        $(document.body).css('padding-right', scrollbarWidth);
        $('.navbar-fixed-top').css('padding-right', scrollbarWidth);    
    }
})
.on('hidden.bs.modal', function () {
    $(document.body).css('padding-right', 0);
    $('.navbar-fixed-top').css('padding-right', 0);
});

function getScrollBarWidth () {
    var inner = document.createElement('p');
    inner.style.width = "100%";
    inner.style.height = "200px";

    var outer = document.createElement('div');
    outer.style.position = "absolute";
    outer.style.top = "0px";
    outer.style.left = "0px";
    outer.style.visibility = "hidden";
    outer.style.width = "200px";
    outer.style.height = "150px";
    outer.style.overflow = "hidden";
    outer.appendChild (inner);

    document.body.appendChild (outer);
    var w1 = inner.offsetWidth;
    outer.style.overflow = 'scroll';
    var w2 = inner.offsetWidth;
    if (w1 == w2) w2 = outer.clientWidth;

    document.body.removeChild (outer);

    return (w1 - w2);
};

Here is the working example: http://jsbin.com/oHiPIJi/64

Agni Pradharma
  • 134
  • 1
  • 6
  • Works just fine with the latest version of Bootstrap, tested in latest version Chrome, Firefox and Opera. Did not have a look at it with Safari or IE. – lowtechsun Apr 02 '15 at 14:24
  • Exactly what I needed. That and this : `.modal { overflow: auto; } .modal-open { overflow: auto; } .modal-open[style] { padding-right: 0px !important; }` I was trying to fire a modal from another one and the shift was doubled. Thanks for your tip. – Aelys Jan 04 '16 at 06:56
8

None of the items in this page worked for me in version 3.3.4 and 3.3.5 Adding this CSS has solved the problem for me.

body {
padding-right:0px !important;
margin-right:0px !important;
}
Dizzle
  • 1,026
  • 13
  • 26
7

If you have fixed navbar and dont want to scroll body to top when modal is opened use this style

.modal-open {
    overflow: visible;
}
.modal-open, .modal-open .navbar-fixed-top, .modal-open .navbar-fixed-bottom {
    padding-right:0px!important;
}
abxstract
  • 319
  • 3
  • 11
6

to solve the problem causing the page to shift to the right

html, body{
  padding: 0 !important;
}
4
$('body').on('show.bs.modal', function () {
    if ($("body").innerHeight() > $(window).height()) {
        $("body").css("margin-right", "17px");
    }
}); 

$('body').on('hidden.bs.modal', function (e) {
    $("body").css("margin-right", "0px");
});

This little fix simulates the scrollbar when the modal is shown, adding a margin-right to the body.

ashatte
  • 5,442
  • 8
  • 39
  • 50
hect0r90
  • 101
  • 4
  • 1
    Margin-right should not have a fixed pixel value as the scrollbar width varies from browser to browser. – lowtechsun Apr 02 '15 at 14:31
  • The scrollbar width changes based on the browser zoom too. Should use this script in conjunction with a scrollbar size detection script like [this](http://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes) – Kunal May 08 '15 at 22:39
4

This solution work for me!!!!

.modal {
 overflow-y: auto;
}

.modal-open {
 overflow: auto;
}


.modal-open[style] {
padding-right: 0px !important;
}
Jigar Bhatt
  • 4,217
  • 2
  • 34
  • 42
4

None of the above worked and others hours of research. But the following code worked perfect with just a bit of CSS. The above would not remove inline style padding:17px; with JS or jquery, I could add 0 padding, but had no effect.

.modal-open {
  padding-right: 0px !important;
  overflow-y: scroll;
  width: 100%;
  display: block;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1050;
  display: none;
  width: 100%;
  height: 100%;
  outline: 0;
  padding-right: 0 !important;
}
Corey B
  • 85
  • 8
  • This makes a page with scroll bar to have a second scroll bar when a modal is opened. And if you have a second modal on an opened modal, scroll bar of the first modal will be missing after you closed the second one. – Lacek Mar 31 '20 at 08:41
4

I fixed this issue by adding this code in my css file:

body {
    padding-right: 0px !important;
}
Anurag Phadnis
  • 817
  • 7
  • 13
4

I had this problem with Bootstrap 4. I have html { overflow-y: scroll; } and I think it is a problem but after add .modal-open[style] { padding-right: 0px !important; } to my local css file, everything work perfect!

.modal-open[style] { 
    padding-right: 0px !important; 
}
Seldo97
  • 611
  • 1
  • 8
  • 17
  • Worked perfect for me, thank you :) By the way: You could also use `padding-right: 0;` instead of `padding-right: 0px` for max efficiency – janisch Oct 06 '20 at 07:29
3

html, body{
    padding-right: 0px !important; 
    position: relative!important;
}

try this code really it's working

beast.nil
  • 31
  • 1
2

In my case, the body tag already specify overflow:hidden.

When modal dialog opens, it also add padding-right:17px; to body.

My code here

.modal-open {
  overflow: hidden!important;
  padding-right:0!important
}
I'm Geeker
  • 4,601
  • 5
  • 22
  • 41
KayJ
  • 21
  • 3
1

My page needed a modified version of Agni Pradharma's code to keep it from shifting when the modal was shown. I have a fixed nav header and some pages with scroll, some without. Demo here: http://jsbin.com/gekenakoki/1/

I used both the css:

.modal {
    overflow-y: auto;
}

.modal-open {
    overflow: auto;
} 

and the script:

$(document.body)
.on('show.bs.modal', function () {
    if (this.clientHeight <= window.innerHeight) {
        return;
    }
    // Get scrollbar width
    var scrollbarWidth = getScrollBarWidth();
    if (scrollbarWidth) {
        $(document.body).css('padding-left', scrollbarWidth); 
    }
})
.on('hidden.bs.modal', function () {
    $(document.body).css('padding-left', 0);
});

function getScrollBarWidth () {
    var inner = document.createElement('p');
    inner.style.width = "100%";
    inner.style.height = "200px";

    var outer = document.createElement('div');
    outer.style.position = "absolute";
    outer.style.top = "0px";
    outer.style.left = "0px";
    outer.style.visibility = "hidden";
    outer.style.width = "200px";
    outer.style.height = "150px";
    outer.style.overflow = "hidden";
    outer.appendChild (inner);

    document.body.appendChild (outer);
    var w1 = inner.offsetWidth;
    outer.style.overflow = 'scroll';
    var w2 = inner.offsetWidth;
    if (w1 == w2) w2 = outer.clientWidth;

    document.body.removeChild (outer);

    return (w1 - w2);
};
knighter
  • 1,137
  • 8
  • 13
1

As of Bootstrap 3.3.2 the behavior appears to be that the scroll bars are removed when the dialog is shown and Bootstrap adds some right padding to the body element to compensate for the space previously taken up by the scroll bar. Unfortunately this doesn't prevent the screen shift, at least in modern versions of Chrome, IE, Firefox or Safari. None of the fixes here completely fix this issue but combining the answers from ben.kaminski and part of the answer from cjd82187 resolves the issue with only CSS:

/* removes inline padding added by Boostrap that makes the screen shift left */
.modal-open[style] {
    padding-right: 0px !important;
}

/* keeps Bootstrap from removing the scrollbar if it's there */
.modal-open {
    overflow: auto;
}

As mentioned by ben.kaminski, the code was added to Twitter Bootstrap so you could scroll to bring the modal into view if it's beyond the bottom of the screen. To retain that functionality you can wrap the CSS solution in a media query so it only applies to large viewports, something like this:

@media (min-width: 992px) {         
    .modal-open[style] {
        padding-right: 0px !important;
    }

    .modal-open {
        overflow: auto;
    }   
}
clav
  • 4,221
  • 30
  • 43
1

When the bootstrap modal opens then .modal-open class is set to body tag. In this tag overflow:hidden is set. we have to change this. Add the below code in your CSS.

<style>
body.modal-open {
    overflow: visible !important;
}
</style>

Reference :- How to fix Bootstrap modal background scroll to top

Sudhanshu sharma
  • 1,917
  • 3
  • 20
  • 29
1

Implemented this simple solution

.modal-open {

  padding-right: 0 !important;

}

html {

  overflow-y: scroll !important;

}
Lonare
  • 3,581
  • 1
  • 41
  • 45
1

For Bootstrap-4.3.x use the following css:

.modal-open {
    padding-right: 0 !important;
}

/* if you have .navbar in your page then add padding-right for your .navbar (default is 16px) */
.modal-open .navbar {
    padding-right: 16px !important;
}

That's it. Nothing else is needed like: JavaScript code to add some .class in your body and then adding CSS codes to style them.

Partho63
  • 3,117
  • 2
  • 21
  • 39
0

if anyone happens to be using react-bootstrap the solution is just a bit more complex because react-bootstrap applies inline styles to the body element to manipulate the overflow and padding styles. This means you must override those inline styles with !important

body.modal-open {
  // enable below if you want to additionally allow scrolling with the modal displayed
  // overflow: auto !important;

  // prevent the additional padding from being applied
  padding: 0 !important;
}

NOTE: if you do not enable scrolling (i.e. make the scrollbar visible) by uncommenting the overflow style, then your page content will appear to shift over by the scrollbar width (if the scrollbar was previously visible that is).

pjs
  • 2,601
  • 1
  • 20
  • 24
0

My Jquery solution:

var nb = $('nav.navbar-fixed-top');
$('.modal')
    .on('show.bs.modal', function () {
        nb.width(nb.width());
    })
    .on('hidden.bs.modal', function () {
        nb.width(nb.width('auto'));
    });
0

For Bootstrap version 3.2.0 this lines in css file fill fix the error:

.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
padding-right: 17px;
}

Solution found here

Theo Orphanos
  • 1,417
  • 1
  • 19
  • 27
0

The best solution for me was use this settings. It works for web and mobile

.modal-open {
   overflow: hidden;
   position: absolute;
   width: 100%;
   height: 100%;
}
Bartando
  • 719
  • 8
  • 26
0

For Bootstrap 5, this worked for me

body.modal-open {
  overflow-y: inherit;
}
Aldrin Jenson
  • 906
  • 7
  • 6