Reputation: 90198
Vertically center modal dialogues in Bootstrap 4.
Note: The requirements below have been added to make it clear I am looking for a proper way to vertically center a Bootstrap modal, covering all possible cases, on all possible devices, in all browsers. In my case, I wanted it for a large SPA reusing the same modal throughout the app so I needed it to work in each case.
It should:
1%
display:table-cell
or similar hacks (any layout-ing technique not meant or designed for layout-ing)click
or tap
anywhere outside of .modal-content
(including above and below).Upvotes: 40
Views: 82703
Reputation: 571
Try this,
::ng-deep{
.modal-body{
padding: 0.25rem;
width: 600px !important;
}
.modal-content {
position: relative;
display: flex;
flex-direction: row;
margin-top: auto;
margin-bottom: auto;
width: 600px !important;
}
}
Upvotes: 0
Reputation: 513
Just use this class " modal-dialog-centered " for showing Modal on center of screen Vertically .
for exmaple:
<div class="modal-dialog modal-dialog-centered" role="document">
Thanks
Upvotes: 6
Reputation: 321
Simply add modal-dialog-centered class along with model-dialog as below
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<button class="btn btn-success" data-toggle="modal" data-target="#MyModal">Launch Modal</button>
<div class="modal align-middle" id="MyModal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal Title</h5>
<button class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">Lorem Ipsum is simply dummy text of the printing and typesetting industry</div>
<div class="modal-footer">
<button class="btn btn-info" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Upvotes: 13
Reputation: 1330
By adding following css to '.modal-dialog' class, it works fine for me. You can override with custom css class also.
.modal-dialog {
height: 100vh;
display: flex;
align-items: center;
}
Upvotes: 2
Reputation: 467
Add .modal-dialog-centered to .modal-dialog to vertically center the modal.
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Upvotes: 3
Reputation: 90198
Update, as of Beta 3, [docs]:
Add
.modal-dialog-centered
to.modal-dialog
to vertically center the modal.
Original answer:
SCSS
:
.modal-dialog {
min-height: calc(100vh - 60px);
display: flex;
flex-direction: column;
justify-content: center;
overflow: auto;
@media(max-width: 768px) {
min-height: calc(100vh - 20px);
}
}
or unprefixed CSS
:
.modal-dialog {
min-height: calc(100vh - 60px);
display: flex;
flex-direction: column;
justify-content: center;
overflow: auto;
}
@media(max-width: 768px) {
.modal-dialog {
min-height: calc(100vh - 20px);
}
}
Note 1: Please note fully prefixed CSS gradually becomes obsolete as browser support for certain properties changes. The right way of getting the updated prefixed CSS is to:
> 0%
).Note 2: This answer was added in early stages of v4 (alpha 3 or 4), which is now currently in beta. You can safely replace the CSS part of this answer by adding the following classes to .modal-dialog
:
h-100 d-flex flex-column justify-content-center my-0
..., as pointed out by @Androbaut in the comment below. You will still need the JavaScript (see below) to close the modal window on click tap
below/above the modal window.
jQuery
(needed to close modal on click/tap above/below):
$('.modal-dialog').on('click tap', function(e){
if ($(e.target).hasClass('modal-dialog')) {
$('.modal').modal('hide');
}
})
That's it.
Working snippet, fully-prefixed CSS and markup using different modal sizes:
$('.modal-dialog').on('click tap', function(e){
if ($(e.target).hasClass('modal-dialog')) {
$('.modal').modal('hide');
}
})
.modal-dialog {
min-height: -webkit-calc(100vh - 60px);
min-height: -moz-calc(100vh - 60px);
min-height: calc(100vh - 60px);
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
overflow: auto;
}
@media (max-width: 768px) {
.modal-dialog {
min-height: -webkit-calc(100vh - 20px);
min-height: -moz-calc(100vh - 20px);
min-height: calc(100vh - 20px);
}
}
/* you don't need the CSS below this line. It's mainly cosmetic and for aligning the modal launch buttons */
.modal-content {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column; }
.modal-content > * {
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-moz-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
}
.modal-content > *.modal-body {
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-moz-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
}
#Modal_2 .modal-content {
min-height: 50vh;
}
#Modal_3 .modal-content {
min-height: 85vh;
}
#Modal_4 .modal-content {
min-height: 200vh;
}
.full-page-center {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
min-height: 100vh;
}
.full-page-center button {
margin: 15px;
}
@media (max-width: 768px) {
.full-page-center {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.full-page-center button {
display: block;
min-width: 100%;
margin: 10px 15px;
}
.full-page-center::after {
display: none;
-webkit-box-flex: 0;
-webkit-flex-grow: 0;
-moz-box-flex: 0;
-ms-flex-positive: 0;
flex-grow: 0;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<div class="container full-page-center">
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#Modal_1">
Tiny modal
</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="modal" data-target="#Modal_2">
Normal modal
</button>
<button type="button" class="btn btn-success btn-lg" data-toggle="modal" data-target="#Modal_3">
Large modal
</button>
<button type="button" class="btn btn-warning btn-lg" data-toggle="modal" data-target="#Modal_4">
Very large modal
</button>
</div>
<div class="modal fade" id="Modal_1" tabindex="-1" role="dialog" aria-labelledby="modalLabel_1" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="modalLabel_1">Tiny modal</h4>
</div>
<div class="modal-body">
I am cute...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="Modal_2" tabindex="-1" role="dialog" aria-labelledby="modalLabel_2" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="modalLabel_2">Dull modal</h4>
</div>
<div class="modal-body">
I am normal...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Some action</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="Modal_3" tabindex="-1" role="dialog" aria-labelledby="modalLabel_3" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="modalLabel_3">Don't call me fat</h4>
</div>
<div class="modal-body">
Call me "oversized".
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success">Some action</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="Modal_4" tabindex="-1" role="dialog" aria-labelledby="modalLabel_4" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="modalLabel_4">Huge modal</h4>
</div>
<div class="modal-body">
Comments, anyone?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-warning">Some action</button>
</div>
</div>
</div>
</div>
If you find any bugs or shortcomings please let me know. I will take the time to improve the answer and keep it useful. Help with this task is welcome.
Upvotes: 91
Reputation: 6222
This solution works for small and long modals thats needs scroll.
Add these custom css rules:
.modal-header {
flex-shrink: 0;
}
.modal-body {
overflow-y: auto;
}
And add these classes:
modal-dialog
: h-100 my-0 mx-auto d-flex flex-column justify-content-center
modal-content
: m-2
Like this:
<div class="modal-dialog h-100 my-0 mx-auto d-flex flex-column justify-content-center" role="document">
<div class="modal-content m-2">
...
</div>
</div>
Upvotes: 3
Reputation: 10171
There is a much easier way of achieving this without having to write a bunch of CSS overrides or other custom CSS, basically using just the stock bootstrap classes and adding one extra HTML element to control the height.
.modal > .row{
flex: 1;
}
<div id="dialogBox" class="modal fade d-flex">
<div class="row justify-content-center"> <!-- Vertically Align Modal -->
<div class="modal-dialog align-self-center" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
$("#dialogBox").modal('show');
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dialogBox">
Launch demo modal
</button>
There is probably a way to achieve the desired result using only the bootstrap .row
, .col
and flex-XXX
classes but I was unable to get that to work.
One last note, you might have to add: <body class="d-flex">
to get everything to work depending on the rest of your CSS.
There is a way to achieve this using only bootstrap classes, h-100
and w-100
:
<div id="dialogBox" class="modal fade d-flex">
<div class="row justify-content-center w-100"> <!-- Vertically Align Modal -->
<div class="modal-dialog align-self-center" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 6740
Here's a simple Flexbox Approach.
SCSS
.modal-open .modal {
display: flex!important;
align-items: center!important;
.modal-dialog {
flex-grow: 1;
}
}
Upvotes: 7
Reputation: 3926
Another simple way to make your modal vertical align is to adjust top: 50%;
, transform: translateY(-50%);
and margin: 0 auto
to the modal dialog class.
Edit:
The downside is that you also have to set max-height: 100vh;
to .modal-content
. Otherwise the top of modal is not accessible anymore when your modal is getting heigher than the viewport.
Demo:
.modal.vertically-modal .modal-dialog {
transform: translateY(-25%);
top: 50%;
margin: 0 auto;
}
.modal.vertically-modal.show .modal-dialog {
transform: translateY(-50%);
}
.modal-content {
max-height: 100vh;
overflow-y: auto;
padding: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js "></script>
<button class="btn btn-primary" data-toggle="modal" data-target=".vertically-modal">Show modal</button>
<div class="modal fade vertically-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
Vertically modal
</div>
</div>
</div>
Upvotes: 1