El modelo de caja

Una vez que empiezas a espaciar las cosas con CSS, te encuentras con el mismo puzzle que todos: estableces un ancho, añades algo de relleno, y el elemento termina siendo más ancho de lo que pediste. Dos párrafos se sientan más cerca juntos de lo que los números dicen que deberían. Nada de esto es un error. Es el modelo de caja, el conjunto de reglas que decide cuánto espacio ocupa cada elemento, y una vez que puedas visualizarlo, la mayoría de tus sorpresas de espaciado dejan de serlo.
Cada elemento es una caja
CSS trata cada elemento de la página como un rectángulo, incluso una palabra única o un enlace. Ese rectángulo se construye a partir de cuatro capas apiladas de dentro hacia afuera, y esto es el modelo de caja: el contenido en el medio, luego relleno alrededor de él, luego un borde, luego margen en el exterior.
Imagina una foto enmarcada en una pared. La foto es el contenido. El marco blanco alrededor de la foto es el relleno, espacio de respiración dentro del marco. El marco de madera en sí es el borde. Y la pared vacía entre este marco y el siguiente es el margen. Cada elemento que diseñas se empaqueta de la misma manera, de dentro hacia afuera.
.card {
padding: 16px; /* espacio dentro, alrededor del contenido */
border: 2px solid #333; /* el marco */
margin: 24px; /* espacio fuera, empujando a los vecinos */
}padding, border, y margin
Las tres capas de espaciado cada una hacen un trabajo. Padding es espacio en el interior, entre el contenido y el borde. Margin es espacio en el exterior, empujando otros elementos lejos. El borde es la línea trazada entre ellos.
Puedes establecer un valor para los cuatro lados a la vez, o dirigirse a un solo lado:
.card {
padding: 20px; /* los cuatro lados obtienen 20px */
margin-bottom: 32px; /* solo el borde inferior */
}La abreviatura padding: 20px es una forma rápida de decir arriba, derecha, abajo e izquierda todos juntos. Cuando necesitas un lado diferente del resto, usa la propiedad específica como margin-bottom.
padding cuando el texto se siente apretado dentro de una caja, y margin cuando dos cajas se sientan demasiado cerca. Un valor como padding: 20px cubre los cuatro lados, o nombra un lado como margin-bottom cuando solo uno necesita cambiar. box-sizing: content-box vs border-box
Aquí viene la sorpresa que atrapa a casi todos. Estableces una tarjeta a width: 300px, añades algo de relleno, y la tarjeta termina siendo más ancha que 300 píxeles en la página. No hiciste nada mal. Por defecto, width solo mide el contenido en el medio, y cualquier relleno y borde se añaden encima.
Hay una solución de una línea que hace que el ancho se comporte como esperabas. Establece box-sizing: border-box, y ahora el ancho que escribes es el ancho completo de la caja, relleno y borde incluidos:
.card {
box-sizing: border-box; /* el ancho ahora incluye relleno y borde */
width: 300px;
padding: 20px; /* la tarjeta se mantiene en 300px de ancho, no 340px */
}width que estableces solo mide el contenido en el medio, así que relleno y borde hacen la caja más grande que el número que escribiste. Establecer box-sizing: border-box lo arregla: el ancho se convierte en la caja completa, relleno y borde incluidos. Este me atrapó durante años, así que vale la pena recordarlo temprano. Colapso de margen
Una sorpresa más, y es sobre márgenes apilados. Pon dos párrafos uno encima del otro, da al primero un margen inferior de 24px y al segundo un margen superior de 16px, y podrías esperar 40px de hueco entre ellos. Realmente obtienes 24px.
Esto se llama colapso de margen. Cuando dos márgenes verticales se encuentran, el navegador no los suma. Mantiene el mayor de los dos y descarta el más pequeño. Así que el margen más grande gana, y el hueco es 24px, no 40px. Solo sucede con márgenes superior e inferior, nunca con relleno.
.intro {
margin-bottom: 24px;
}
.details {
margin-top: 16px;
/* el hueco entre ellos es 24px, el margen más grande, no 40px */
}24px abajo encontrándose con 16px arriba da un hueco de 24px, no 40px. Solo sucede con márgenes superior e inferior, y sorprende a todos la primera vez. 
