Pregunta 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?

Por "apropiado" quiero decir que si mi elemento padre es 200px alto y especifico height = 100% con padding = 5px Yo esperaría que debería obtener un 190px elemento alto con border = 5px en todos 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 se me ocurre:

<html style="height: 100%">
    <body style="height: 100%">
        <div style="background-color: black; height: 100%; padding: 25px"></div>
    </body>
</html>

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.


724
2018-01-27 23:28


origen


Respuestas:


Aprendí a hacer este tipo de cosas leyendo "Patrones de diseño PRO HTML y CSS". Los 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 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;
}
<div class="stretchedToMargin">
  Hello, world
</div>

Violín por Nooshu's comentario


694
2018-01-27 23:53



Hay un 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 Dean Edward's IE7.js agrega soporte para eso. Disfruta :)


326
2018-06-14 14:10



¡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}
<div class="box" style="background:black">
  <div class="box" style="background:green">
    <div class="box" style="background:lightblue">
      This will show three nested boxes. Try resizing browser to see they remain nested properly.
    </div>
  </div>
</div>


62
2018-04-09 20:03



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 sintaxis. ¡Disfrútelo!


35
2018-06-15 17:34



De acuerdo con la altura de la especificación w3c se refiere a la altura del área visible, p. en un monitor de resolución de 1280x1024 píxeles con una altura del 100% = 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.

<style>
    .FullHeight { 
       height: auto !important; /* ie 6 will ignore this */
       height: 100%;            /* ie 6 will use this instead of min-height */
       min-height: 100%;        /* ie 6 will ignore this */
    }

    .Padded {
       padding: 5px;
    }
</style>

<div class="FullHeight">
   <div class="Padded">
      Hello i am padded.
   </div
</div>

20
2018-01-27 23:45



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 al contenedor longitud, es decir, es 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.


7
2018-01-27 23:33



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.


5
2017-11-30 14:35



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 aumentará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%).


4
2017-10-29 19:12



1. Altura completa con padding

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  padding: 50px;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>

2. Altura completa con margin

body {
  margin: 0;
}
.container {
  min-height: calc(100vh - 100px);
  margin: 50px;
  background: silver;
}
<div class="container">Hello world.</div>

3. Altura completa con border

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  border: 50px solid pink;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>


4
2018-01-15 20:30



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;
}
<div id="box">
  <p>100% height and width!</p>
</div>
<div id="more-content">
</div>

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


2
2018-02-08 07:37