Quiero tener un menú vertical con una altura específica.
Cada niño debe llenar la altura del padre y tener texto alineado en el medio.
El número de hijos es aleatorio, así que tengo que trabajar con valores dinámicos.
Div .container
contiene un número aleatorio de hijos ( .item
) que siempre tienen que llenar la altura del padre. Para lograr eso usé flexbox.
Para hacer enlaces con texto alineado al medio, estoy usando la display: table-cell
técnica. Pero el uso de pantallas de mesa requiere el uso de una altura del 100%.
Mi problema es que .item-inner { height: 100% }
no funciona en webkit (Chrome).
- ¿Hay alguna solución para este problema?
- ¿O hay una técnica diferente para hacer que todos
.item
llenen la altura del padre con texto vertical alineado al medio?
Ejemplo aquí jsFiddle, debe verse en Firefox y Chrome
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
.item {
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
height: 100%;
width: 100%;
display: table;
}
a {
background: orange;
display: table-cell;
vertical-align: middle;
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
css
google-chrome
webkit
flexbox
Ricardo Castañeda
fuente
fuente
top:0
yleft:0
hacer que aparezca como se esperaba.Respuestas:
Solución
Use contenedores flexibles anidados.
Deshágase de las alturas porcentuales. Deshágase de las propiedades de la tabla. Deshacerse de
vertical-align
. Evitar el posicionamiento absoluto. Solo quédate con flexbox hasta el final.Aplique
display: flex
al elemento flexible (.item
), convirtiéndolo en un contenedor flexible. Esto se establece automáticamentealign-items: stretch
, lo que le dice al niño (.item-inner
) que expanda la altura completa del padre.Importante: elimine las alturas especificadas de los elementos flexibles para que este método funcione. Si un niño tiene una altura especificada (p
height: 100%
. Ej. ), Ignorará laalign-items: stretch
llegada del padre. Para que elstretch
valor predeterminado funcione, la altura del niño debe calcularauto
(explicación completa ).Pruebe esto (sin cambios en HTML):
Mostrar fragmento de código
jsFiddle demo
Explicación
No funciona porque está utilizando el porcentaje de altura de una manera que no se ajusta a la implementación tradicional de la especificación.
En otras palabras, para que la altura porcentual funcione en un elemento secundario en flujo, el elemento primario debe tener una altura establecida.
En su código, el contenedor de nivel superior tiene una altura definida:
.container { height: 20em; }
El contenedor de tercer nivel tiene una altura definida:
.item-inner { height: 100%; }
Pero entre ellos, el contenedor de segundo nivel
.item
- no tiene una altura definida. Webkit lo ve como un eslabón perdido..item-inner
le está diciendo a Chrome: dameheight: 100%
. Chrome mira al padre (.item
) como referencia y responde: ¿ 100% de qué? No veo nada (ignorando laflex: 1
regla que está allí). Como resultado, se aplicaheight: auto
(altura de contenido), de acuerdo con la especificación.Firefox, por otro lado, ahora acepta la altura flexible de un padre como referencia para la altura porcentual del niño. IE11 y Edge también aceptan alturas flexibles.
Además, Chrome aceptará
flex-grow
como referencia principal adecuada si se usa junto conflex-basis
(cualquier valor numérico funciona (auto
no lo hará), incluidoflex-basis: 0
). Al escribir estas líneas, sin embargo, esta solución falla en Safari.Mostrar fragmento de código
Cuatro soluciones
1. Especifique una altura en todos los elementos principales
Una solución confiable para varios navegadores es especificar una altura en todos los elementos principales. Esto evita la falta de enlaces, que los navegadores basados en Webkit consideran una violación de la especificación.
Tenga en cuenta que
min-height
ymax-height
no son aceptables. Debe ser laheight
propiedad.Más detalles aquí: trabajar con la
height
propiedad CSS y los valores de porcentaje2. Posicionamiento relativo y absoluto de CSS
Aplicar
position: relative
a los padres yposition: absolute
al niño.Tamaño del niño con
height: 100%
ywidth: 100%
, o utilizar las propiedades de desplazamiento:top: 0
,right: 0
,bottom: 0
,left: 0
.Con posicionamiento absoluto, la altura porcentual funciona sin una altura especificada en el padre.
3. Eliminar contenedores HTML innecesarios (recomendado)
¿Hay necesidad de dos contenedores alrededor
button
? ¿Por qué no eliminar.item
o.item-inner
, o ambos? Aunque losbutton
elementos a veces fallan como contenedores flexibles , pueden ser elementos flexibles. Considere crearbutton
un hijo de.container
o.item
y eliminar el marcado gratuito.Aquí hay un ejemplo:
Mostrar fragmento de código
4. Contenedores flexibles anidados (recomendado)
Deshágase de las alturas porcentuales. Deshágase de las propiedades de la tabla. Deshacerse de
vertical-align
. Evitar el posicionamiento absoluto. Solo quédate con flexbox hasta el final.Aplique
display: flex
al elemento flexible (.item
), convirtiéndolo en un contenedor flexible. Esto se establece automáticamentealign-items: stretch
, lo que le dice al niño (.item-inner
) que expanda la altura completa del padre.Importante: elimine las alturas especificadas de los elementos flexibles para que este método funcione. Si un niño tiene una altura especificada (p
height: 100%
. Ej. ), Ignorará laalign-items: stretch
llegada del padre. Para que elstretch
valor predeterminado funcione, la altura del niño debe calcularauto
(explicación completa ).Pruebe esto (sin cambios en HTML):
Mostrar fragmento de código
jsFiddle
fuente
Solución: eliminar
height: 100%
en .item-inner y agregardisplay: flex
en .itemDemostración: https://codepen.io/tronghiep92/pen/NvzVoo
fuente
Especificar un atributo flex para el contenedor funcionó para mí:
Esto asegura que la altura esté establecida y que tampoco crezca.
fuente
Para Safari móvil Hay una solución de navegador. necesita agregar -webkit-box para dispositivos iOS.
Ex.
Si está utilizando la
align-items: stretch;
propiedad para el elemento primario, elimine laheight : 100%
del elemento secundario.fuente
He tenido un problema similar en iOS 8, 9 y 10 y la información anterior no pudo solucionarlo, sin embargo, descubrí una solución después de un día de trabajar en esto. De acuerdo, no funcionará para todos, pero en mi caso mis artículos se apilaron en una columna y tenían una altura de 0 cuando debería haber sido altura de contenido. Cambiar el CSS para que sea fila y ajuste solucionó el problema. Esto solo funciona si tiene un solo elemento y están apilados, pero como me llevó un día descubrirlo, ¡pensé que debería compartir mi solución!
fuente
Tuve un error similar, pero mientras usaba un número fijo para la altura y no un porcentaje. También era un contenedor flexible dentro del cuerpo (que no tiene una altura especificada). Parecía que en Safari, mi contenedor flexible tenía una altura de 9px por alguna razón, pero en todos los demás navegadores mostraba la altura correcta de 100px especificada en la hoja de estilo.
Logré que funcionara agregando las propiedades
height
ymin-height
a la clase CSS.Lo siguiente funcionó para mí en Safari 13.0.4 y Chrome 79.0.3945.130:
¡Espero que esto ayude!
fuente