Del Html y Body y los misterios de su altura en porcentajes

¿Por qué el body no ocupa toda la altura de la ventana pese a declararle height: 100%?

Del Html y Body y los misterios de su altura en porcentajes

Por Kseso ✎ 10
Del Html y Body y los misterios de su altura en porcentajes

Situación común, causante de muchas canas, arrugas y consultas con cara de no lo entiendo.

Hay un elemento cualquiera hijo directo del body y le encargas vía Css que de alto sea el 100% height: 100% y va y no hace caso.

O lo que es más desconcertante: le dices al 'body' que sea el 100% de alto y le pones un color para visualizarlo y no aparece por ningún lado y sólo va creciendo al ir añadiendo contenido. Como en este gif:

Del body y su pasotismo con height 100%

De la altura en %

De entrada y pese a lo intuitivo o no que resulte este comportamiento has de saber que es el correcto y el que corresponde según la especificación a las alturas declaradas en porcentajes:

La Propiedad height establece la altura de los elementos de bloque.
Si se declara en porcentaje, hace referencia a la altura del elemento en el que se encuentra (a su padre). Si este elemento contenedor no tiene establecida una altura de forma explícita y el elemento para el que se define la altura no está posicionado de forma absoluta, se ignora la altura en porcentaje y se sustituye por el valor auto.

Y qué pasa con el Html

Si vuelves al gif anterior notarás que el html pese a no tener declarado valor para la propiedad 'height' aparenta ocupar todo el alto de la ventana del navegador en todo momento, con o sin contenido.

Pero es eso, una apariencia, ya que su altura no es toda la ventana, como anota expresamente la especificación:

Una altura declarada en porcentaje en el elemento raíz es relativa al bloque inicial de contención.

Recuerda que el bloque inicial de contención para cualquier documento es el viewport o espacio (ventana) en el que se muestra.

Así que en ausencia de valor declarado explícitamente para la propiedad 'height' del html es el marcado como valor por defecto: 'auto'. Lo que significa que la altura del Html es la que fuerza su contenido. Y en ausencia de contenido y/u otras propiedades que la modifiquen es 0 (cero) como en cualquier otro elemento de bloque como un div.

Y sí, el fondo ocupa toda la ventana (su altura), pero es que es el único caso y propiedad en el que ocurre una "herencia ascendente". El valor del fondo del html (elemento raíz) es "heredado" por su caja de contención (el viewport). Sin embargo si declaras alguna otra propiedad como bordes, márgenes... al html verás qué ocurre:

See the Pen La cuestión de las alturas en % by Kseso (@Kseso) on CodePen.

La solución para la altura 100%

Hay dos formas para que el body ocupe toda la altura de la ventana pese a que su contenido sea menor.

La clásica de Css2.1

Declarar tanto al html como al body una altura del 100% (si estás seguro que su contenido será siempre menor al viewport o no alteras el overflow) o una altura mínima (min-height) del 100%.

La moderna: unidades relativas al viewport

Una segunda forma es utilizar las unidades relativas al viewport. En el caso que nos ocupa la unidad vh. Ya sea en la propiedad height o min-height según el modelo de caja que uses y cómo gestiones el desbordamiento (overflow) si los contenidos del documento superarán o no la altura del viewport.

Otros artículos sobre la propiedad background

  1. El fondo a fondo. Novedades Css3 en la propiedad background
  2. Relación entre fondos y bordes: background-clip y background-origin
  3. Background-blend-mode: guía para estar a la última en Css
  4. Background-position: secretos, curiosidades y un valor complejo recién documentado
  5. Algunas demos con la propiedad background como protagonista:
    1. Parallax scroll puro Css en todos los contenidos de la página
    2. Troceado de imagen y manejo independiente de cada parte puro Css. Dos sliders
    3. Sustituyendo Gif´s animados por Css y animación de sprites Css
    4. Ventana abierta al fondo del body: recortes en el background
    5. Background 100%. 2 técnicas
    6. Tipografía con texturas y rellenos de imagen
  6. ... Y otros muchos más. Sólo tienes que usar el buscador del blog.

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso

Comentarios: 10

  1. Estimado Don Kseso.

    Primero lo que ha ir primero, ¡Felicidades! por tus enredos en CSS que aportan, junto con tu manifiesta capacidad comunicativa, una imparable fuente de esparcimiento y conocimiento.

    Desde hace tiempo (no se precisar cuanto) que te sigo en tus interesantes enteradas en la bitácora (vulgo posts) y hay una pregunta que me planteo, ¿Cómo lograr la animación que tienes en a:hover? No recuerdo haber leído publicación a este respecto ¿me equivoco?.

    Disculpa si este no es el sitio correcto, pero no encuentro otro.

    ¡Ah! Por cierto, comparto lo del Beerware y me agradaría mucho poder pagar 1+

    ResponderEliminar
    Respuestas
    1. Hola HenryGR

      Gracias pero te pasaste con la cera xD Creo que ni es ni merezco tanto.

      Sobre el efecto al :hover: son varios los artículos que he dedicado a estos efectos y otros que se podrían aplicar con un mínimo de modificación, entre otros:
      .- Animando el Text-decoration
      .- Bordes giratorios: caminitos de hormigas
      .- Dibujado progresivo del contorno puro Css que seguramente es el que buscas.

      Sobre la licencia Beerware: hablando sobre Css sólo hay una postura: aquí lo tienes porque realmente es un a ver quién es el guapo que lo oculta xD
      No hay más. Y yo que soy de pueblo y campo se que es tontería poner puertas a lo que no tiene paredes ;-)

      ¿Te sientes en deuda o crees que merece la pena agradecer algo de alguna manera? Con el reconocimiento tengo suficiente, pero si quieres ir un paso más allá sin que te cueste 1 céntimo y si no usas bloqueadores (ABPlus o similares) eres libre usar tu ratón donde y como quieras ;-)

      Un saludo

      Eliminar
  2. Hola, creo que este es el lugar más idóneo para preguntar mi problema con la unidad relativa de porcentaje. Pero al no poder poner código html aquí voy a dejar el enlace donde esta esta misma pregunta, haber si puedes ayudarme.

    http://www.comocreartuweb.com/consultas/showthread.php/58594-problema-unidad-relativa-(porcentaje)

    ResponderEliminar
    Respuestas
    1. Hola Isaac
      Los comentarios del blog admiten código, pero se ha de pasar a texto plano (por limitaciones de Blogger).
      Pero para estos casos lo mejor es crear el ejemplo en Codepen.io e insertar el pen en el comentario.
      Tanto para una opción como para la otra tienes en el aside (a la derecha y arriba de la zona de comentarios en pantallas anchas) un enlace donde lo explico detalladamente (bajo el epígrafe Tags especiales).

      Bien, aclarado esto vamos con tu caso.

      La respuesta te la has dado tú en la cita de la definición que trascribes:
      Definición de height css:
      Si se utilizan porcentajes, hace referencia a la altura del elemento en el que se encuentra [1]. Si este elemento contenedor no tiene establecida una altura de forma explícita [2] y el elemento para el que se define la altura no está posicionado de forma absoluta, se ignora la altura en porcentaje y se sustituye por el valor auto [3].


      Tu estructura es la siguiente:
      +Body (con hight declarada en px)
      ---+div_padre (sin altura declarada = auto)
      ------+otro_div_padre (sin altura declarada = auto)
      ---------+Hijo (height: 50%)

      [1] Tu body tiene altura declarada.
      [2] Los dos siguiente (hijo y nieto de body) no la tienen por lo que su valor es auto.
      [3] La altura de tu div .hijo (bisnieto de body) declarada es 50%. Y como la altura de su padre (#otro_div_padre) es auto se ignora el valor 50% y computa también como auto.

      Si tu siguiente pregunta es cómo "saltarse" este aspecto te sugeriría (así a bote pronto y sin pensarlo demasiado) que repienses el marcado html y uses el flexbox dispuestos en columna y que ese elemento ocupe el espacio sobrante o como última uses el valor inherit si no te destroza tu estructura.

      Un saludo

      Eliminar
  3. Hola, creo que este es el lugar más idóneo para preguntar mi problema con la unidad relativa de porcentaje. Pero al no poder poner código html aquí voy a dejar el enlace donde esta esta misma pregunta, haber si puedes ayudarme.

    http://www.comocreartuweb.com/consultas/showthread.php/58594-problema-unidad-relativa-(porcentaje)

    ResponderEliminar
  4. Hola gracias por tu pronta respuesta y por el tema de los caracteres html:

    Volviendo a la pregunta que te formule:

    ¿Por qué el div con id hijo NO establece una altura de 50% referente al padre body?

    Y haciendo un análisis de tu respuesta se podría decir entonces:

    “Si se utilizan porcentajes, hace referencia a la altura del elemento en el que se encuentra (su padre, su padre directo)” ¿cierto? , ya que div_padre (sin altura declarada = auto)
    y otro_div_padre (sin altura declarada = auto) por tu respuesta y el ejemplo que puse veo que es así.

    Y en la propiedad width no tiene que ser su padre directo, ya que si cogemos el ejemplo que puse, se puede ver claramente como establece width 50% a su padre body y aquí también hijo y nieto de body tiene establecido el valor auto.

    ResponderEliminar
  5. Creo que el artículo no responde a la última pregunta (creo). Está bien todo el tema del valor auto que ya mas o menos conocía.

    Yo solo quiero saber esto:

    ¿Por qué el div con id hijo NO establece una altura de 50% referente al padre body?
    Tu respuesta fue está y la entendí perfectamente:

    [1] Tu body tiene altura declarada.
    [2] Los dos siguiente (hijo y nieto de body) no la tienen por lo que su valor es auto.
    [3] La altura de tu div .hijo (bisnieto de body) declarada es 50%. Y como la altura de su padre (#otro_div_padre) es auto se ignora el valor 50% y computa también como auto.

    Normal, si su padre tiene auto no puede establecer la altura en porcentaje su hijo, entonces la ignora y el también pone auto.

    La conclusión que yo he sacado, es que para que ese div#hijo aplique el porcentaje tiene que tener su padre una altura explícitamente declarada, SU PADRE, NO SU ABUELO...PADRE DIRECTO es decir, en este caso div#otro_div_padre. ¿Estoy en lo cierto?

    Y en la propiedad width no tiene que tener establecido ningún valor explícitamente su elemento contenerdor (padre) para que aplique la anchura en porcentajes, ya que si cogemos el ejemplo que puse, se puede ver claramente como div#hijo (bisnieto de body) establece width 50% referente a él (body). Aquí la conclusión que saco es que aquí si establece la anchura en porcentajes por una razón:

    Si a body le pusimos width:900px, su hijo div#padre aplicara en valor auto y será este valor auto el mismo que body 900px, div#otro_div_padre que es hijo de div#padre hará lo mismo y div#hijo al final hará referencia al valor auto que su padre estableció de los demás y que dará como computado 900px tambien.

    [1] body_padre = 900px
    [2]div_padre = auto = computado = 900px
    [3] otro_div_padre = auto computado = 900px

    Conclusión sobre width:

    Al div#hijo no le hace falta que su padre tenga un valor explícitamente establecido( en la w3c no dice que tenga que tener un valor explícitamente) como es el caso de la propiedad heigth que si le hace falta. En este caso el elemento div#hijo con la propiedad width hace referencia al elemento padre (otro_div_padre) sin tener la anchura explícitamente declarada.

    Si puedes ayudarme y aclararme este tema seria de gran ayuda por favor.

    ResponderEliminar
    Respuestas
    1. Creo que en ese artículo que te mencionaba sí está la respuesta a los dos casos que planteas, Isaac.
      Otra cosa es que quizás también estás intentando hallar respuesta no sólo a cómo computa el valor 'auto' en distintas situaciones sino también al porqué de ese valor computado.
      La segunda cuestión es irrelevante (así fue definido y sus razones tendrían los distintos editores de cada módulo).

      Respecto a la primera, valor computado de auto:

      En anchuras en "Elementos no reemplazados en flujo normal a nivel de bloque"
      Este es tu div, un elemento de bloque que no ha sido sacado del flujo del documento. 'Auto' es el valor por defecto de 'width' y se traduce (para entendernos) como "ocupa toda la anchura que esté disponible".
      Y el valor computado de ese "ocupa toda la anchura que tengas disponible" es mesurable y por tanto cualquier otro valor relativo a él en su hijo se calcula y aplica.
      En padre:
      'Width: auto' --> computado = Zpx
      En hijo
      50% de Zpx = calc(Zpx / 2) = Ypx

      En aturas
      Creo que ya lo tienes claro. Pero resumiendo.
      'Height: Auto' significa lo que tu contenido fuerce.
      Cualquier cálculo sobre 'auto' se ignora y sigue significando "la altura que tu contenido fuerce".

      Espero que ahora ya haya sido capaz de explicarme.
      Un saludo.

      Eliminar
  6. Le voy a echar un vistazo al enlace que me pasaste en profundidad…pero ya con la explicación última que me distes lo he entendido bien, y aunque me lo resumiste de una manera más técnica y precisa, se puede decir que es más o menos el resumen que hice en mi último comentario pero bien explicado.
    Gracias por tus aportes, ya comprendo este tema mucho mejor.
    Solo hay que tener presente algunos detalles con la propidad height y width y los valores en porcentajes, ya que hay algunas diferencias cuando se aplica a height o a width que si no las comprendes bien viene después los dolores de cabeza ¿ y qué pasa aquí?
    Un saludo

    ResponderEliminar

EsCss RSS del Blog RSSS Comentarios Humans.txt ᛯ Diseno por Kseso SiteMap