html - tutorial - No se puede desplazar a la parte superior del elemento flexible que está desbordando el contenedor
webkit box (7)
El problema
Flexbox hace que el centrado sea muy fácil.
Simplemente aplicando
align-items: center
y
justify-content: center
al contenedor flexible, sus elementos flexibles estarán centrados vertical y horizontalmente.
Sin embargo, hay un problema con este método cuando el elemento flexible es más grande que el contenedor flexible.
Como se señaló en la pregunta, cuando el elemento flexible desborda el contenedor, la parte superior se vuelve inaccesible.
Para el desbordamiento horizontal, la sección izquierda se vuelve inaccesible (o la sección derecha, en lenguajes RTL).
Aquí hay un ejemplo con un contenedor LTR que tiene
justify-content: center
y tres elementos flexibles:
Consulte la parte inferior de esta respuesta para obtener una explicación de este comportamiento.
Solución n. ° 1
Para solucionar este problema, utilice los
márgenes automáticos de flexbox
, en lugar de
justify-content
.
Con los márgenes
auto
, un elemento flexible que se desborda puede centrarse vertical y horizontalmente sin perder el acceso a ninguna parte del mismo.
Entonces, en lugar de este código en el contenedor flexible:
#flex-container {
align-items: center;
justify-content: center;
}
Use este código en el elemento flexible:
.flex-item {
margin: auto;
}
Solución n. ° 2 (aún no implementada en la mayoría de los navegadores)
Agregue el valor
safe
a su regla de alineación de palabras clave, así:
justify-content: safe center
o
align-self: safe center
De la especificación del módulo de alineación de caja CSS :
4.4. Alineación de desbordamiento: las palabras clave
safe
eunsafe
y los límites de seguridad de desplazamientoCuando el [elemento flexible] es más grande que el [contenedor flexible], se desbordará. Algunos modos de alineación, si se cumplen en esta situación, pueden causar pérdida de datos: por ejemplo, si los contenidos de una barra lateral están centrados, cuando se desbordan, pueden enviar parte de sus cuadros más allá del borde inicial de la ventana gráfica, que no se puede desplazar a .
Para controlar esta situación, se puede especificar explícitamente un modo de alineación de desbordamiento .
Unsafe
alineaciónUnsafe
respeta el modo de alineación especificado en situaciones de desbordamiento, incluso si causa pérdida de datos, mientras quesafe
alineaciónsafe
cambia el modo de alineación en situaciones de desbordamiento en un intento de evitar la pérdida de datos.El comportamiento predeterminado es contener el asunto de alineación dentro del área desplazable, aunque al momento de escribir esta característica de seguridad aún no está implementada.
safe
Si el tamaño del [elemento flexible] desborda el [contenedor flexible], el [elemento flexible] se alinea como si el modo de alineación fuera [
flex-start
].
unsafe
Independientemente de los tamaños relativos de [elemento flexible] y [contenedor flexible], se respeta el valor de alineación dado.
Nota: El módulo de alineación de cajas se usa en varios modelos de diseño de cajas, no solo en flex.
Entonces, en el extracto de la especificación anterior, los términos entre paréntesis en realidad dicen "sujeto de alineación", "contenedor de alineación" y "
start
".
Usé términos específicos de flex para mantener el enfoque en este problema en particular.
Explicación para la limitación de desplazamiento de MDN:
Consideraciones de artículos flexibles
Las propiedades de alineación de Flexbox hacen un centrado "verdadero", a diferencia de otros métodos de centrado en CSS. Esto significa que los elementos flexibles permanecerán centrados, incluso si desbordan el contenedor flexible.
Sin embargo, esto a veces puede ser problemático si se desbordan más allá del borde superior de la página o del borde izquierdo, ya que no puede desplazarse a esa área, ¡incluso si hay contenido allí!
En una versión futura, las propiedades de alineación se ampliarán para tener también una opción "segura".
Por ahora, si esto es una preocupación, puede usar márgenes para lograr el centrado, ya que responderán de una manera "segura" y dejarán de centrarse si se desbordan.
En lugar de usar las propiedades de
align-
, simplemente coloque márgenesauto
en los elementos flexibles que desea centrar.En lugar de las propiedades de
justify-
, coloque márgenes automáticos en los bordes exteriores del primer y último elemento flexible en el contenedor flexible.Los márgenes
auto
se "flexionarán" y asumirán el espacio sobrante, centrando los elementos flexibles cuando haya espacio sobrante y cambiando a alineación normal cuando no lo sea.Sin embargo, si está tratando de reemplazar
justify-content
con un centrado basado en márgenes en una caja flexible de varias líneas, probablemente no tenga suerte, ya que necesita colocar los márgenes en el primer y último elemento flexible en cada línea. A menos que pueda predecir con anticipación qué elementos terminarán en qué línea, no puede utilizar de manera confiable el centrado basado en márgenes en el eje principal para reemplazar la propiedad dejustify-content
.
Entonces, al intentar hacer un modo útil usando flexbox, encontré lo que parece ser un problema del navegador y me pregunto si hay una solución o solución conocida, o ideas sobre cómo resolverlo.
Lo que estoy tratando de resolver tiene dos aspectos. Primero, obtener la ventana modal centrada verticalmente, que funciona como se esperaba. El segundo es hacer que la ventana modal se desplace, externamente, de modo que toda la ventana modal se desplace, no el contenido dentro de ella (esto es para que pueda tener menús desplegables y otros elementos de la interfaz de usuario que se puedan extender fuera de los límites del modal) como un selector de fecha personalizado, etc.)
Sin embargo, al combinar el centrado vertical con las barras de desplazamiento, la parte superior del modal puede volverse inaccesible a medida que comienza a desbordarse. En el ejemplo anterior, puede cambiar el tamaño para forzar el desbordamiento, y al hacerlo le permite desplazarse hacia la parte inferior del modal, pero no hacia la parte superior (el primer párrafo se corta).
Aquí está el enlace al código de ejemplo (altamente simplificado)
https://jsfiddle.net/dh9k18k0/2/
.modal-container {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
overflow-x: auto;
}
.modal-container .modal-window {
display: -ms-flexbox;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// Optional support to confirm scroll behavior makes sense in IE10
//-ms-flex-direction: column;
//-ms-flex-align: center;
//-ms-flex-pack: center;
height: 100%;
}
.modal-container .modal-window .modal-content {
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
width: 100%;
max-width: 500px;
padding: 10px
}
Esto afecta (actual) a Firefox, Safari, Chrome y Opera. Curiosamente se comporta correctamente en IE10 si comenta en el CSS prefijado del vendedor de IE10. Todavía no me molesté en probar en IE11, pero supongo que el comportamiento coincide con el de IE10 .
Cualquier idea sería buena. Los enlaces a problemas conocidos o el razonamiento detrás de este comportamiento también serían útiles.
2 Método Flex de contenedor con tabla de respaldo probada IE8-9, flex funciona en IE10,11. Editar: editado para garantizar el centrado vertical cuando el contenido es mínimo, se agregó soporte heredado.
El problema se debe a que la altura se hereda del tamaño de la ventana gráfica, lo que hace que los niños se desborden, como respondió Michael. https://.com/a/33455342/3500688
algo más simple y use flex para mantener el diseño dentro del contenedor emergente (contenido):
#popup {
position: fixed;
top: 0;
left: 0;
right: 0;
min-height: 100vh;
background-color: rgba(0,0,0,.25);
margin: auto;
overflow: auto;
height: 100%;
bottom: 0;
display: flex;
align-items: flex-start;
box-sizing:border-box;
padding:2em 20px;
}
.container {
background-color: #fff;
margin: auto;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
/* width: 100%; */
max-width: 500px;
padding: 10px;
/* display: flex; */
/* flex-wrap: wrap; */
}
<!--[if lt IE 10]>
<style>
#popup {
display: table;
width:100%;
}
.iewrapper {
display: table-cell;
vertical-align: middle;
}
</style>
<![endif]-->
<div id="popup">
<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
<div class="container">
<p class="p3">Test</p>
<p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry''s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry''s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
</div>
Bueno, como diría la Ley de Murphy, la lectura que hice después de publicar esta pregunta resultó en algunos resultados, no completamente resueltos, pero de alguna manera útiles.
Jugué un poco con la altura mínima un poco antes de publicar, pero no estaba al tanto de las restricciones de tamaño intrínsecas que son bastante nuevas para la especificación.
http://caniuse.com/#feat=intrinsic-width
Agregar un
min-height: min-content
al área de flexbox resuelve el problema en Chrome, y con los prefijos de los proveedores también se corrige Opera y Safari, aunque Firefox sigue sin resolverse.
min-height: -moz-min-content; // not implemented
min-height: -webkit-min-content // works for opera and safari
min-height: min-content // works for chrome
Todavía estoy buscando ideas sobre Firefox y otras posibles soluciones.
Creo que encontré una solución. Funciona con mucho texto y un poco de texto . No necesita especificar el ancho de nada, y debería funcionar en IE8.
.wrap1 {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
overflow-y: auto;
}
.wrap2 {
display: table;
width: 100%;
height: 100%;
text-align: center;
}
.wrap3 {
vertical-align: middle;
display: table-cell;
}
.wrap4 {
margin: 10px;
}
.dialog {
text-align: left;
background-color: white;
padding: 5px;
border-radius: 3px;
margin: auto;
display: inline-block;
box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
}
<div class="wrap1">
<div class="wrap2">
<div class="wrap3">
<div class="wrap4">
<div class="dialog">
<p>Lorem ipsum dolor sit amet.</p>
</div>
</div>
</div>
</div>
</div>
Logré lograr esto con solo 3 contenedores. El truco consiste en separar el contenedor flexbox del contenedor que controla el desplazamiento. Por último, coloque todo en un contenedor raíz para centrarlo todo. Estos son los estilos esenciales para crear el efecto:
CSS:
.root {
display: flex;
justify-content: center;
align-items: center;
}
.scroll-container {
margin: auto;
max-height: 100%;
overflow: auto;
}
.flex-container {
display: flex;
flex-direction: column;
justify-content: center;
}
HTML:
<div class="root">
<div class="scroll-container">
<div class="flex-container">
<p>Lorem ipsum dolor sit amet.</p>
</div>
</div>
</div>
He creado una demostración aquí: https://jsfiddle.net/r5jxtgba/14/
Según MDN, el valor
safe
ahora se puede proporcionar a propiedades como
align-items
y
align-items
.
Se describe de la siguiente manera:
Si el tamaño del elemento desborda el contenedor de alineación, el elemento se alineará como si se
start
modo de alineación.
Por lo tanto, podría usarse de la siguiente manera.
.rule
{
display: flex;
flex-direction: row;
justify-content: center;
align-items: safe center;
}
Sin embargo, no está claro cuánto soporte de navegador tiene, no pude encontrar ningún ejemplo de su uso, y yo también he tenido algunos problemas. Mencionándolo aquí para llamar más la atención.
También logré hacerlo usando un contenedor extra
HTML
<div class="modal-container">
<div class="modal">
<div class="content-container">
<div class="content">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry''s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
</div>
</div>
</div>
CSS
.modal-container {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: black;
}
.modal {
display: flex;
justify-content: center;
align-items: center;
background-color: #aaa;
height: 80%;
width: 90%;
}
.content-container {
background-color: blue;
max-height: 100%;
overflow: auto;
padding:0;
}
.content {
display: flex;
background-color: red;
padding: 5px;
width: 900px;
height: 300px;
}
en jsfiddle> https://jsfiddle.net/Nash171/cpf4weq5/
cambiar los valores de ancho / alto de contenido y ver