Entendiendo el Modelo de Caja de CSS para el Diseño Web

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 propiedades width y height se refieren únicamente al área del contenido del elemento. El padding y el border se 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 propiedades width y height incluyen el padding y el border. 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:

  • width y height: Los porcentajes se calculan con respecto a las dimensiones del elemento contenedor (padre), siempre y cuando este tenga una dimensión explícitamente definida (no auto).
  • padding y margin: 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 tenga position: 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, padding y margin en 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 width ni height (su tamaño se ajusta al contenido).
    • Solo se puede aplicar padding y margin en 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 width y height, así como padding y margin en todas las direcciones, como los elementos de bloque.

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.

Etiquetas: css ModeloDeCaja BoxSizing MaquetacionCSS DisplayCSS

Publicado el 6-2 06:32