Pwnna
Pwnna

Reputation: 9528

Bootstrap modal body max height 100%

I have a custom sized (80% height width) bootstrap modal body and it scrolls (body content will overflow on some sized screens)

There are 2 problems:

  1. I can't set the max-height to 100% as that will be 100% of the entire document instead of the max height of the container, which is what i need for scrolling to work properly.
  2. If there is a div with a fixed height inside the modal body at the very end, it will overflow outside of the modal if the screen is not big enough for the content.

How would I fix this? I'm currently experimenting with negative margins but i'm not too familiar with it.

JavaScript solutions are acceptable (jQuery is available as is backbone.js)

Thanks

Edit: Screenshot provided

enter image description here

Edit 2: More screenshot

enter image description here

Upvotes: 14

Views: 74717

Answers (11)

George Beier
George Beier

Reputation: 256

In BS 5.2.2, I got it to work by using the view-height (in-line style). H-100 didn't work.

<div class="modal-body" style="height:100vh">
      Body Here
</div>

Upvotes: 0

Deevan
Deevan

Reputation: 39

You just need to set the height of modal popup on its show, get the height of screen / window and set it to modal's height. (you can multiply it by 0.8 to get 80% height of screen, which fits nicely).

$('#YourModalId').on('show.bs.modal', function () {
    $('.modal .modal-body').css('overflow-y', 'auto'); 
    var _height = $(window).height()*0.8;
    $('.modal .modal-body').css('max-height', _height);
});

Upvotes: 3

Daniel de Lima
Daniel de Lima

Reputation: 1

This code

//adjust modal body sizes
var fit_modal_body;

fit_modal_body = function(modal) {
  var body, bodypaddings, header, headerheight, height, modalheight;
  header = $(".modal-header", modal);
  footer = $(".modal-footer", modal);
  body = $(".modal-body", modal);
  modalheight = parseInt(modal.css("height"));
  headerheight = parseInt(header.css("height")) + parseInt(header.css("padding-top")) + parseInt(header.css("padding-bottom"));
  footerheight = parseInt(footer.css("height")) + parseInt(footer.css("padding-top")) + parseInt(footer.css("padding-bottom"));
  bodypaddings = parseInt(body.css("padding-top")) + parseInt(body.css("padding-bottom"));
  height = $(window).height() - headerheight - footerheight - bodypaddings - 150;
  return body.css({"max-height": "" + height + "px", 'height':'auto'});
};

fit_modal_body($(".modal"));
$(window).resize(function() {
  return fit_modal_body($(".modal"));
});

Written by tsdexter, it worked for me!

Upvotes: 0

Andy
Andy

Reputation: 8630

Here is a fully working Sass solution, but it requires flexbox.

  // don't clamp modal height when screen is shorter than 400px
  // .modal-body is short in that case, and the default behavior
  // (entire modal will scroll) is easier to use
  @media(min-height:400px)
    .modal
      // use top/bottom margin here instead of .modal-dialog
      // so that .modal-dialog can use height: 100%
      margin: 30px
      // without overflow: visible the shadow will be clipped
      // at the bottom
      overflow: visible

      > .modal-dialog
        margin: 0 auto
        // height must be explicitly set for .modal-content to
        // use percentage max-height
        height: 100%

        > .modal-content
          display: flex
          flex-direction: column
          max-height: 100%

          > .modal-header,
          > .modal-footer,
            // don't allow header/footer to grow or shrink
            flex: 0 0 auto

          > .modal-body
            // allow body to shrink but not grow
            flex: 0 1 auto
            // make body scrollable instead of entire modal
            overflow-y: auto

Upvotes: 2

elnino3800
elnino3800

Reputation: 163

Pwnna's answer have good concept, bud doesn't work for me. Here is solution that work's for me:

fit_modal_body = function (modal, padding) {
    var windowHeight = $(window).height();
    var modalHeight = modal.height();

    var dif = windowHeight - (modalHeight + 2*padding);
    var modalBody = $(".modal-body:first", modal);
    modalBody.css("max-height", modalBody.height() + dif);
};

resizeLastWindow = function () {
    fit_modal_body($(".modal-dialog:last"), 15);
};

$(window).resize(resizeLastWindow);

It's depend's on css:

.modal-body {
    overflow-y: auto; 
}

Upvotes: 0

tsdexter
tsdexter

Reputation: 2991

As a follow up to pwnna's answer this code is working better for me as it's working with a variable height depending on the content size with a max-height as well and it runs on load too, instead of just resize.

//adjust modal body sizes
var fit_modal_body;

fit_modal_body = function(modal) {
  var body, bodypaddings, header, headerheight, height, modalheight;
  header = $(".modal-header", modal);
  footer = $(".modal-footer", modal);
  body = $(".modal-body", modal);
  modalheight = parseInt(modal.css("height"));
  headerheight = parseInt(header.css("height")) + parseInt(header.css("padding-top")) + parseInt(header.css("padding-bottom"));
  footerheight = parseInt(footer.css("height")) + parseInt(footer.css("padding-top")) + parseInt(footer.css("padding-bottom"));
  bodypaddings = parseInt(body.css("padding-top")) + parseInt(body.css("padding-bottom"));
  height = $(window).height() - headerheight - footerheight - bodypaddings - 150;
  return body.css({"max-height": "" + height + "px", 'height':'auto'});
};

fit_modal_body($(".modal"));
$(window).resize(function() {
  return fit_modal_body($(".modal"));
});

Upvotes: 2

lluisaznar
lluisaznar

Reputation: 2393

I faced the same problem with a long form. Javascript was not an option for me, so I ended up with a fully HTML-CSS solution.

The main goal was to code it just working with percentages, in order to have an easy way to build the media queries.

I've tested it with Firefox 22.0, Google Chrome 28.0.1500.71, Safari 6.0.5 and IE8. Here's the demo.

Modal HTML Structure:

The key is to have the structural divs clean from padding/margin/border. All these styles should be applied to the items inside them.

<div id="dialog" class="modal hide dialog1" aria-hidden="false">
    <div class="modal-header">
    </div>
    <div class="modal-body">
        <div>
        </div>
    </div>
</div>

Styles:

The styles applied to these structure divs are the ones which determines its size.

.modal.dialog1 { /* customized styles. this way you can have N dialogs, each one with its own size styles */
    width: 60%;
    height: 50%;
    left: 20%; /* ( window's width [100%] - dialog's width [60%] ) / 2 */
}

/* media query for mobile devices */
@media ( max-width: 480px ) {
    .modal.dialog1 {
        height: 90%;
        left: 5%; /* ( window's width [100%] - dialog's width [90%] ) / 2 */
        top: 5%;
        width: 90%;
    }
}

/* split the modal in two divs (header and body) with defined heights */
.modal .modal-header {
    height: 10%;
}

.modal .modal-body {
    height: 90%;
}

/* The div inside modal-body is the key; there's where we put the content (which may need the vertical scrollbar) */
.modal .modal-body div {
    height: 100%;
    overflow-y: auto;
    width: 100%;
}

For more detailed code, refer to the demo, where you'll see whole styling classes and those bootstrap styles which needs to be disabled/overriden.

Upvotes: 6

GianFS
GianFS

Reputation: 2605

try this Bootstrap Modal v2.1

https://github.com/jschr/bootstrap-modal

Upvotes: 4

Pwnna
Pwnna

Reputation: 9528

I caved in and wrote coffeescript to fix this. If anyone's interested, here's the coffeescript:

fit_modal_body = (modal) ->
  header = $(".modal-header", modal)
  body = $(".modal-body", modal)

  modalheight = parseInt(modal.css("height"))
  headerheight = parseInt(header.css("height")) + parseInt(header.css("padding-top")) + parseInt(header.css("padding-bottom"))
  bodypaddings = parseInt(body.css("padding-top")) + parseInt(body.css("padding-bottom"))

  height = modalheight - headerheight - bodypaddings - 5 # fudge factor

  body.css("max-height", "#{height}px")

# Here you need to bind your event with the appropriate modal, as an example:
$(window).resize(() -> fit_modal_body($(".modal")))

Or the equivalent javascript as generated per above.

var fit_modal_body;

fit_modal_body = function(modal) {
  var body, bodypaddings, header, headerheight, height, modalheight;
  header = $(".modal-header", modal);
  body = $(".modal-body", modal);
  modalheight = parseInt(modal.css("height"));
  headerheight = parseInt(header.css("height")) + parseInt(header.css("padding-top")) + parseInt(header.css("padding-bottom"));
  bodypaddings = parseInt(body.css("padding-top")) + parseInt(body.css("padding-bottom"));
  height = modalheight - headerheight - bodypaddings - 5;
  return body.css("max-height", "" + height + "px");
};

$(window).resize(function() {
  return fit_modal_body($(".modal"));
});

Upvotes: 9

Guffa
Guffa

Reputation: 700192

Make the html and body elements fill the window:

html, body { height: 100%; }

Now you can use max-height: 100% on the element inside body, and it will be 100% of the window as the body element now is the size of the window.

Upvotes: 0

Luke
Luke

Reputation: 8407

you should try to position it absolutly within an element whose position is set to relative. There you then can work with something like

{
    bottom:0;
    top:0;
    left:0;
    right:0;

Upvotes: 0

Related Questions