El Modelo de Caja en CSS
En el diseño web, cada elemento que mostramos en una página se considera una "caja". Comprender cómo funciona este modelo de caja es fundamental para controlar la disposición y el espaciado de los elementos en CSS. Esta caja se compone de cuatro partes: el contenido (content), el relleno (padding), el borde (border) y el margen (margin).
Tipos de Modelos de Caja: content-box y border-box
Existen dos interpretaciones principales de cómo se calcula el tamaño total de una caja, controladas por la propiedad box-sizing:
- Modelo Estándar (
content-box): Es el comportamiento por defecto de CSS. En este modelo, las propiedadeswidthyheightse refieren únicamente al área del contenido del elemento. Elpaddingy elborderse añaden a estas dimensiones, aumentando el tamaño total de la caja.
.caja-estandar {
width: 250px;
height: 150px;
padding: 20px; /* Se añadirán 20px de relleno a cada lado */
border: 5px solid #0056b3; /* Se añadirán 5px de borde a cada lado */
margin: 10px auto;
box-sizing: content-box; /* Comportamiento por defecto */
background-color: #e0f2f7;
}
/* Dimensiones finales de la caja:
Ancho total = 250px (contenido) + 2*20px (padding) + 2*5px (border) = 300px
Alto total = 150px (contenido) + 2*20px (padding) + 2*5px (border) = 200px
*/
- Modelo de Borde (
border-box): En este modelo, las propiedadeswidthyheightincluyen elpaddingy elborder. El contenido se encoge para hacer espacio para el relleno y el borde, asegurando que el tamaño total de la caja permanezca constante según lo especificado.
.caja-moderna {
width: 250px;
height: 150px;
padding: 20px; /* Incluido en el width/height total */
border: 5px solid #0056b3; /* Incluido en el width/height total */
margin: 10px auto;
box-sizing: border-box; /* El padding y border no aumentan el tamaño total */
background-color: #e0f2f7;
}
/* Dimensiones finales de la caja:
Ancho total = 250px
Alto total = 150px
El contenido se ajustará para acomodar padding y border dentro de estas dimensiones.
*/
Uso de Porcentajes en Propiedades de Caja
Las propiedades de dimensionamiento y espaciado pueden usar valores porcentuales, pero su comportamiento varía:
widthyheight: Los porcentajes se calculan con respecto a las dimensiones del elemento contenedor (padre), siempre y cuando este tenga una dimensión explícitamente definida (noauto).paddingymargin: Los porcentajes para estas propiedades (tanto verticales como horizontales) siempre se calculan con respecto al ancho del elemento contenedor (padre).border-width: Esta propiedad no admite valores porcentuales.
Ejemplo de Porcentajes
<div class="contenedor-principal">
<div class="elemento-interior">
<div class="sub-elemento"></div>
</div>
</div>
.contenedor-principal {
width: 600px;
height: 700px;
padding: 15px;
margin: 80px auto;
background-color: #ccc;
box-sizing: border-box; /* Para simplificar cálculos */
}
.elemento-interior {
width: 75%; /* 75% de 600px = 450px */
height: 75%; /* 75% de 700px = 525px */
padding: 10% 4% 6% 8%; /* Todos los porcentajes son del width del padre (600px)
padding-top: 60px, padding-right: 24px, padding-bottom: 36px, padding-left: 48px */
margin: 10% 4% 6% 8%; /* Todos los porcentajes son del width del padre (600px)
margin-top: 60px, margin-right: 24px, margin-bottom: 36px, margin-left: 48px */
border: 3px solid #333;
background-color: #f0f0f0;
box-sizing: border-box;
}
.sub-elemento {
width: 80%; /* 80% del width del padre (450px) = 360px */
height: 80%; /* 80% del height del padre (525px) = 420px */
padding: 12% 6% 9% 7%; /* Todos los porcentajes son del width del padre (450px)
padding-top: 54px, padding-right: 27px, padding-bottom: 40.5px, padding-left: 31.5px */
margin: 12% 6% 9% 7%; /* Todos los porcentajes son del width del padre (450px)
margin-top: 54px, margin-right: 27px, margin-bottom: 40.5px, margin-left: 31.5px */
border: 2px solid #666;
background-color: #a0a0a0;
box-sizing: border-box;
}
Porcentajes y Posicionamiento
Cuando un elemento tiene una propiedad position de absolute o fixed, los porcentajes de width, height, padding y margin se calculan de manera diferente:
- Si
position: absolute;: Los porcentajes se calculan respecto al primer ancestro posicionado (que no tengaposition: static;). Si no hay ninguno, se basan en el elemento<html>. - Si
position: fixed;: Los porcentajes se calculan siempre respecto al viewport (la ventana del navegador).
<div class="marco-principal">
<div class="panel-relativo">
<div class="capa-absoluta"></div>
</div>
</div>
html, body {
margin: 0;
padding: 0;
height: 100%; /* Necesario para que el html tenga una altura definida */
}
.marco-principal {
width: 800px;
height: 900px;
margin: 50px auto;
background-color: #ddd;
}
.panel-relativo {
position: relative; /* Convierte este en el contenedor para elementos absolutos */
width: 70%; /* 70% de 800px = 560px */
height: 70%; /* 70% de 900px = 630px */
padding: 5%; /* 5% del ancho del padre (800px) = 40px */
background-color: #eee;
box-sizing: border-box;
}
.capa-absoluta {
position: absolute;
top: 10%; /* 10% de la altura del panel-relativo (630px) = 63px */
left: 10%; /* 10% del ancho del panel-relativo (560px) = 56px */
width: 50%; /* 50% del ancho del panel-relativo (560px) = 280px */
height: 50%; /* 50% de la altura del panel-relativo (630px) = 315px */
background-color: #a0a0a0;
border: 2px solid #555;
box-sizing: border-box;
}
La Cadena de Dependencia de Altura con Porcentajes
Para que un elemento hijo con height: N% tome una altura significativa, todos sus ancestros directos hasta <html> y <body> deben tener una height explícitamente definida (no auto). Si cualquier elemento en la cadena tiene height: auto (que es el valor por defecto y significa que la altura se ajusta al contenido), los elementos hijos que usan porcentajes para su altura no tendrán un punto de referencia para calcular su altura y, en la práctica, se renderizarán con una altura de 0.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Altura por Porcentajes</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%; /* Permite que el viewport sea el referente */
}
.contenedor-alto {
background: #ccc;
/* height: 50%; Si se comenta esta línea, .caja-hija no tendrá altura */
}
.caja-hija {
background: #007bff;
height: 50%; /* Intentará tomar 50% de .contenedor-alto */
color: white;
text-align: center;
line-height: 100px; /* Solo para visualización si tiene altura */
}
</style>
</head>
<body>
<div class="contenedor-alto">
<div class="caja-hija">Contenido de la Caja Hija</div>
</div>
</body>
</html>
En el ejemplo anterior, si la propiedad height: 50%; de .contenedor-alto se comenta, .caja-hija no tendrá una altura calculable, ya que su padre .contenedor-alto tendría height: auto por defecto.
Comportamiento de width: auto
A diferencia de la altura, el ancho no tiene una cadena de dependencia tan estricta. Para los elementos de bloque (display: block), si width es auto (valor por defecto), el elemento automáticamente ocupará todo el ancho disponible de su contenedor. Por lo tanto, un hijo con width: N% siempre podrá calcular su ancho en relación con el ancho de su padre, incluso si el padre tiene width: auto.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ancho por Porcentajes</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.contenedor-ancho-auto {
/* width: auto; es el valor por defecto y ocupará todo el espacio */
background-color: lightcoral;
padding: 30px;
}
.contenido-interno {
width: 70%; /* Calculará 70% del ancho disponible de .contenedor-ancho-auto */
height: 80px;
background-color: lightblue;
margin: 10px;
text-align: center;
line-height: 80px;
color: white;
}
</style>
</head>
<body>
<div class="contenedor-ancho-auto">
<div class="contenido-interno">Elemento con Ancho Porcentual</div>
</div>
</body>
</html>
En este caso, .contenedor-ancho-auto, al ser un div (elemento de bloque), tomará automáticamente el 100% del ancho del body (menos los márgenes si los tuviera). Entonces, .contenido-interno calculará su 70% basándose en ese ancho disponible.
Elementos de Bloque y en Línea
Los elementos HTML se clasifican fundamentalmente en dos categorías de visualización, lo cual impacta directamente en cómo se comportan dentro del modelo de caja:
- Elementos de Bloque (
display: block):- Siempre ocupan todo el ancho disponible y comienzan en una nueva línea.
- Permiten establecer
width,height,paddingymarginen todas las direcciones (arriba, abajo, izquierda, derecha). - Ejemplos por defecto:
<p>,<h1>-<h6>,<div>,<ul>,<li>.
- Elementos en Línea (
display: inline):- Solo ocupan el ancho necesario para su contenido y no fuerzan un salto de línea.
- No permiten establecer
widthniheight(su tamaño se ajusta al contenido). - Solo se puede aplicar
paddingymarginen las direcciones horizontal (izquierda, derecha); los valores verticales (arriba, abajo) no afectan la posición de otros elementos en la línea. - Ejemplos por defecto:
<a>,<span>,<em>,<strong>.
- Elementos de Bloque en Línea (
display: inline-block):- Combina características de ambos: se colocan uno al lado del otro como elementos en línea, pero permiten establecer
widthyheight, así comopaddingymarginen todas las direcciones, como los elementos de bloque.
- Combina características de ambos: se colocan uno al lado del otro como elementos en línea, pero permiten establecer
Es importante notar que cuando un elemento tiene position: absolute; o position: fixed;, su comportamiento de visualización se asemeja al de display: inline-block. Es decir, pueden tener width y height definidos, y si no se especifican, su tamaño se ajusta a su contenido.