[css] Twitter bootstrap scrollable modal

I'm using twitter bootstrap for a project I am working on.

I have a modal window that has a somewhat longer form in it and I didn't like that when the window got too small the modal didn't scroll (if just disappeared off my page which isn't scrollable).

To fix this I used the following css

.modal {
    overflow-y:auto;
    max-height:90%;
    margin-top:-45%;
}

This works exactly the way I want it to in Chrome (that is, the form is full size when the window is big enough, but as the window shrinks the modal shrinks and becomes scrollable). The problem is that in IE the modal is off the screen. Does anyone have a better solution to this problem?

My example can be found at tinyhousemap.com (click 'Add an Entry to the map' in the navigation window for the modal to appear)

Thanks

This question is related to css twitter-bootstrap

The answer is


In case of using .modal {overflow-y: auto;}, would create additional scroll bar on the right of the page, when body is already overflowed.

The work around for this is to remove overflow from the body tag temporarily and set modal overflow-y to auto.

Example:

$('.myModalSelector').on('show.bs.modal', function () {

        // Store initial body overflow value
        _initial_body_overflow = $('body').css('overflow');

        // Let modal be scrollable
        $(this).css('overflow-y', 'auto');
        $('body').css('overflow', 'hidden');


    }).on('hide.bs.modal', function () {

        // Reverse previous initialization
        $(this).css('overflow-y', 'hidden');
        $('body').css('overflow', _initial_body_overflow);
});

Try and override bootstrap's:

 .modal {
position: fixed;

With:

.modal {
position: absolute;

It worked for me.


I´ve done a tiny solution using only jQuery.

First, you need to put an additional class to your <div class="modal-body"> I called "ativa-scroll", so it becomes something like this:

<div class="modal-body ativa-scroll">

So now just put this piece of code on your page, near your JS loading:

<script type="text/javascript">
  $(document).ready(ajustamodal);
  $(window).resize(ajustamodal);
  function ajustamodal() {
    var altura = $(window).height() - 155; //value corresponding to the modal heading + footer
    $(".ativa-scroll").css({"height":altura,"overflow-y":"auto"});
  }
</script>

I works perfectly for me, also in a responsive way! :)


None of this will work as expected.. The correct way is to change position: fixed to position: absolute for .modal class


How about the below solution? It worked for me. Try this:

.modal .modal-body {
    max-height: 420px;
    overflow-y: auto;
}

Details:

  1. remove overflow-y: auto; or overflow: auto; from .modal class (important)
  2. remove max-height: 400px; from .modal class (important)
  3. Add max-height: 400px; to .modal .modal-body (or what ever, can be 420px or less, but would not go more than 450px)
  4. Add overflow-y: auto; to .modal .modal-body

Done, only body will scroll.


I also added

.modal { position: absolute; }

to the stylesheet to allow the dialog to scroll, but if the user has moved down to the bottom of a long page the modal can end up hidden off the top of the visible area.

I understand this is no longer an issue in bootstrap 3, but looking for a relatively quick fix until we upgrade I ended up with the above plus calling the following before opening the modal

$('.modal').css('top', $(document).scrollTop() + 50);

Seems to be happy in FireFox, Chrome, IE10 8 & 7 (the browsers I had to hand)


Your modal is being hidden in firefox, and that is because of the negative margin declaration you have inside your general stylesheet:

.modal {
    margin-top: -45%; /* remove this */
    max-height: 90%;
    overflow-y: auto;
}

Remove the negative margin and everything works just fine.


I was able to overcome this by using the "vh" metric with max-height on the .modal-body element. 70vh looked about right for my uses. Then set the overflow-y to auto so it only scrolls when needed.

.modal-body {
   overflow-y: auto;
   max-height: 70vh;
}

The problem with @grenoult's CSS solution (which does work, mostly), is that it is fully responsive and on mobile when the keyboard pops up (i.e. when they click in an input in the modal dialog) the screen size changes and the modal dialog's size changes and it can hide the input they just clicked on so they can't see what they are typing.

The better solution for me was to use jquery as follows:

$(".modal-body").css({ "max-height" : $(window).height() - 212, "overflow-y" : "auto" });

It isn't responsive to changing the window size, but that doesn't happen that often anyway.


/* Important part */
.modal-dialog{
    overflow-y: initial !important
}
.modal-body{
    max-height: calc(100vh - 200px);
    overflow-y: auto;
}

This works for Bootstrap 3 without JS code and is responsive.

Source