ejemplos - CSS 100% alto con relleno/margen
css html (13)
Borde alrededor de div, en lugar del margen del cuerpo de la página
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;
}
Esto me ha estado volviendo loca por un par de días, pero en realidad es un problema que he tenido en los últimos años: con HTML / CSS, ¿cómo puedo crear un elemento que tenga un ancho y ¿La altura que es el 100% de su elemento padre y aún tiene el relleno o los márgenes adecuados?
Por "correcto" quiero decir que si mi elemento principal tiene 200px
altura y especifico height = 100%
con padding = 5px
esperaría que obtuviera un elemento de 190px
alto con border = 5px
en todos los lados, bien centrado en el elemento principal .
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 este efecto de manera confiable para un padre de tamaño arbitrario. ¿Alguien sabe de una manera de lograr esta tarea (aparentemente simple)?
Ah, y para el registro no estoy terriblemente interesado en la compatibilidad con IE, así que (con suerte) debería hacer las cosas un poco más fáciles.
EDITAR: Dado que se solicitó 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 la caja negra aparezca 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.
¡La solución es NO usar altura y anchura en absoluto! Adjunte la caja interna usando la parte superior, izquierda, derecha, inferior 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>
Aprendí cómo hacer este tipo de cosas leyendo " PRO HTML y CSS Design Patterns ". La display:block
es el valor de pantalla predeterminado para el div
, pero me gusta hacerlo explícito. El contenedor debe 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;
}
<div class="stretchedToMargin">
Hello, world
</div>
El ejemplo de Frank me confundió un poco, no funcionó en mi caso porque todavía no entendía lo suficientemente bien cómo posicionarme. Es importante tener en cuenta que el elemento contenedor primario debe tener una posición no estática (mencionó esto pero lo pasé por alto y no estaba en su ejemplo).
Aquí hay un ejemplo en el que el niño, el relleno y un borde, usa la posición absoluta para llenar el 100% principal. El padre utiliza la posición relativa 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 link útil para aprender rápidamente el posicionamiento CSS
Este es uno de los idiotas absolutos de CSS: todavía tengo que entender el razonamiento (si alguien sabe, por favor, explique).
100% significa 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 su padre y que tenga un margen, borde o relleno.
También tenga en cuenta que la configuración de la altura es notoriamente inconsistente 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 viewport vh y vw son más útiles, pero aún no son especialmente útiles para nada más que los contenedores de nivel superior.
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 "cuadro de borde" hace que cualquier elemento que aplique no se estire cuando agregue un relleno o borde. Si define algo con un ancho de 100 px y un relleno de 10 px, seguirá teniendo un ancho de 100 px.
box-sizing: border-box;
Vea aquí para soporte de navegador . No funciona para IE7 e inferior, sin embargo, creo que el IE7.js Dean Edward agrega soporte para él. Disfrutar :)
La mejor manera es con la propiedad calc (). Entonces tu caso se vería como:
#myDiv {
width: calc(100% - 5px);
height: calc(100% - 5px);
padding: 5px;
}
Sencillo, 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. ¡Disfrute!
Otra solución es usar display: table que tiene un comportamiento de modelo de caja diferente.
Puede establecer una altura y un ancho para el padre y agregar relleno sin expandirlo. El niño tiene un 100% de altura y anchura menos los rellenos.
Otra opción sería usar la propiedad de tamaño de caja. El único problema con ambos sería que no funcionen en IE7.
Otra solución: puede usar unidades porcentuales para márgenes y tamaños. Por ejemplo:
.fullWidthPlusMargin {
width: 98%;
margin: 1%;
}
El principal problema aquí es que los márgenes aumentarán / disminuirán ligeramente con el tamaño del elemento principal. Es de suponer que la funcionalidad que prefiere es que los márgenes se mantengan constantes y que el elemento secundario aumente / disminuya para rellenar los cambios en el espacio. Entonces, dependiendo de qué tan apretado necesites que sea tu pantalla, eso podría ser problemático. (También apostaría por un margen menor, como 0.3%).
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 1280x1024 píxeles, 100% de altura = 1024 píxeles.
min-height se refiere a la altura total de la página, incluido el contenido, por lo que en una página donde el contenido es mayor que 1024px min-height: el 100% se extenderá para incluir todo el contenido.
El otro problema entonces es que el relleno y el borde se agregan a la altura y el 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. Así que si especificas
min-height: 100%;
padding: 5px;
En realidad, le dará 100% + 5px + 5px para la altura. Para sortear 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>
Ya es 2018, la nueva mierda caliente debería mencionarse aquí, ya que la pregunta sigue apareciendo en Google.
Una solución con flexbox (trabajando en IE11): ( o ver en jsfiddle )
<html>
<style>
html, body {
height: 100%; /* fix for IE11, not needed for chrome/ff */
margin: 0; /* CSS-reset for chrome */
}
</style>
<body style="display: flex;">
<div style="background-color: black; flex: 1; margin: 25px;"></div>
</body>
</html>
(El CSS-reset no es necesariamente importante para el problema real).
La parte importante es flex: 1
(en combinación con display: flex
en el padre). Curiosamente, la explicación más plausible que conozco sobre cómo funciona la propiedad Flex proviene de una documentación nativa de reacción, así que me refiero a ella de todos modos .
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>
<style type="text/css">
.stretchedToMargin {
position:absolute;
width:100%;
height:100%;
}
</style>