El Modelo de Caja: El secreto mejor guardado

“Todo elemento es una caja. Domina la caja, dominarás el layout.” - Zen del CSS

🎯 Objetivo Ninja

Entenderás el box model al 100%: content, padding, border, margin. Usarás box-sizing como un profesional.

🏯 Teoría: El Por Qué

Cada elemento HTML es una caja rectangular con 4 capas:

┌─────────────────── MARGIN ───────────────────┐
│                                               │
│  ┌────────────── BORDER ──────────────┐      │
│  │                                     │      │
│  │  ┌────────── PADDING ──────────┐   │      │
│  │  │                              │   │      │
│  │  │  ┌────── CONTENT ──────┐    │   │      │
│  │  │  │                      │    │   │      │
│  │  │  │   width: 200px       │    │   │      │
│  │  │  │   height: 100px      │    │   │      │
│  │  │  │                      │    │   │      │
│  │  │  └──────────────────────┘    │   │      │
│  │  │                              │   │      │
│  │  └──────────────────────────────┘   │      │
│  │                                     │      │
│  └─────────────────────────────────────┘      │
│                                               │
└───────────────────────────────────────────────┘

Las capas:

  1. Content: El contenido real (texto, imagen)
  2. Padding: Espacio INTERNO (entre content y border)
  3. Border: El borde visible
  4. Margin: Espacio EXTERNO (entre cajas)

⚔️ Implementación

Box Model Clásico (Problemático)

.caja {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 5px solid black;
  margin: 10px;
}

/* Ancho REAL = 200 + 40 (padding) + 10 (border) = 250px */
/* Alto REAL = 100 + 40 (padding) + 10 (border) = 150px */

Problema: Si dices width: 200px, esperarías 200px total, pero es 250px. ¡Pesadilla!

Box Model Moderno (Solución)

* {
  box-sizing: border-box; /* SIEMPRE usa esto */
}

.caja {
  width: 200px;       /* Ahora SÍ es 200px total */
  padding: 20px;
  border: 5px solid;
}

/* Ancho REAL = 200px (incluye padding y border) */
/* Content se ajusta: 200 - 40 - 10 = 150px */

Padding: Espacio Interno

/* Todos los lados */
.ninja {
  padding: 20px;
}

/* Vertical | Horizontal */
.ninja {
  padding: 10px 20px;
}

/* Top | Horizontal | Bottom */
.ninja {
  padding: 10px 20px 30px;
}

/* Top | Right | Bottom | Left (sentido horario) */
.ninja {
  padding: 10px 20px 30px 40px;
}

/* Individual */
.ninja {
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 30px;
  padding-left: 40px;
}

Margin: Espacio Externo

/* Misma sintaxis que padding */
.caja {
  margin: 20px;          /* Todos los lados */
  margin: 10px 20px;     /* Vertical | Horizontal */
}

/* Centrar horizontalmente */
.centrado {
  width: 300px;
  margin: 0 auto; /* Top/Bottom: 0, Left/Right: auto */
}

/* Margin negativo (overlay) */
.superpuesto {
  margin-top: -20px; /* Sube 20px */
}

Margin Collapse (Comportamiento Ninja)

.hermano1 {
  margin-bottom: 30px;
}

.hermano2 {
  margin-top: 20px;
}

/* 
  Espacio entre ellos = 30px (el MAYOR, no la suma)
  Esto es "margin collapse"
*/

Solución si quieres sumarlos:

.hermano1 {
  margin-bottom: 30px;
  padding-bottom: 1px; /* Rompe el collapse */
}

Border: El Borde

/* Shorthand */
.caja {
  border: 2px solid #333;
  /*      ↑    ↑     ↑
       width style color */
}

/* Estilos de border */
.variado {
  border-style: solid;  /* Línea continua */
  border-style: dashed; /* Línea discontinua */
  border-style: dotted; /* Puntos */
  border-style: double; /* Doble línea */
}

/* Bordes individuales */
.custom {
  border-top: 3px solid red;
  border-right: 2px dashed blue;
  border-bottom: 1px dotted green;
  border-left: 4px solid black;
}

/* Border radius (esquinas redondeadas) */
.redondeado {
  border-radius: 10px;
}

.circulo {
  width: 100px;
  height: 100px;
  border-radius: 50%; /* Círculo perfecto */
}

Width y Height

.contenedor {
  width: 300px;       /* Ancho fijo */
  height: 200px;      /* Alto fijo */
  
  max-width: 600px;   /* Máximo ancho */
  min-width: 200px;   /* Mínimo ancho */
  
  max-height: 400px;  /* Máximo alto */
  min-height: 100px;  /* Mínimo alto */
}

/* Responsive (usa porcentajes) */
.responsive {
  width: 100%;        /* Ocupa todo el ancho disponible */
  max-width: 1200px;  /* Pero no más de 1200px */
  margin: 0 auto;     /* Centrado */
}

🎯 Reto Ninja

MISIÓN DE BOX MODEL

📦 El Maestro de las Cajas

1

Crea un contenedor con la clase .ninja-card y añade un título y un par de párrafos dentro.

2

Aplica box-sizing: border-box de forma global usando el selector universal *.

3

Dale a la card un ancho fijo de 300px y céntrala horizontalmente usando margin: 20px auto.

4

Añade un padding de 20px para separar el texto de los bordes y un border sólido de 3px con color naranja (#ff6600).

5

Añade un border-radius de 12px para suavizar las esquinas y un fondo blanco.

6

Verifica en las DevTools que el ancho total de la caja sigue siendo exactamente 300px.

🔓 Pergamino Oculto (Bonus)

Técnica 1: Outline (Debugging sin afectar layout)

/* PROBLEMA con border: afecta el tamaño */
.caja {
  border: 2px solid red; /* Añade 4px al tamaño total */
}

/* SOLUCIÓN: outline NO afecta layout */
.debug {
  outline: 2px solid red; /* Para debugging */
  outline-offset: -2px;   /* Dentro del elemento */
}

Técnica 2: Calc() para Medidas Dinámicas

.contenedor {
  width: calc(100% - 40px); /* Ancho total menos 40px */
  padding: 20px;
}

.columnas {
  width: calc(50% - 10px); /* Mitad menos espacio */
}

Técnica 3: Aspect Ratio

/* Mantener proporción 16:9 */
.video {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* Cuadrado */
.cuadrado {
  width: 200px;
  aspect-ratio: 1;
}

Técnica 4: Overflow

/* Si el contenido es muy grande */
.caja {
  width: 200px;
  height: 100px;
  overflow: auto;    /* Scroll si es necesario */
  overflow: hidden;  /* Oculta lo que no cabe */
  overflow: scroll;  /* Siempre muestra scrollbars */
}

✅ Checklist de Dominio

MAESTRÍA ALCANZADA

Pergamino del Maestro de Cajas


💡 Snippets relacionados:

Próximo Pergamino: Colores y Tipografías - La paleta del artista.

¡El box model es TU ALIADO, no tu enemigo, ninja! 📦