Twitter Bootstrap modal pushes html content to the left

If I open a modal dialog, through Twitter Bootstrap, I've noticed that it pushes all the html content of the page (i.e., in the container) to the left a little bit, and then puts it back to normal after closing itself. However, this only happens if the browser width is large enough to not be on the "mobile" (i.e., smallest) media query. This occurs with the latest versions of FF and Chrome (haven't tested other browsers).

You can see the problem here: http://jsfiddle.net/jxX6A/2/

Note: You have to increase the width of the "Result" window so it switches to the "med" or "large" media query css.

I have setup the HTML of the page based upon the examples shown on Bootstrap's site:

<div class='container'>
    <div class='page-header'>
        <h4>My Heading</h4>
    </div>
    <div id='content'>
        This is some content.
    </div>
    <div class='footer'>
        <p>&copy; 2013, me</p>
    </div>
</div>

I'm guessing this is not supposed to happen, but I'm not sure what I've done wrong.

EDIT: This is a known bug, for more (and up-to-date) information, please see: https://github.com/twbs/bootstrap/issues/9855


Solution 1:

For bootstrap 3.x.x.

I have found a solution, that works with 100% CSS and no JavaScript.

The trick is to show the scrollbar for modal over the scrollbar of html content.

CSS:

html {
  overflow: hidden;
  height: 100%;
}
body {
  overflow: auto;
  height: 100%;
}

/* unset bs3 setting */
.modal-open {
 overflow: auto; 
}

Here is an online example: http://jsbin.com/oHiPIJi/43/

I tested it on Windows 7 with:

  • FireFox 27.0
  • Chrome 32.0.1700.107 m
  • IE 11 in Browser Mode 8, 9, 10, Edge (Desktop)
  • IE 11 in Browser Mode 8, 9, 10, Edge (windows phone)

One new little issue I found with IE:

IE has background (=body) scrolling with mouse wheel, if there is nothing more to scroll in the foreground.

Take care with position:fixed!

Because of the nature of this workaround, you need extra care for fixed elements. For example the padding for "navbar fixed" needs to be set to html and not to body (how it is described in bootstrap doc).

/* only for fixed navbar: 
* extra padding setting not on "body" (like it is described in docs), 
* but on "html" element
* the value used depends on the height of your navbar
*/
html {
  padding-top: 50px;
  padding-bottom: 50px;
}

Alternative with wrapper

If you do not like setting overflow:hidden on html (some people don't like this, but it works, is valid and 100% standards compliant), you can wrap the content of body in an extra div. You can use it as before by using this approach.

body, html {
  height: 100%;
}
.bodywrapper {
  overflow: auto;
  height: 100%;
}

/* unset bs3 setting */
.modal-open {
 overflow: auto; 
}

/* extra stetting for fixed navbar, see bs3 doc
*/
body {
  padding-top: 50px;
  padding-bottom: 50px;
}

Here is an example: http://jsbin.com/oHiPIJi/47/

Update:

Issues in Bootstrap:

  • #12627
  • #9855

Update 2: FYI

In Bootstrap 3.2.0 they add a workaround to modal.js that tries to handle the issues with Javascript for every invoke of modal.prototype.show(), Modal.prototype.hide() and Modal.prototype.resize(). They add 7 (!) new methods for that. Now about 20% of code from modal.js tries to handle just that issue.

Solution 2:

Try this:

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

.modal::-webkit-scrollbar {
    width: 0 !important; /*removes the scrollbar but still scrollable*/
    /* reference: http://stackoverflow.com/a/26500272/2259400 */
}

Solution 3:

It is actually caused by the following rule in bootstrap.css:

body.modal-open,
.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
  margin-right: 15px;
}

I am not exactly sure why it behaves like that (perhaps to account for scrollbar somehow) but you can change the behaviour with this:

body.modal-open {margin-right: 0px}

EDIT: Actually, this is a reported issue in bootstrap: https://github.com/twbs/bootstrap/issues/9855

Solution 4:

When the model opens, a padding of 17px to the right of the body. The code below should resolve that issue.

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

Solution 5:

Here's the fix proposed by user yshing that really FIXED it for me while using Bootstrap v3.1.1 and Google Chrome 35.0.1916.114m. The fix comes from a GitHub issue thread regarding this matter:

.modal
{
    overflow-y: auto;
}

.modal-open
{
   overflow:auto;
   overflow-x:hidden;
}

The fix will land only in Bootstrap 3.2 as desbribed by mdo.