Daniel White
Daniel White

Reputation: 3377

Bootstrap 3 modal fires and causes page to shift to the left momentarily / browser scroll bar problems

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.

Upvotes: 80

Views: 84178

Answers (26)

Ethan
Ethan

Reputation: 2087

As of Sept 2024, modals opening can still result in showing/hiding right scroll bars, which create a screen bounce-like effect. This will handle it:

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

Upvotes: 0

Aldrin Jenson
Aldrin Jenson

Reputation: 1016

For Bootstrap 5, this worked for me

body.modal-open {
  overflow-y: inherit;
}

Upvotes: 0

Seldo97
Seldo97

Reputation: 719

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; 
}

Upvotes: 4

Anurag Phadnis
Anurag Phadnis

Reputation: 867

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

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

Upvotes: 4

Sudhanshu sharma
Sudhanshu sharma

Reputation: 1967

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

Upvotes: 1

Partho63
Partho63

Reputation: 3117

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.

Upvotes: 1

Corey B
Corey B

Reputation: 85

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;
}

Upvotes: 4

Bartando
Bartando

Reputation: 748

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%;
}

Upvotes: 0

Lonare
Lonare

Reputation: 4683

Implemented this simple solution

.modal-open {

  padding-right: 0 !important;

}

html {

  overflow-y: scroll !important;

}

Upvotes: 1

Theo Orphanos
Theo Orphanos

Reputation: 1447

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

Upvotes: 0

Jigar Bhatt
Jigar Bhatt

Reputation: 4680

This solution work for me!!!!

.modal {
 overflow-y: auto;
}

.modal-open {
 overflow: auto;
}


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

Upvotes: 4

Goloveichuk
Goloveichuk

Reputation: 1

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'));
    });

Upvotes: 0

user4314713
user4314713

Reputation: 236

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;
}

Upvotes: 22

beast.nil
beast.nil

Reputation: 31

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

try this code really it's working

Upvotes: 3

Tony S
Tony S

Reputation: 612

.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.

Upvotes: 41

Femi-oke Anthony
Femi-oke Anthony

Reputation: 61

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

html, body{
  padding: 0 !important;
}

Upvotes: 6

pjs
pjs

Reputation: 2731

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).

Upvotes: 0

Dizzle
Dizzle

Reputation: 1016

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;
}

Upvotes: 8

hect0r90
hect0r90

Reputation: 101

$('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.

Upvotes: 4

abxstract
abxstract

Reputation: 319

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;
}

Upvotes: 7

KayJ
KayJ

Reputation: 21

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
}

Upvotes: 2

clav
clav

Reputation: 4251

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;
    }   
}

Upvotes: 1

knighter
knighter

Reputation: 1227

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);
};

Upvotes: 1

ben.kaminski
ben.kaminski

Reputation: 976

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!

Upvotes: 77

Agni Pradharma
Agni Pradharma

Reputation: 134

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

Upvotes: 8

cjd82187
cjd82187

Reputation: 3593

.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.

Upvotes: 93

Related Questions