Centro de posición vertical modal Bootstrap 3

Esta es una pregunta de dos partes:

  1. ¿Cómo se puede colocar el modal verticalmente en el centro cuando no se conoce la altura exacta del modal?

  2. ¿Es posible tener el modal centrado y tener overflow: auto en el cuerpo modal, pero solo si el modal excede la altura de la pantalla?

He intentado usar esto:

.modal-dialog { height: 80% !important; padding-top:10%; } .modal-content { height: 100% !important; overflow:visible; } .modal-body { height: 80%; overflow: auto; } 

Esto me da el resultado que necesito cuando el contenido es mucho más grande que el tamaño de pantalla vertical, pero para los contenidos modales pequeños es prácticamente inutilizable.

 .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; } 

Y ajuste un poco la clase .fade para asegurarse de que aparece fuera del borde superior de la ventana, en lugar del centro

1. ¿Cómo se puede colocar el modal verticalmente en el centro cuando no se conoce la altura exacta del modal?

Para centrar por completo el Bootstrap 3 Modal sin declarar una altura, primero deberá sobrescribir el Bootstrap CSS agregándolo a su hoja de estilos:

 .modal-dialog-center { /* Edited classname 10/03/2014 */ margin: 0; position: absolute; top: 50%; left: 50%; } 

Esto colocará la esquina superior izquierda de diálogo modal en el centro de la ventana.

Tenemos que agregar esta consulta de medios o el margen modal izquierdo es incorrecto en dispositivos pequeños:

 @media (max-width: 767px) { .modal-dialog-center { /* Edited classname 10/03/2014 */ width: 100%; } } 

Ahora necesitaremos ajustar su posición con JavaScript. Para hacer eso le damos al elemento un margen negativo superior e izquierdo igual a la mitad de su altura y ancho. En este ejemplo usaremos jQuery ya que está disponible con 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); } }); }); 

Actualización (01/10/2015):

Añadiendo la respuesta de Finik . Créditos para centrarse en lo desconocido .

 .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; } 

Observe el margen negativo, ¿verdad? Esto elimina el espacio agregado por el bloque en línea. Ese espacio hace que el modal salte al final de la página @media width <768px.

2. ¿Es posible tener el modal centrado y tener overflow: auto en el cuerpo modal, pero solo si el modal excede la altura de la pantalla?

Esto es posible otorgando al cuerpo modal un desbordamiento-y: automático y un máximo de altura. Esto requiere un poco más de trabajo para que funcione correctamente. Comience agregando esto a su hoja de estilo:

 .modal-body { overflow-y: auto; } .modal-footer { margin-top: 0; } 

Usaremos jQuery nuevamente para obtener la altura de la ventana y establecer la altura máxima del contenido modal primero. Luego, debemos establecer la altura máxima del cuerpo modal, restando el contenido modal con el encabezado modal y el pie de página 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); } }); }); 

Puede encontrar una demostración funcional aquí con Bootstrap 3.0.3: http://cdpn.io/GwvrJ EDITAR: Recomiendo usar la versión actualizada en su lugar para una solución más receptiva: http://cdpn.io/mKfCc

Actualización (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')); } }); 

(Actualizado el 30/11/2015 http://cdpn.io/mKfCc con la edición anterior)

Mi solución

 .modal-dialog-center { margin-top: 25%; }  

Simplemente se puede arreglar con 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); } 

Con prefijo

 .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); } 

¡Se me ocurrió una solución de CSS pura! Sin embargo, es css3, lo que significa que ie8 o inferior no es compatible, pero aparte de esto, está probado y funciona en ios, android, ie9 +, cromo, firefox, safari de escritorio …

Estoy usando el siguiente CSS:

 .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; } 

Aquí hay un violín. http://codepen.io/anon/pen/Hiskj

… seleccionando esto como la respuesta correcta, ya que no hay javascript extra pesado que pone al navegador de rodillas en caso de más de un modo.

Si estás de acuerdo con el uso de flexbox, esto debería ayudar a resolverlo.

 .modal-dialog { height: 100%; width: 100%; display: flex; align-items: center; } .modal-content { margin: 0 auto; } 

Todo lo que hice en mi caso es establecer el Top en mi CSS sabiendo la altura del modal

en mi css puse

 #myModal{ height: 400px; top: calc(50% - 200px) !important; } 

Mi solución:

 .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%); } 

Ampliando la excelente respuesta de @ Finik, esta solución solo se aplica a dispositivos que no son móviles. Probé en IE8, Chrome y Firefox 22, funciona con contenido muy largo o corto.

 .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; } 

Hay una manera más fácil de hacer esto usando css:

 .modal-dialog { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; width:500px; height:300px; } 

Eso es. Tenga en cuenta que solo es necesario aplicarlo a .modal-dialog container div.

Demostración: https://jsfiddle.net/darioferrer/0ueu4dmy/

La solución más universal que escribí. Calcula dinámicamente con la altura del diálogo. (El siguiente paso podría ser volver a calcular la altura de los diálogos en el tamaño de la ventana).

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', ''); } }); }); 

Encontré la solución perfecta desde aquí

 $(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 } }); 

He descargado el cuadro de diálogo bootstrap3 desde el enlace de abajo y he modificado la función de abrir en bootstrap-dialog.js

https://github.com/nakupanda/bootstrap3-dialog

Código

 open: function () { !this.isRealized() && this.realize(); this.updateClosable(); //Custom To Vertically centering Bootstrap var $mymodal = this.getModal(); $mymodal = $mymodal.append('
'); $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; } 

Aquí hay otro método CSS que funciona bastante bien y se basa en esto: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/

hablar con descaro a:

 .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; } } 

Pruebe algo como esto:

 .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 } 

Es posible que desee consultar esta colección de métodos para centrar por completo un div: http://codepen.io/shshaw/full/gEiDt

otra solución más que establecerá una posición válida para cada modal visible en el evento window.resize y en 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); 

Sé que es un poco tarde, pero estoy agregando una nueva respuesta para que no se pierda entre la multitud. Es una solución cross-desktop-mobile-browser que funciona en todas partes como debe.

Solo necesita que el modal-dialog esté dentro de una clase modal-dialog-wrap y necesite tener las siguientes adiciones de código:

 .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; } 

El diálogo comienza centrado y, en el caso de un gran contenido, simplemente crece verticalmente hasta que aparece una barra de desplazamiento.

¡Aquí hay un violín que funciona para su placer!

https://jsfiddle.net/v6u82mvu/1/

Esto funciona para mí:

 .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; } 

Considere usar el complemento modal de arranque que se encuentra aquí – https://github.com/jschr/bootstrap-modal

El complemento centrará todos tus modales

Para el centrado, no entiendo qué pasa con las soluciones demasiado complicadas. bootstrap ya lo centra horizontalmente para usted, por lo que no necesita meterse con esto. Mi solución solo establece un margen superior solo con jQuery.

 $('#myModal').on('loaded.bs.modal', function() { $(this).find('.modal-dialog').css({ 'margin-top': function () { return (($(window).outerHeight() / 2) - ($(this).outerHeight() / 2)); } }); }); 

He utilizado el evento loaded.bs.modal porque estoy cargando contenido de forma remota y el uso del evento shown.ba.modal hace que el cálculo de altura sea incorrecto. Por supuesto, puede agregar un evento para cambiar el tamaño de la ventana si necesita que responda de esa manera.

Una manera muy muy fácil de lograr este concepto y obtendrá modal siempre en el moddle de su pantalla por css como fllow: http://jsfiddle.net/jy0zc2jc/1/

solo tiene que mostrar la clase modal como tabla siguiendo a css:

 display:table 

y modal-dialog como display:table-cell

ver ejemplo de trabajo completo en violín dado

no es tan complicado.

por favor intente esto:

 $(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(); }); }); 

Una manera simple. Trabaja para mi. Thks rensdenobel 🙂 http://jsfiddle.net/rensdenobel/sRmLV/13/

      

Use este sencillo script que centra los modales.

Si lo desea, puede establecer una clase personalizada (por ejemplo: .modal.modal-vcenter en lugar de .modal) para limitar la funcionalidad solo a algunos modales.

 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); 

También agregue este arreglo CSS para el espaciado horizontal modal; mostramos el pergamino en los modales, el cuerpo se desplaza automáticamente por Bootstrap:

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

En la planta móvil puede parecer un poco diferente, aquí está mi código.

  

Estilo de tabla