El modelo de caja, las guías y de dónde sale ese espacio
El diagrama interactivo de caja, los colores del resaltado, y el procedimiento para identificar el origen de un espacio en blanco sin tocar el CSS.
La pregunta que más veces se hace un desarrollador frontend en su vida es de dónde sale ese hueco. Puede ser un margen, un relleno, un gap, un espacio en blanco del HTML entre elementos inline, la altura de línea, el descendente de la fuente, un pseudo-elemento, un borde transparente o el colapso de dos márgenes que se fusionaron. Son nueve causas con nueve arreglos y todas producen exactamente el mismo píxel vacío. El inspector distingue entre ellas con colores, y saber leer esos colores convierte una búsqueda a ciegas en una lectura.
- Leer el diagrama de caja interactivo y editar sus valores directamente.
- Identificar el origen de un espacio a partir del color con que se resalta.
- Reconocer los cuatro espacios que no aparecen en el diagrama de caja.
- Aplicar el procedimiento de eliminación para localizar un hueco en menos de un minuto.
El diagrama y sus colores
Al final del panel de estilos hay un diagrama de cajas concéntricas. De fuera adentro: margen, borde, relleno y contenido, cada uno con su color propio, y con los valores numéricos reales en cada lado.
Tres cosas que hacer con él.
Leer. Los números son los valores usados, en píxeles, después de resolver porcentajes y unidades relativas. Un padding: 2em aparece como el número de píxeles que resultó.
Editar. Doble clic sobre cualquier número lo convierte en editable, y las flechas funcionan igual que en el panel de estilos. Es la vía más rápida para ajustar espaciado, porque no hay que localizar en qué regla estaba declarado.
Resaltar. Pasar el cursor sobre cada zona del diagrama la resalta en la página con su color. Esa correspondencia entre color del diagrama y color del resaltado es lo que hace del inspector un instrumento de diagnóstico: no te dice solo cuánto mide, te enseña dónde está.
Los mismos colores aparecen cuando pasas el cursor sobre un nodo del árbol, así que el resaltado completo de un elemento es ya una respuesta parcial. Si el hueco que te molesta se colorea con el tono del margen, es un margen. Si no se colorea con ningún tono, ninguna de las cuatro zonas de este elemento lo produce y hay que buscar en otro sitio.
El diagrama muestra - en lugar de un cero cuando la propiedad no aplica. Un elemento con position: static muestra guiones en la sección de posición, y eso es en sí mismo un diagnóstico: la propiedad top que declaraste no está haciendo nada.
Los cuatro espacios que no salen en el diagrama
Aquí está el valor real de esta lección, porque cuando el hueco no está en el diagrama es cuando la gente se atasca.
El gap. Los espacios de gap en flex y grid no pertenecen a ninguna caja: pertenecen al contenedor y se dibujan entre sus hijos. No aparecen en el diagrama de ningún hijo. Se ven con el overlay de flex o de grid, con su rayado característico. Si el hueco solo aparece cuando activas el overlay del padre, es gap.
El espacio en blanco entre elementos inline. Cuando dos elementos inline o inline-block están separados por un salto de línea en el HTML, el parser conserva un espacio, y ese espacio se pinta con el tamaño de un carácter de la fuente del padre. No es margen, no es padding, y no está en ningún sitio del CSS. Se reconoce porque el hueco cambia de tamaño si cambias el font-size del contenedor, cosa que ningún margen hace. El arreglo clásico es cambiar el contexto de formato del padre a flex o grid, con lo que el espacio en blanco deja de generar cajas.
La altura de línea y las métricas de la fuente. Una caja que contiene texto tiene una altura mínima gobernada por line-height, y el texto se coloca dentro de esa caja centrado respecto a las métricas de la fuente, no respecto a los píxeles visibles del glifo. Eso produce un espacio arriba y abajo que no es padding y que varía con la fuente. Se reconoce porque desaparece si pones line-height: 0 en el contenedor, y porque cambia al cambiar de familia tipográfica sin tocar nada más. La propiedad line-height con un número sin unidad, y no con una longitud, es la que hace que este espacio se comporte de forma predecible al heredarse.
El colapso de márgenes. Dos márgenes verticales adyacentes se fusionan en uno del tamaño del mayor, en lugar de sumarse. Y un margen superior de un hijo puede salirse de su padre y colapsar con el margen del padre, produciendo el desconcertante fenómeno de un elemento que empuja a su propio contenedor. El diagrama muestra el margen declarado, no el colapsado, así que los números no cuadran con lo que ves. Se reconoce porque el hueco no cambia al modificar uno de los dos márgenes, solo al modificar el mayor. Y no ocurre en contenedores flex ni grid, que es una razón más para preferirlos.
El procedimiento de eliminación
Un hueco desconocido se localiza en menos de un minuto con esta secuencia, que va de lo más barato a lo más caro.
Pasa el cursor por el elemento anterior al hueco y mira si el resaltado lo cubre. Si el hueco se colorea con el tono del margen, es margen del anterior.
Haz lo mismo con el elemento posterior. Si se colorea, es margen del posterior.
Pasa el cursor por el contenedor. Si el hueco se colorea con el tono del relleno, es padding del padre.
Activa el overlay de flex o grid del contenedor. Si el hueco aparece rayado, es gap.
Si ninguna de las cuatro, es uno de los espacios invisibles: pon line-height: 0 en el contenedor y mira si cambia; si cambia, es tipografía. Si no cambia y los elementos son inline, es el espacio en blanco del HTML. Si tampoco, comprueba pseudo-elementos con contenido en el árbol.
Y hay un atajo bruto que resuelve el caso difícil en cinco segundos.
// Dibuja el contorno de cada elemento con un color por profundidad
document.querySelectorAll('*').forEach((el, i) => {
el.style.outline = `1px solid hsl(${(i * 37) % 360} 90% 50%)`;
});
Con todos los contornos visibles, un hueco que queda fuera de cualquier contorno es espacio generado por el flujo —blanco entre inline, o interlineado— y un hueco que queda dentro de un contorno es relleno de ese elemento. Para deshacerlo, recarga.
Hay un caso concreto de esta familia que aparece en prácticamente todos los proyectos y que ha generado más búsquedas desesperadas que cualquier otro: el espacio en blanco de unos pocos píxeles debajo de una imagen, o debajo de un vídeo, o debajo de un iframe. Buscas márgenes y no hay. Buscas rellenos y no hay. El diagrama de caja de la imagen está limpio. Y el hueco sigue ahí. La causa es que una imagen es un elemento en línea por defecto, y los elementos en línea se colocan sobre la línea base del texto, no sobre el borde inferior de la caja. El espacio que ves es el hueco reservado para los descendentes de la fuente: el trozo por debajo de la línea base donde caen las colas de la p y la g. No pertenece a la imagen ni al contenedor: pertenece a la caja de línea que los contiene, y por eso no aparece en el diagrama de nadie. Hay tres arreglos y los tres funcionan por razones distintas: display: block en la imagen la saca del flujo en línea; vertical-align: bottom la alinea con el borde inferior de la caja de línea en vez de con la base; y line-height: 0 en el contenedor reduce a cero la caja de línea entera. El tercero es el que más gente aplica y el que peor envejece, porque afecta a cualquier texto que caiga dentro. La lección que generaliza este caso es la que importa: el flujo en línea es un sistema de composición tipográfica, no un sistema de cajas, y buena parte de los espacios inexplicables de CSS son consecuencias de que estás componiendo texto sin darte cuenta. Cuando un espacio no está en el diagrama de caja de nadie, la primera hipótesis debería ser siempre esa.