user2613813
user2613813

Reputation: 1971

Vertically centering Bootstrap modal window

I would like to center my modal on the viewport (middle) I tried to add some css properties

 .modal { position: fixed; top:50%; left:50%; }   

I'm using this example http://jsfiddle.net/rniemeyer/Wjjnd/

I tried

$("#MyModal").modal('show').css(
    {
        'margin-top': function () {
            return -($(this).height() / 2);
        },
        'margin-left': function () {
            return -($(this).width() / 2);
        }
    })

Upvotes: 193

Views: 302747

Answers (30)

Max
Max

Reputation: 150

Bootstrap 5 comes now with the class modal-dialog-centered this will center the modal for you

Upvotes: 0

Bluerain
Bluerain

Reputation: 506

Just ignore all the Upper methods. It will work with Bootstrap versions 4 and 5.

openModal(template: TemplateRef) { this.modalRef = this.modalService.show(template, {class: 'modal-sm modal-dialog-centered'}); }

Upvotes: 0

Tayyab Roy
Tayyab Roy

Reputation: 513

Vertically centered Add .modal-dialog-centered to .modal-dialog to vertically center the modal

Launch demo modal

<!-- 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="exampleModalCenterTitle">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</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

jcaruso
jcaruso

Reputation: 2504

As of Bootstrap 4 the following class was added to achieve this for you without JavaScript.

modal-dialog-centered

You can find their documentation here.

Thanks v.d for pointing out you need to add both .modal-dialog-centered to .modal-dialog to vertically center the modal.

Upvotes: 27

RdN
RdN

Reputation: 3273

This does the job : http://jsfiddle.net/sRmLV/1140/

It uses a helper-div and some custom css. No javascript or jQuery required.

HTML (based on Bootstrap's demo-code)

<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Launch demo modal</button>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="vertical-alignment-helper">
        <div class="modal-dialog vertical-align-center">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span>

                    </button>
                     <h4 class="modal-title" id="myModalLabel">Modal title</h4>

                </div>
                <div class="modal-body">...</div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-primary">Save changes</button>
                </div>
            </div>
        </div>
    </div>
</div>

CSS

.vertical-alignment-helper {
    display:table;
    height: 100%;
    width: 100%;
    pointer-events:none; /* This makes sure that we can still click outside of the modal to close it */
}
.vertical-align-center {
    /* To center vertically */
    display: table-cell;
    vertical-align: middle;
    pointer-events:none;
}
.modal-content {
    /* Bootstrap sets the size of the modal in the modal-dialog class, we need to inherit it */
    width:inherit;
    max-width:inherit; /* For Bootstrap 4 - to avoid the modal window stretching full width */
    height:inherit;
    /* To center horizontally */
    margin: 0 auto;
    pointer-events: all;
}

Upvotes: 269

AmirHossein Manian
AmirHossein Manian

Reputation: 617

this Works for me perfectly:

.modal {
text-align: center;
padding: 0!important;
}

.modal:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -4px;
}

.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
}

complete Demo URL : https://codepen.io/dimbslmh/full/mKfCc

Upvotes: 16

Michael Oxborrow
Michael Oxborrow

Reputation: 431

.modal.in .modal-dialog {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

Upvotes: 3

yogesh mhetre
yogesh mhetre

Reputation: 121

The best solution to centralize your modal with width and height is, in css add and in modal add this 'centralize' as a class..

.centralize{
   position:absolute;
   left:50%;
   top:50%;

   background-color:#fff;
   transform: translate(-50%, -50%);
   width: 40%; //specify watever u want
   height: 50%;
   }

Upvotes: 0

tao
tao

Reputation: 90277

Advantages:

  • modal contents accessible even when taller than device
  • doesn't use display:table-cell (that's not meant for layouts)
  • does not require any modifications to default Bootstrap 3 modal markup
  • positioning is pure CSS. The JS is added for closing the modal on click/tap below and above it
  • I included the un-prefixed SCSS for those who use gulp or grunt

// closes the modal on click/tap below/above the modal

$('.modal-dialog').on('click tap', function(e){
    if (e.target.classList.contains('modal-dialog')) {
    $('.modal').modal('hide');
  }
})
.modal-dialog {
  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-y: auto;
  min-height: -webkit-calc(100vh - 60px);
  min-height: -moz-calc(100vh - 60px);
  min-height: calc(100vh - 60px);
}
@media (max-width: 767px) {
  .modal-dialog {
    min-height: -webkit-calc(100vh - 20px);
    min-height: -moz-calc(100vh - 20px);
    min-height: calc(100vh - 20px);
  }
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/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://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Launch demo modal
</button>

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <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">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

Note: I intend to keep this answer up to date with the latest specs of Bootstrap 3. For a Bootstrap 4 solution, see this answer (for now they are more or less the same, but in time they might diverge). If you find any bug or problem with it, let me know and I will update. Thanks.


Clean, un-prefixed SCSS (for use with gulp/grunt):

.modal-dialog {
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow-y: auto;
  min-height: calc(100vh - 60px);
  @media (max-width: 767px) {
    min-height: calc(100vh - 20px);
  }
}

Upvotes: 8

No one
No one

Reputation: 1140

No need to us javascript. Boostrap modal adds .in class when it appears. Just modify this class combination with modalclassName.fade.in with flex css and you are done.

add this css to center your modal vertically and horizontally.

.modal.fade.in {
    display: flex !important;
    justify-content: center;
    align-items: center;
}
.modal.fade.in .modal-dialog {
    width: 100%;
}

Upvotes: 3

Greg Blass
Greg Blass

Reputation: 3660

The cleanest and simplest way to do this is to use Flexbox! The following will vertically align a Bootstrap 3 modal in the center of the screen and is so much cleaner and simpler than all of the other solutions posted here:

body.modal-open .modal.in {
  display: flex !important;
  align-items: center;
}

NOTE: While this is the simplest solution, it may not work for everyone due to browser support: http://caniuse.com/#feat=flexbox

It looks like (per usual) IE lags behind. In my case, all the products I develop for myself or for clients are IE10+. (it doesn't make sense business wise to invest development time supporting older versions of IE when it could be used to actually develop the product and get the MVP out faster). This is certainly not a luxury that everyone has.

I have seen larger sites detect whether or not flexbox is supported and apply a class to the body of the page - but that level of front-end engineering is pretty robust, and you'd still need a fallback.

I would encourage people to embrace the future of the web. Flexbox is awesome and you should start using it if you can.

P.S. - This site really helped me grasp flexbox as a whole and apply it to any use case: http://flexboxfroggy.com/

EDIT: In the case of two modals on one page, this should apply to .modal.in

Upvotes: 8

dsanchez
dsanchez

Reputation: 1268

Another CSS answer to this question...
This solution uses CSS only to achieve the desired effect while still maintaining the ability to close the modal by clicking outside of it. It also allows you to set .modal-content height and width maximums so that your pop-up won't grow beyond the viewport. A scroll will automatically appear when the content grows beyond the modal size.

note:
The Bootstrap recommended .modal-dialog div should be omitted in order for this to work properly (doesn't seem to break anything). Tested in Chrome 51 and IE 11.

CSS Code:

.modal {
   height: 100%;
   width: 100%;
}

.modal-content {
   margin: 0 auto;
   max-height: 600px;
   max-width: 50%;
   overflow: auto;
   transform: translateY(-50%);
}

EDIT: The .modal-dialog class allows you to choose whether or not a user can close the modal by clicking outside of the modal itself. Most modals have an explicit 'close' or 'cancel' button. Keep this in mind when using this workaround.

Upvotes: 0

Vit Koumar
Vit Koumar

Reputation: 41

I think this is a bit cleaner pure CSS solution than Rens de Nobel's solution. Also this does not prevent from closing the dialog by clicking outside of it.

http://plnkr.co/edit/JCGVZQ?p=preview

Just add some CSS class to DIV container with .modal-dialog class to gain higher specificity than the bootstraps CSS, e.g. .centered.

HTML

<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
  <div class="modal-dialog centered modal-lg">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

And make this .modal-dialog.centered container fixed and properly positioned.

CSS

.modal .modal-dialog.centered {
    position: fixed;
    bottom: 50%;
    right: 50%;
    transform: translate(50%, 50%);
}

Or even simpler using flexbox.

CSS

.modal {
    display: flex;
    align-items: center;
    justify-content: center;
}

Upvotes: 2

Robert McKee
Robert McKee

Reputation: 21477

Because most of the answer here didn't work, or only partially worked:

body.modal-open .modal[style]:not([style='display: none;']) {
    display: flex !important;
    height: 100%;
} 

body.modal-open .modal[style]:not([style='display: none;']) .modal-dialog {
    margin: auto;
}

You have to use the [style] selector to only apply the style on the modal that is currently active instead of all the modals. .in would have been great, but it appears to be added only after the transition is complete which is too late and makes for some really bad transitions. Fortunately it appears bootstrap always applies a style attribute on the modal just as it is starting to show so this is a bit hacky, but it works.

The :not([style='display: none;']) portion is a workaround to bootstrap not correctly removing the style attribute and instead setting the style display to none when you close the dialog.

Upvotes: 12

Aryeh Armon
Aryeh Armon

Reputation: 2185

you can use:

.modal {
    position: fixed;
    top: 50% !important;
    left: 50%;
    transform: translate(-50%, -50%);
}

to center it both vertically and horizontally.

Upvotes: 11

Rakesh Vadnal
Rakesh Vadnal

Reputation: 985

Use this simple script that centers the modals.

If you want you can set a custom class (ex: .modal.modal-vcenter instead of .modal) to limit the functionality only to some modals.

var modalVerticalCenterClass = ".modal";

function centerModals($element) {
    var $modals;
    if ($element.length) {
      $modals = $element;
    } else {
    $modals = $(modalVerticalCenterClass + ':visible');
}
$modals.each( function(i) {
    var $clone = $(this).clone().css('display', 'block').appendTo('body');
    var top = Math.round(($clone.height() - $clone.find('.modal-content').height()) / 2);
    top = top > 0 ? top : 0;
    $clone.remove();
    $(this).find('.modal-content').css("margin-top", top);
});
}
$(modalVerticalCenterClass).on('show.bs.modal', function(e) {
    centerModals($(this));
});
$(window).on('resize', centerModals);

Also add this CSS fix for the modal's horizontal spacing; we show the scroll on the modals, the body scrolls is hidden automatically by Bootstrap:

/* scroll fixes */
.modal-open .modal {
  padding-left: 0px !important;
  padding-right: 0px !important;
  overflow-y: scroll;
}

Upvotes: 0

taha shahid
taha shahid

Reputation: 727

Best way I found for all HTML5 browsers:

body.modal-open .modal {
    display: flex !important;
    height: 100%;
} 

body.modal-open .modal .modal-dialog {
    margin: auto;
}

Upvotes: 72

Jyotirmoy Pan
Jyotirmoy Pan

Reputation: 857

For those who are using angular-ui bootstrap can add the below classes based on above info:

Note: No other changes are needed and it shall resolve all modals.

// The 3 below classes have been placed to make the modal vertically centered
.modal-open .modal{
    display:table !important;
    height: 100%;
    width: 100%;
    pointer-events:none; /* This makes sure that we can still click outside of the modal to close it */
}

.modal-dialog{
    display: table-cell;
    vertical-align: middle;
    pointer-events: none;
}

.modal-content {
    /* Bootstrap sets the size of the modal in the modal-dialog class, we need to inherit it */
    width:inherit;
    height:inherit;
    /* To center horizontally */
    margin: 0 auto;
    pointer-events: all;
}

Upvotes: 3

mathieu
mathieu

Reputation: 31

Based on Arany's answer, but also accounting for page scroll.

(function($) {
    "use strict";
    function positionModals(e) {
        var $this = $(this).css('display', 'block'),
            $window = $(window),
            $dialog = $this.find('.modal-dialog'),
            offset = ($window.height() - $window.scrollTop() - $dialog.height()) / 2,
            marginBottom = parseInt($dialog.css('margin-bottom'), 10);

        $dialog.css('margin-top', offset < marginBottom ? marginBottom : offset);
    }

    $(document).on('show.bs.modal', '.modal', positionModals);

    $(window).on('resize', function(e) {
        $('.modal:visible').each(positionModals);
    });
}(jQuery));

Upvotes: 2

Arany
Arany

Reputation: 1238

Because gpcola's answer didn't work for me, I edited a bit so its works now. I used "margin-top" instead of transform. Also, i use the "show" instead of "shown" event because after it gave me a very bad jump of positioning (visible when you have bootstrap animations on). Be sure to set the display to "block" before positioning, otherwise $dialog.height() will be 0 and the modal will not be centered completely.

(function ($) {
    "use strict";
    function centerModal() {
        $(this).css('display', 'block');
        var $dialog  = $(this).find(".modal-dialog"),
        offset       = ($(window).height() - $dialog.height()) / 2,
        bottomMargin = parseInt($dialog.css('marginBottom'), 10);

        // Make sure you don't hide the top part of the modal w/ a negative margin if it's longer than the screen height, and keep the margin equal to the bottom margin of the modal
        if(offset < bottomMargin) offset = bottomMargin;
        $dialog.css("margin-top", offset);
    }

    $(document).on('show.bs.modal', '.modal', centerModal);
    $(window).on("resize", function () {
        $('.modal:visible').each(centerModal);
    });
}(jQuery));

Upvotes: 93

Shankar Prakash G
Shankar Prakash G

Reputation: 1129

Simply add the following CSS to you existing one,It works fine for me

.modal {
  text-align: center;
}
@media screen and (min-width: 768px) {
    .modal:before {
      display: inline-block;
      vertical-align: middle;
      content: " ";
      height: 100%;
    }
}
.modal-dialog {
  display: inline-block;
  text-align: left;
  vertical-align: middle;
}

Upvotes: 2

pravin
pravin

Reputation: 1153

Yet another CSS solution. Does not Work for popups that are bigger than the view port.

.modal-dialog {
    position: absolute;
    right: 0;
    left: 0;
    margin-top: 0;
    margin-bottom: 0; 
}
.modal.fade .modal-dialog {
    transition: top 0.4s ease-out;
    transform: translate(0, -50%);
    top: 0;
}
.modal.in .modal-dialog {
    transform: translate(0, -50%);
    top: 50%;
}

In .modal-dialog class overriding the position to absolute(from relative) and centering the content right:0, left: 0

In .modal.fade .modal-dialog , .modal.in .modal-dialog setting the transition animation over top rather than on translate.

margin-top moves the popup slightly below the center in case of small popup and in case of long popups, the modal is stuck with header. Hence margin-top:0, margin-bottom:0

Need to further refine it.

Upvotes: 3

John Bernardsson
John Bernardsson

Reputation: 1781

My choice, just a little CSS: ( NOT working in IE8 )

.modal.fade .modal-dialog {
    transform: translate(-50%, -80%);
}

.modal.in .modal-dialog {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin-top: 0px;
}

You can play with the first rule to change how the modal appears.

Using: Bootstrap 3.3.4

Upvotes: 2

andersra
andersra

Reputation: 1135

To add vertical modal centering to bootstrap modal.js I added this at the end of the Modal.prototype.show function:

var $modalDialog = $('.modal-dialog'),
        modalHeight = $modalDialog.height(),
        browserHeight = window.innerHeight;

    $modalDialog.css({'margin-top' : modalHeight >= browserHeight ? 0 : (browserHeight - modalHeight)/2});

Upvotes: 1

user3389
user3389

Reputation: 489

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="table">
        <div class="table-cell">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
                    </div>
                    <div class="modal-body">
                        ...
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        <button type="button" class="btn btn-primary">Save changes</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

// Styles

.table {
 display: table;
 height:100%;
}
.table-cell {
display: table-cell;
vertical-align: middle;
}

Upvotes: 25

user3690101
user3690101

Reputation: 21

To make Modal verically Align Middle All dialog.

/* Note:

1.Even you don't need to assign selector , it will find all modal from the document and make it vertically middle

2.To avoid middle some specific modal to be it center you can use :not selector in click event

*/

 $( "[data-toggle='modal']" ).click(function(){
     var d_tar = $(this).attr('data-target'); 
     $(d_tar).show();   
     var modal_he = $(d_tar).find('.modal-dialog .modal-content').height(); 
     var win_height = $(window).height();
     var marr = win_height - modal_he;
     $('.modal-dialog').css('margin-top',marr/2);
  });

From Milan Pandya

Upvotes: 0

jetlej
jetlej

Reputation: 3392

This takes Arany's answer and makes it work if the modal is taller than the height of the screen:

function centerModal() {
    $(this).css('display', 'block');
    var $dialog = $(this).find(".modal-dialog");
    var offset = ($(window).height() - $dialog.height()) / 2;
    //Make sure you don't hide the top part of the modal w/ a negative margin if it's longer than the screen height, and keep the margin equal to the bottom margin of the modal
    var bottomMargin = $dialog.css('marginBottom');
    bottomMargin = parseInt(bottomMargin);
    if(offset < bottomMargin) offset = bottomMargin;
    $dialog.css("margin-top", offset);
}

$('.modal').on('show.bs.modal', centerModal);
$(window).on("resize", function () {
    $('.modal:visible').each(centerModal);
});

Upvotes: 1

EGurelli
EGurelli

Reputation: 416

You can achieve vertical alignment center on Bootstrap 3 modal like that :

.modal-vertical-centered {
  transform: translate(0, 50%) !important;
  -ms-transform: translate(0, 50%) !important; /* IE 9 */
  -webkit-transform: translate(0, 50%) !important; /* Safari and Chrome */
}

and add this css class to the "modal-dialog" container

<div class="modal-dialog modal-vertical-centered">
...

jsFiddle working example : http://jsfiddle.net/U4NRx/

Upvotes: 9

Tomtom
Tomtom

Reputation: 11

e(document).on('show.bs.modal', function () {
        if($winWidth < $(window).width()){
            $('body.modal-open,.navbar-fixed-top,.navbar-fixed-bottom').css('marginRight',$(window).width()-$winWidth)
        }
    });
    e(document).on('hidden.bs.modal', function () {
        $('body,.navbar-fixed-top,.navbar-fixed-bottom').css('marginRight',0)
    });

Upvotes: 1

gpcola
gpcola

Reputation: 1009

This works in BS3, not tested in v2. It centers the modal vertically. Note that it will transition there - if you want it to just appear in position edit CSS transition property for .modal-dialog

centerModal = function() {
    var $dialog = $(this).find(".modal-dialog"),
        offset = ($(window).height() - $dialog.height()) / 2;

    // Center modal vertically in window
    $dialog.css({
        'transform': 'translateY(' + offset + 'px) !important',
    });
};

$('.modal').on('shown.bs.modal', centerModal);
$(window).on("resize", function() {
    $('.modal').each(centerModal);
});

Upvotes: 1

Related Questions