Bootstrap 3 modal position verticale center
C'est une question en deux parties:
Comment Pouvez-vous positionner le modal verticalement au centre lorsque vous ne connaissez pas la hauteur exacte du modal?
Est-il possible d'avoir le modal centré et d'avoir un débordement: auto dans le corps modal, mais seulement si le modal dépasse la hauteur de l'écran?
J'ai essayé d'utiliser ceci:
.modal-dialog {
height: 80% !important;
padding-top:10%;
}
.modal-content {
height: 100% !important;
overflow:visible;
}
.modal-body {
height: 80%;
overflow: auto;
}
Cela me donne le résultat dont j'ai besoin lorsque le contenu est beaucoup plus grand que la taille d'écran verticale, mais pour les petits modaux le contenu c'est à peu près inutilisable.
29 réponses
.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;
}
Et ajustez un peu .fade classe pour s'assurer qu'il apparaît hors de la bordure supérieure de la fenêtre, au lieu de center
1. Comment Pouvez-vous positionner le modal verticalement au centre lorsque vous ne connaissez pas la hauteur exacte du modal?
pour centrer le Modal Bootstrap 3 sans déclarer de hauteur, vous devrez d'abord écraser le CSS Bootstrap en ajoutant ceci à votre feuille de style:
.modal-dialog-center { /* Edited classname 10/03/2014 */
margin: 0;
position: absolute;
top: 50%;
left: 50%;
}
Cela positionnera les boîtes de dialogue modales en haut à gauche au centre de la fenêtre.
Nous devons ajouter cette requête média ou bien la marge modale-left est fausse sur petits appareils:
@media (max-width: 767px) {
.modal-dialog-center { /* Edited classname 10/03/2014 */
width: 100%;
}
}
Maintenant, nous allons devoir ajuster sa position avec JavaScript. Pour ce faire, nous donnons à l'élément une marge supérieure et gauche négative égale à la moitié de sa hauteur et de sa largeur. Dans cet exemple, nous utiliserons jQuery car il est disponible avec Bootstrap.
$('.modal').on('shown.bs.modal', function() {
$(this).find('.modal-dialog').css({
'margin-top': function () {
return -($(this).outerHeight() / 2);
},
'margin-left': function () {
return -($(this).outerWidth() / 2);
}
});
});
Mise à jour (01/10/2015):
Ajout de la réponse de Finik . Les crédits à Centrage dans l'Inconnu.
.modal {
text-align: center;
padding: 0!important;
}
.modal:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -4px; /* Adjusts for spacing */
}
.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
}
Notez la marge négative-droit? Cela supprime l'espace ajouté par inline-block. Cet espace fait sauter le modal au bas de la page @media width
2. Est-il possible d'avoir le modal centré et d'avoir un débordement: auto dans le corps modal, mais seulement si le modal dépasse la hauteur de l'écran?
Ceci est possible en donnant au modal-body un overflow-y: auto et une max-height. Cela prend un peu plus de travail pour le faire fonctionner correctement. Commencez par ajouter ceci à votre feuille de style:
.modal-body {
overflow-y: auto;
}
.modal-footer {
margin-top: 0;
}
Nous allons utiliser jQuery à nouveau pour obtenir la hauteur de la fenêtre et définir la hauteur maximale du contenu modal en premier. Ensuite, nous devons définir la hauteur maximale du corps modal, en soustrayant le contenu modal avec l'en-tête modal et le pied de page modal:
$('.modal').on('shown.bs.modal', function() {
var contentHeight = $(window).height() - 60;
var headerHeight = $(this).find('.modal-header').outerHeight() || 2;
var footerHeight = $(this).find('.modal-footer').outerHeight() || 2;
$(this).find('.modal-content').css({
'max-height': function () {
return contentHeight;
}
});
$(this).find('.modal-body').css({
'max-height': function () {
return (contentHeight - (headerHeight + footerHeight));
}
});
$(this).find('.modal-dialog').css({
'margin-top': function () {
return -($(this).outerHeight() / 2);
},
'margin-left': function () {
return -($(this).outerWidth() / 2);
}
});
});
Vous pouvez trouver une démo de travail ici avec Bootstrap 3.0.3: http://cdpn.io/GwvrJ EDIT: je recommande d'utiliser la version mise à jour à la place pour une solution plus réactive: http://cdpn.io/mKfCc
Mise à jour (30/11/2015):
function setModalMaxHeight(element) {
this.$element = $(element);
this.$content = this.$element.find('.modal-content');
var borderWidth = this.$content.outerHeight() - this.$content.innerHeight();
var dialogMargin = $(window).width() < 768 ? 20 : 60;
var contentHeight = $(window).height() - (dialogMargin + borderWidth);
var headerHeight = this.$element.find('.modal-header').outerHeight() || 0;
var footerHeight = this.$element.find('.modal-footer').outerHeight() || 0;
var maxHeight = contentHeight - (headerHeight + footerHeight);
this.$content.css({
'overflow': 'hidden'
});
this.$element
.find('.modal-body').css({
'max-height': maxHeight,
'overflow-y': 'auto'
});
}
$('.modal').on('show.bs.modal', function() {
$(this).show();
setModalMaxHeight(this);
});
$(window).resize(function() {
if ($('.modal.in').length != 0) {
setModalMaxHeight($('.modal.in'));
}
});
(mise à jour 30/11/2015 http://cdpn.io/mKfCc avec Édition ci-dessus)
Ma solution
.modal-dialog-center {
margin-top: 25%;
}
<div id="waitForm" class="modal">
<div class="modal-dialog modal-dialog-center">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 id="headerBlock" class="modal-title"></h4>
</div>
<div class="modal-body">
<span id="bodyBlock"></span>
<br/>
<p style="text-align: center">
<img src="@Url.Content("~/Content/images/progress-loader.gif")" alt="progress"/>
</p>
</div>
</div>
</div>
</div>
Il peut simplement être corrigé avec display: flex
.modal-dialog {
margin-top: 0;
margin-bottom: 0;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
.modal.fade .modal-dialog {
transform: translate(0, -100%);
}
.modal.in .modal-dialog {
transform: translate(0, 0);
}
Avec le préfixe
.modal-dialog {
margin-top: 0;
margin-bottom: 0;
height: 100vh;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.modal.fade .modal-dialog {
-webkit-transform: translate(0, -100%);
transform: translate(0, -100%);
}
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
Je suis venu avec une solution CSS pure! C'est css3 cependant, ce qui signifie que ie8 ou inférieur n'est pas pris en charge, mais à part cela, il est testé et fonctionne sur ios, android, ie9+, chrome, firefox, Desktop safari..
J'utilise le css suivant:
.modal-dialog {
position:absolute;
top:50% !important;
transform: translate(0, -50%) !important;
-ms-transform: translate(0, -50%) !important;
-webkit-transform: translate(0, -50%) !important;
margin:auto 5%;
width:90%;
height:80%;
}
.modal-content {
min-height:100%;
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
}
.modal-body {
position:absolute;
top:45px; /** height of header **/
bottom:45px; /** height of footer **/
left:0;
right:0;
overflow-y:auto;
}
.modal-footer {
position:absolute;
bottom:0;
left:0;
right:0;
}
Voici un violon. http://codepen.io/anon/pen/Hiskj
..en sélectionnant ceci comme la bonne réponse car il n'y a pas de javascript supplémentaire qui met le navigateur à genoux en cas de plus d'un modal.
Si vous êtes d'accord avec l'utilisation de flexbox, cela devrait aider à le résoudre.
.modal-dialog {
height: 100%;
width: 100%;
display: flex;
align-items: center;
}
.modal-content {
margin: 0 auto;
}
Tout ce que j'ai fait dans mon cas est de mettre le haut dans mon css en connaissant la hauteur du modal
<div id="myModal" class="modal fade"> ... </div>
Dans mon css, j'ai défini
#myModal{
height: 400px;
top: calc(50% - 200px) !important;
}
Ma solution:
.modal.in .modal-dialog
{
-webkit-transform: translate(0, calc(50vh - 50%));
-ms-transform: translate(0, 50vh) translate(0, -50%);
-o-transform: translate(0, calc(50vh - 50%));
transform: translate(0, 50vh) translate(0, -50%);
}
En développant l'excellente réponse de @ Finik, ce correctif n'est appliqué qu'aux appareils non mobiles. J'ai testé dans IE8, Chrome et Firefox 22-Il fonctionne avec un contenu très long ou court.
.modal {
text-align: center;
}
@media screen and (min-device-width: 768px) {
.modal:before {
display: inline-block;
vertical-align: middle;
content: " ";
height: 100%;
}
}
.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
}
Il existe un moyen le plus simple de le faire en utilisant css:
.modal-dialog {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width:500px;
height:300px;
}
C'est ça. Notez qu'il est seulement nécessaire d'être appliqué au conteneur .modal-dialog
Div.
Démonstration: https://jsfiddle.net/darioferrer/0ueu4dmy/
La solution la plus universelle que j'ai écrite. Calcule dynamiquement avec la hauteur de dialogue. (L'étape suivante pourrait être le recalcul de la hauteur des boîtes de dialogue sur le redimensionnement de la fenêtre.)
JSfiddle: http://jsfiddle.net/8Fvg9/3/
// initialise on document ready
jQuery(document).ready(function ($) {
'use strict';
// CENTERED MODALS
// phase one - store every dialog's height
$('.modal').each(function () {
var t = $(this),
d = t.find('.modal-dialog'),
fadeClass = (t.is('.fade') ? 'fade' : '');
// render dialog
t.removeClass('fade')
.addClass('invisible')
.css('display', 'block');
// read and store dialog height
d.data('height', d.height());
// hide dialog again
t.css('display', '')
.removeClass('invisible')
.addClass(fadeClass);
});
// phase two - set margin-top on every dialog show
$('.modal').on('show.bs.modal', function () {
var t = $(this),
d = t.find('.modal-dialog'),
dh = d.data('height'),
w = $(window).width(),
h = $(window).height();
// if it is desktop & dialog is lower than viewport
// (set your own values)
if (w > 380 && (dh + 60) < h) {
d.css('margin-top', Math.round(0.96 * (h - dh) / 2));
} else {
d.css('margin-top', '');
}
});
});
Trouvé la solution parfaite de ici
$(function() {
function reposition() {
var modal = $(this),
dialog = modal.find('.modal-dialog');
modal.css('display', 'block');
// Dividing by two centers the modal exactly, but dividing by three
// or four works better for larger screens.
dialog.css("margin-top", Math.max(0, ($(window).height() - dialog.height()) / 2));
}
// Reposition when a modal is shown
$('.modal').on('show.bs.modal', reposition);
// Reposition when the window is resized
$(window).on('resize', function() {
$('.modal:visible').each(reposition);
});
});
$('#myModal').on('shown.bs.modal', function() {
var initModalHeight = $('#modal-dialog').outerHeight(); //give an id to .mobile-dialog
var userScreenHeight = $(document).outerHeight();
if (initModalHeight > userScreenHeight) {
$('#modal-dialog').css('overflow', 'auto'); //set to overflow if no fit
} else {
$('#modal-dialog').css('margin-top',
(userScreenHeight / 2) - (initModalHeight/2)); //center it if it does fit
}
});
J'ai téléchargé bootstrap3-dialog à partir du lien ci-dessous et modifié la fonction d'ouverture dans bootstrap-dialog.js
Https://github.com/nakupanda/bootstrap3-dialog
Code
open: function () {
!this.isRealized() && this.realize();
this.updateClosable();
//Custom To Vertically centering Bootstrap
var $mymodal = this.getModal();
$mymodal = $mymodal.append('<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%"><tr><td align="center" valign="middle" class="centerModal"></td></tr></table>');
$mymodal = $mymodal.find(".modal-dialog").appendTo($mymodal.find(".centerModal"));
//END
this.getModal().modal('show');
return this;
}
Css
.centerModal .modal-header{
text-align:left;
}
.centerModal .modal-body{
text-align:left;
}
Voici une autre méthode CSS seulement qui fonctionne assez bien et est basée sur ceci: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
Sass:
.modal {
height: 100%;
.modal-dialog {
top: 50% !important;
margin-top:0;
margin-bottom:0;
}
//keep proper transitions on fade in
&.fade .modal-dialog {
transform: translateY(-100%) !important;
}
&.in .modal-dialog {
transform: translateY(-50%) !important;
}
}
Essayez quelque chose comme ceci:
.popup__overlay {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 999;
text-align: center
}
.popup {
display: inline-block;
vertical-align: middle
}
Vous voudrez peut-être consulter cette collection de méthodes pour le centrage absolu d'un div: http://codepen.io/shshaw/full/gEiDt
Encore une autre solution qui définira une position valide pour chaque modal visible sur window.resize
événement et sur show.bs.modal
:
(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);
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);
Je sais qu'il est un peu tard, mais j'ajoute une nouvelle réponse pour qu'elle ne se perde pas dans la foule. C'est une solution Cross-desktop-Mobile-browser qui fonctionne partout correctement comme il se doit.
Il faut juste que modal-dialog
soit enveloppé dans une classe modal-dialog-wrap
et avoir les ajouts de code suivants:
.modal-dialog-wrap {
display: table;
table-layout: fixed;
width: 100%;
height: 100%;
}
.modal-dialog {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.modal-content {
display: inline-block;
text-align: left;
}
La boîte de dialogue commence centrée et dans les cas de contenu volumineux, elle se développe simplement verticalement jusqu'à ce qu'une barre de défilement apparaisse.
Voici un violon de travail pour votre plaisir!
Cela fonctionne pour moi:
.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;
}
Pensez à utiliser le plugin Bootstrap-modal trouvé ici - https://github.com/jschr/bootstrap-modal
Le plugin centrera tous vos modals
Pour le centrage, Je ne comprends pas ce qu'il y a avec les solutions trop compliquées. bootstrap déjà centres horizontalement pour vous, donc vous n'avez pas besoin de jouer avec cela. Ma solution est juste de définir une marge supérieure uniquement en utilisant jQuery.
$('#myModal').on('loaded.bs.modal', function() {
$(this).find('.modal-dialog').css({
'margin-top': function () {
return (($(window).outerHeight() / 2) - ($(this).outerHeight() / 2));
}
});
});
J'ai utilisé l'événement loaded.BS.modal car je charge à distance le contenu, et l'utilisation de l'événement.ba.modal affiché provoque le calcul de la hauteur incorrect. Vous pouvez bien sûr ajouter un événement pour la fenêtre en cours de redimensionnement si vous en avez besoin sensible.
Moyen très très facile de réaliser ce concept et vous obtiendrez toujours modal dans le moddle de votre écran par css comme fllow: http://jsfiddle.net/jy0zc2jc/1/
Vous devez simplement modal
afficher la classe en tant que table en suivant css:
display:table
Et modal-dialog
comme display:table-cell
Voir l'exemple de travail complet dans fiddle donné
, Il n'est pas bien compliqué.
Veuillez essayer ceci:
$(document).ready(function(){
var modalId = "#myModal";
resize: function(){
var new_margin = Math.ceil(($(window).height() - $(modalId).find('.modal-dialog').height()) / 2);
$(modalId).find('.modal-dialog').css('margin-top', new_margin + 'px');
}
$(window).resize(function(){
resize();
});
$(modalId).on('shown.bs.modal', function(){
resize();
});
});
Un moyen simple. Le travail pour moi. Thks rensdenobel :) http://jsfiddle.net/rensdenobel/sRmLV/13/
<style>
.vertical-alignment-helper {
display:table;
height: 100%;
width: 100%;
}
.vertical-align-center {
/* To center vertically */
display: table-cell;
vertical-align: middle;
}
.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;
}
</style>
<!-- Button trigger modal -->
<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">×</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>
Utilisez ce script simple qui Centre les modaux.
Si vous le souhaitez, vous pouvez définir une classe personnalisée (ex: .modal.modal-vcenter au lieu de .modal) pour limiter la fonctionnalité uniquement à certains modaux.
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);
Ajoutez également ce correctif CSS pour l'espacement horizontal du modal; nous montrons le défilement sur les modaux, les défilement du corps sont masqués automatiquement par Bootstrap:
/* scroll fixes */
.modal-open .modal {
padding-left: 0px !important;
padding-right: 0px !important;
overflow-y: scroll;
}
Dans plantform mobile, cela pourrait sembler un peu différent, voici mon code.
<div class="modal-container">
<style>
.modal-dialog{
margin-top: 60%;
width:80%;
margin-left: 10%;
margin-right: 10%;
margin-bottom: 100%
}
@media screen and (orientation:landscape){
.modal-dialog{
margin-top: 70;
width:80%;
margin-left: 10%;
margin-right: 10%;
margin-bottom: 100%
}
}
.modal-body{
text-align: center;
}
.modal-body p{
margin:14px 0px;
font-size: 110%;
}
.modal-content{
border-radius: 10px;
}
.modal-footer{
padding:0px;
}
.modal-footer a{
padding: 15px;
}
.modal-footer a:nth-child(1){
border-radius: 0px 0px 0px 10px;
}
.modal-footer a:nth-child(2){
border-radius: 0px 0px 10px 0px;
}
</style>
<h2>Basic Modal Example</h2>
<div data-toggle="modal" data-target="#myModal">Div for modal</div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>确定要取消本次订单嘛?</p>
</div>
<div class="modal-footer">
<div class="btn-group btn-group-justified">
<a href="#" class="btn btn-default" data-dismiss="modal">取消</a>
<a href="#" class="btn btn-default" data-dismiss="modal">确定</a>
</div>
</div>
</div>
</div>
</div>
</div>
Style De Table
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<table height="100%" width="100%">
<tr><td valign="middle">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</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>
</td></tr>
</table>
</div>