41

I'm looking for a way to keep a modal dialog within screen bounds, i.e. that its height is always less than the screen height and the width is adjusted accordingly. I tried:

.modal-dialog {
  max-height: 100%;
}

but this doesn't seem to have any effect.

http://jsfiddle.net/ma4zn5gv/

An illustration:

enter image description here

I prefer a pure CSS solution (no js) if it exists. For clarity, I'm looking for max-height, not height (i.e. is the modal is no taller than screen, leave it as is).

Danield
  • 121,619
  • 37
  • 226
  • 255
georg
  • 211,518
  • 52
  • 313
  • 390
  • Any reason to not use someone else's jQuery plugin? Googling "responsive modal" turns up many options, and I'm 99% sure one of them would meet your needs – henry Mar 05 '15 at 14:35

9 Answers9

79

Use viewport units with calc. Like this:

.img-responsive {
    max-height: calc(100vh - 225px);
}

...where the 225px corresponds to the combined height of the top and bottom sections of the viewport which surround the dialog.

Also, in order to take care of the width of the modal we need to set a few more properties:

.modal {
    text-align:center;
}
.modal-dialog {
    display: inline-block;
    width: auto;
}

Updated Fiddle (Resize the viewport height to see the effect)


Alternatively:

We can replace calc with a padding + negative margin technique like so:

.img-responsive {
    max-height: 100vh;
    margin: -113px 0;
    padding: 113px 0;
}

FIDDLE

PS: browser support for viewport units is very good

Danield
  • 121,619
  • 37
  • 226
  • 255
  • 2
    Oh wow. I had no idea how good browser support has become - for viewport units as well as calc(). – j4k3 Mar 04 '15 at 14:16
  • I don't like `calc` for the image. Is it possible to get rid of it? – georg Mar 04 '15 at 14:44
  • You could use something less than 100vh (full height of viewport), like 90vh, although this would vary from device to device.. – plushyObject Mar 05 '15 at 01:47
  • @georg I updated thie answer with an approach which doesn't use `calc` – Danield Mar 09 '15 at 09:34
  • Forgive my ignorance, but where does 225px come from in the first solution and what is 113px in the second? If I change fonts and margins should I recalculate these numbers? – wigy Mar 11 '15 at 10:13
  • @wigy We want the image to fill the screen vertically - while still leaving enough room for the top and bottom sections of the dialog plus additional top and bottom margin of the dialog wrt. the screen. So the value 225px is just an example. The value should be adjusted according to how big you want the dialog to be wrt. the screen height – Danield Mar 11 '15 at 10:24
  • I thank you for I've got new insight in calc(100vh - 225px); :D – Joe Kdw Mar 12 '15 at 02:55
  • I have had this component on my site bugging me for months. Came across your solution and it finally fixed it. Thank you so much! – Bilbonic Jan 12 '22 at 01:10
11

Target the modal-body and not the modal-dialog.

Add the following to your CSS:

max-height: 80vh;
overflow-y: auto;

It should look like this:

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

Adjust the VH height to preference.

Prince Lionel N'zi
  • 2,510
  • 2
  • 12
  • 27
Juan J
  • 413
  • 6
  • 12
  • What's the reason that the modal body needs to be targeted rather than the element as a whole, which also includes the modal header and footer? – Hashim Aziz Dec 13 '21 at 23:04
  • Just a guess based on my own experimentation, but the whole modal _could_ be targeted. The difference is that the header and footer won't be "sticky" to the top and bottom (it will scroll with the contents), which is probably not the desired behavior. Also, targeting the modal-content doesn't "shrink" the viewport of the contents, because it's by default display:flex. – Joe Sadoski Feb 04 '22 at 14:48
3

Script

$('#myModal').on('show.bs.modal', function () {
$('.modal-content').css('max-height',$( window ).height()*0.8);
$('.modal-content img').css('max-height',(($( window ).height()*0.8)-86));
});

Fiddle

Richie Fredicson
  • 2,150
  • 3
  • 16
  • 19
3

Since the default value set to auto and 100% in width and height. you just be able to modify; the image inside the viewport and the target ID, as follows:

/*let target has the same value as modal-dialog*/
#myModal {
    width:auto;
    height:auto;
    margin:0 auto;
}
/*modify image inside modal-dialog*/
.modal-dialog,.modal-dialog img { /*same value to avoid overwidth*/
    width:70%;
    height:70%;
    margin:0 auto;
}

Here's the DEMO in jsfiddle.

You also can separate it into, as follows:

.modal-dialog img {
    width:100%;
    height:100%;
    margin:0 auto;
}
.modal-dialog {/*modify the modal-dialog*/
/*ONLY CHANGE THIS, NOT others (#myModal or .modal-image img)*/
    width:60%;
    height:60%;
    margin:0 auto;
}

UPDATED DEMO:

Joe Kdw
  • 2,245
  • 1
  • 21
  • 38
  • if you set the image into img-responsive, the changes in .modal-dialog img as codes above will not give bad display in width and height – Joe Kdw Mar 11 '15 at 10:29
2

If you ensure that the parent elements have a height set, then you should be able to do it pretty easily. I have given the header and footer 10 percent heights hear and the body 80 percent so that it all adds up to 100 :)

.modal, .modal-dialog, .modal-content{
  height: 100%;

}
.modal-header, .modal-footer {height:10%;}
.modal-body {height:80%;}
.img-responsive {
    max-height:100%;
}
Achilles
  • 41
  • 5
  • 1
    The image still expands out of the model in Chrome and Firefox: [jsFiddle](http://jsfiddle.net/ma4zn5gv/37/) – Rison Mar 10 '15 at 05:39
  • ahh sorry about that. the paragraph would also have to have the height of 100%. I've updated the code here. [jsFiddle](http://jsfiddle.net/zt0jn1c0/) `.modal-content p{ height: 100%; }` – Achilles Mar 10 '15 at 23:13
  • Also, if the most outer parent of the modal is set to max-height then the model should squeeze within that as well. It's all about making sure all of the topmost parent is set to only be as tall as the browser. – Achilles Mar 10 '15 at 23:21
2

Fix the container size first, then set modal-dialog size.

For example:

.modal{height:100%;width:50%;margin: 0 auto;}
.modal-dialog{overflow:hidden; max-height:96%;}

Fiddle

Kanti
  • 1,062
  • 1
  • 10
  • 27
1

If you provide max-height and max-width to 100% then it will take automatically accordingly screen but as you want this dialog size smaller then you will have to set max-height and max-width to some fix value. As you have already used responsive model dialog so it will change dialog size automatically as per your screen size.

Try following css it may work as per your requirement. you can change max-height and max-width accordingly, margin-left and margin-right used for center align.

 .modal-dialog {
      max-height: 225px;
      max-width:  200px; 
      margin-left: auto;
      margin-right: auto;
    }

Hope it may help you.!!

Ranjitsinh
  • 1,323
  • 1
  • 11
  • 28
1

Try working Fiddle with some css changes.

css:

.modal-dialog {
 height: 100%;
 margin: 0;
 padding: 10px;
}
.modal-content { height:100%; }
.modal-body {
position: absolute;
padding: 15px;
left:0;
right:0;
top: 55px;
bottom: 65px;
margin: auto;
}
.modal-body > p {
height: 100%;
margin: 0;
}
.img-responsive{
max-height: 100%;
max-width: 100%;
margin:auto;
}
.modal-footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
Amit
  • 827
  • 10
  • 17
0

I think you should use overflow: hidden on .modal-dialog, with a style to mantain the image proportion.

David Vartanian
  • 460
  • 4
  • 12
  • Can you post a fiddle? – georg Mar 11 '15 at 08:34
  • You're right unfortunately, it's harder than I thought! I've been trying for a while without success, sorry... But maybe this helps: http://appendto.com/2014/03/responsive-approach-image-scaling-css/ – David Vartanian Mar 11 '15 at 12:34