Solución:
La altura de un elemento de bloque tiene como valor predeterminado la altura del contenido del bloque. Entonces, dado algo como esto:
<div id="outer">
<div id="inner">
<p>Where is pancakes house?</p>
</div>
</div>
#inner
crecerá hasta ser lo suficientemente alto como para contener el párrafo y #outer
crecerá hasta ser lo suficientemente alto como para contener #inner
.
Cuando especifica la altura o el ancho como un porcentaje, es un porcentaje con respecto al padre del elemento. En el caso del ancho, todos los elementos de bloque son, a menos que se especifique lo contrario, tan anchos como su padre hasta <html>
; entonces, el ancho de un elemento de bloque es independiente de su contenido y dice width: 50%
produce un número bien definido de píxeles.
Sin embargo, la altura de un elemento de bloque depende de su contenido a menos que especifique una altura específica. Por lo tanto, hay una retroalimentación entre el padre y el niño en lo que respecta a la altura y se dice height: 50%
no produce un valor bien definido a menos que rompa el ciclo de retroalimentación dando al elemento padre una altura específica.
Un valor porcentual en un height
La propiedad tiene una pequeña complicación, y el width
y height
las propiedades en realidad se comportan de manera diferente entre sí. Déjame llevarte en un recorrido por las especificaciones.
height
propiedad:
Echemos un vistazo a lo que dice la especificación CSS Snapshot 2010 sobre height
:
El porcentaje se calcula con respecto a la altura de la caja generada bloque que contiene. Si la altura del bloque contenedor no se especifica explícitamente (es decir, depende de la altura del contenido), y este elemento no está absolutamente posicionado, el valor se calcula como ‘auto’. Un porcentaje de altura en el elemento raíz es relativo a la bloque contenedor inicial. Nota: Para elementos absolutamente posicionados cuyo bloque contenedor se basa en un elemento a nivel de bloque, el porcentaje se calcula con respecto a la altura del cuadro de relleno de ese elemento.
Bien, desarmemos eso paso a paso:
El porcentaje se calcula con respecto a la altura de la caja generada bloque que contiene.
¿Qué es un bloque contenedor? Es un poco complicado, pero para un elemento normal por defecto static
posición, es:
la caja de antepasados de contenedor de bloques más cercana
o en inglés, su caja principal. (Vale la pena saber para qué sería fixed
y absolute
posiciones también, pero lo estoy ignorando para que esta respuesta sea breve).
Así que tome estos dos ejemplos:
<div id="a" style="width: 100px; height: 200px; background-color: orange">
<div id="aa" style="width: 100px; height: 50%; background-color: blue"></div>
</div>
<div id="b" style="width: 100px; background-color: orange">
<div id="bb" style="width: 100px; height: 50%; background-color: blue"></div>
</div>
En este ejemplo, el bloque contenedor de #aa
es #a
y así sucesivamente para #b
y #bb
. Hasta aquí todo bien.
La siguiente oración de la especificación para height
es la complicación que mencioné en la introducción a esta respuesta:
Si la altura del bloque contenedor no se especifica explícitamente (es decir, depende de la altura del contenido), y este elemento no está absolutamente posicionado, el valor se calcula en ‘auto’.
¡Ajá! ¡Importa explícitamente si la altura del bloque contenedor se ha especificado!
- 50% de
height:200px
es 100px en el caso de#aa
- Pero el 50% de
height:auto
esauto
, que es 0px en el caso de#bb
ya que no hay contenido paraauto
expandirse a
Como dice la especificación, también importa si el bloque contenedor se ha posicionado absolutamente o no, pero pasemos a width
.
width
propiedad:
Entonces, ¿funciona de la misma manera para width
? Echemos un vistazo a la especificación:
El porcentaje se calcula con respecto al ancho del bloque contenedor de la caja generada.
Eche un vistazo a estos ejemplos familiares, modificados del anterior para variar width
en lugar de height
:
<div id="c" style="width: 200px; height: 100px; background-color: orange">
<div id="cc" style="width: 50%; height: 100px; background-color: blue"></div>
</div>
<div id="d" style=" height: 100px; background-color: orange">
<div id="dd" style="width: 50%; height: 100px; background-color: blue"></div>
</div>
- 50% de
width:200px
es 100px en el caso de#cc
- 50% de
width:auto
es el 50% de lo que seawidth:auto
termina siendo, a diferencia deheight
, no existe una regla especial que trate este caso de manera diferente.
Ahora, aquí está la parte complicada: auto
significa cosas diferentes, dependiendo en parte de si se ha especificado para width
o height
! Para height
, solo significaba la altura necesaria para adaptarse al contenido *, pero para width
, auto
en realidad es más complicado. Puede ver en el fragmento de código que en este caso terminó siendo el ancho de la ventana gráfica.
¿Qué dice la especificación sobre el valor automático para el ancho?
El ancho depende de los valores de otras propiedades. Consulte las secciones siguientes.
Wahey, eso no ayuda. Para evitarle problemas, le encontré la sección correspondiente a nuestro caso de uso, titulada “cálculo de anchos y márgenes”, subtitulada “elementos a nivel de bloque, no reemplazados en flujo normal”:
Las siguientes restricciones deben mantenerse entre los valores usados de las otras propiedades:
‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ = ancho del bloque contenedor
OK entonces width
más el margen relevante, el borde y los bordes de relleno deben sumarse al ancho del bloque contenedor (no descendientes el camino height
obras). Solo una oración más específica:
Si ‘ancho’ se establece en ‘auto’, cualquier otro valor de ‘auto’ se convierte en ‘0’ y ‘ancho’ se sigue de la igualdad resultante.
¡Ajá! Entonces, en este caso, el 50% de width:auto
es el 50% de la ventana gráfica. ¡Ojalá todo finalmente tenga sentido ahora!
Notas al pie
* Al menos, por lo que importa en este caso. spec De acuerdo, todo tiene sentido ahora.
Creo que solo necesita darle un contenedor principal … incluso si la altura de ese contenedor está definida en porcentaje. Esto parece funcionar bien: JSFiddle
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.wrapper {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 50%;
}