CSS 100% de altura con relleno / margen

Esto me ha estado volviendo loco durante un par de días, pero en realidad es un problema con el que me he equivocado durante los últimos años: con HTML / CSS, ¿cómo puedo hacer un elemento que tenga un ancho y / o altura que es el 100% de su elemento principal y aún tiene el relleno o los márgenes adecuados?

Con “apropiado” me refiero a que si mi elemento padre es 200px alto y especifico height = 100% con padding = 5px esperaría que obtuviera un elemento alto de 190px con border = 5px en todos los lados, bien centrado en el elemento padre .

Ahora, sé que no es así como el modelo de caja estándar especifica que debería funcionar (aunque me gustaría saber por qué, exactamente …), por lo que la respuesta obvia no funciona:

 #myDiv { width: 100% height: 100%; padding: 5px; } 

Pero me parece que debe haber ALGUNA forma de producir de manera confiable este efecto para un padre de tamaño arbitrario. ¿Alguien sabe de una manera de lograr esta tarea (aparentemente simple)?

Ah, y para que conste en acta, no estoy muy interesado en la compatibilidad con IE, así que (afortunadamente) debería facilitar un poco las cosas.

EDITAR: desde que se pidió un ejemplo, este es el más simple que puedo pensar:

   

El desafío es lograr que aparezca la caja negra con un relleno de 25 píxeles en todos los bordes sin que la página crezca lo suficiente como para requerir barras de desplazamiento.

Aprendí a hacer este tipo de cosas leyendo ” PRO HTML y CSS Design Patterns “. La display:block es el valor de visualización predeterminado para el div , pero me gusta hacerlo explícito. El contenedor tiene que ser del tipo correcto; position atributo de position es fixed , relative o absolute .

 .stretchedToMargin { display: block; position:absolute; height:auto; bottom:0; top:0; left:0; right:0; margin-top:20px; margin-bottom:20px; margin-right:80px; margin-left:80px; background-color: green; } 
 
Hello, world

Hay una nueva propiedad en CSS3 que puede usar para cambiar la forma en que el modelo de caja calcula el ancho / alto, se llama tamaño de caja.

Al establecer esta propiedad con el valor “border-box”, hace que el elemento al que lo aplique no se estire cuando agrega un relleno o borde. Si define algo con un ancho de 100 píxeles y un relleno de 10 píxeles, seguirá teniendo 100 píxeles de ancho.

 box-sizing: border-box; 

Vea aquí para soporte de navegador . No funciona para IE7 y versiones anteriores , sin embargo, creo que IE7.js de Dean Edward agrega soporte para ello. Disfruta 🙂

¡La solución es NO usar altura y ancho en absoluto! Adjunte la caja interna usando arriba, izquierda, derecha, abajo y luego agregue margen.

 .box {margin:8px; position:absolute; top:0; left:0; right:0; bottom:0} 
 
This will show three nested boxes. Try resizing browser to see they remain nested properly.

La mejor manera es con la propiedad calc (). Entonces su caso se vería así:

 #myDiv { width: calc(100% - 5px); height: calc(100% - 5px); padding: 5px; } 

Simple, limpio, sin soluciones. Solo asegúrese de no olvidar el espacio entre los valores y el operador (por ejemplo, (100% -5px) que romperá la syntax. ¡Disfrútelo!

Según la especificación w3c, la altura se refiere a la altura del área visible, por ejemplo, en un monitor de resolución de 1280×1024 píxeles, 100% de altura = 1024 píxeles.

min-height se refiere a la altura total de la página, incluido el contenido, de modo que en una página donde el contenido sea más grande que 1024px min-height: 100% se ampliará para incluir todo el contenido.

El otro problema es que el relleno y el borde se agregan al alto y ancho en la mayoría de los navegadores modernos, excepto ie6 (ie6 es en realidad bastante lógico pero no se ajusta a la especificación). Esto se llama el modelo de caja. Entonces si especifica

 min-height: 100%; padding: 5px; 

Realmente le dará 100% + 5px + 5px para la altura. Para evitar esto, necesitas un contenedor contenedor.

  
Hello i am padded.

Esta es una de las idioteces absolutas de CSS: aún no he comprendido el razonamiento (si alguien sabe, por favor explique).

El 100% significa el 100% de la altura del contenedor, a la que se agregan los márgenes, bordes y relleno. Por lo tanto, es efectivamente imposible obtener un contenedor que llene a sus padres y que tenga un margen, borde o relleno.

Tenga en cuenta también que establecer la altura es notoriamente incoherente entre los navegadores, también.


Otra cosa que he aprendido desde que publiqué esto es que el porcentaje es relativo a la longitud del contenedor, es decir, su ancho, lo que hace que un porcentaje sea aún más inútil para la altura.

Hoy en día, las unidades de visualización vh y vw son más útiles, pero aún no son especialmente útiles para nada más que los contenedores de nivel superior.

Otra solución es usar display: table que tiene un comportamiento de modelo de caja diferente.

Puede establecer un alto y un ancho para el elemento primario y agregar relleno sin expandirlo. El niño tiene 100% de alto y ancho menos los almohadones.

JSBIN

Otra opción sería usar propiedad de tamaño de caja. El único problema con ambos sería que no funcionan en IE7.

1. Altura completa con padding

 body { margin: 0; } .container { min-height: 100vh; padding: 50px; box-sizing: border-box; background: silver; } 
 
Hello world.

Otra solución: puede usar unidades porcentuales para los márgenes y tamaños. Por ejemplo:

 .fullWidthPlusMargin { width: 98%; margin: 1%; } 

El problema principal aquí es que los márgenes boostán / disminuirán ligeramente con el tamaño del elemento padre. Es de suponer que la funcionalidad que prefiera es que los márgenes se mantengan constantes y que el elemento hijo crezca o se reduzca para completar los cambios en el espaciado. Entonces, dependiendo de cuán apretada necesite su pantalla, podría ser problemático. (También iría por un margen más pequeño, como 0.3%).

El ejemplo de Frank me confundió un poco; no funcionó en mi caso porque todavía no entendía el posicionamiento lo suficientemente bien. Es importante tener en cuenta que el elemento del contenedor principal debe tener una posición no estática (mencionó esto, pero lo pasé por alto, y no fue en su ejemplo).

Aquí hay un ejemplo en el que el relleno y el borde de un niño usan posicionamiento absoluto para llenar al padre al 100%. El padre usa el posicionamiento relativo para proporcionar un punto de referencia para la posición del niño mientras permanece en el flujo normal; el siguiente elemento “más contenido” no se ve afectado:

 #box { position: relative; height: 300px; width: 600px; } #box p { position: absolute; border-style: dashed; padding: 1em; top: 0; right: 0; bottom: 0; left: 0; } 
 

100% height and width!

Un enlace útil para aprender rápidamente el posicionamiento de CSS

Ahora es 2018, la nueva mierda debería mencionarse aquí mientras la pregunta sigue apareciendo en Google.

Una solución con flexbox (trabajando en IE11): ( o ver en jsfiddle )

    

(El restablecimiento de CSS no es necesariamente importante para el problema real).

La parte más importante es flex: 1 (En combinación con display: flex at the parent). Curiosamente, la explicación más plausible que conozco sobre cómo funciona la propiedad Flex proviene de una documentación nativa de la reacción, por lo que me refiero a ella de todos modos .

Borde alrededor de div, en lugar de margen de página de cuerpo

Otra solución: solo quería un borde simple alrededor del borde de mi página, y quería 100% de altura cuando el contenido era más pequeño que eso.

Border-box no funcionó, y el posicionamiento fijo parecía incorrecto para una necesidad tan simple.

Terminé agregando un borde a mi contenedor, en lugar de confiar en el margen del cuerpo de la página, se ve así:

 body, html { height: 100%; margin: 0; } .container { width: 100%; min-height: 100%; border: 8px solid #564333; }