Bueno, en realidad no es solo cosa de las imágenes. Suele ocurrir en elementos en línea que están dentro de un elemento de bloque sin altura definida.
Si llevas un tiempo trabajando en el frontend, seguro que alguna vez te ha pasado algo así: tienes una serie de imágenes, cada una dentro de un enlace, y para ordenar esos enlaces decides darles un display:block;
o inline-block
, para poder manejarlos a gusto. Pero, oh sorpresa, de repente te aparece un hueco debajo de las imágenes que no sabes de dónde ha salido (la que tiene el borde naranja es un enlace en estado :hover).
Como ya dije antes, te puede pasar con cualquier elemento, también influye un poco como suelas trabajar definiendo el marcado de la web. En mi caso, la mayoría de veces que me he encontrado en esta situación es trabajando con imágenes que van dentro de enlaces con display:block.
El caso es que ves el hueco y piensas "ya se me ha colado un padding". Entonces pones todos los márgenes y paddings a cero ¡pero el hueco sigue estando ahí!
Te emocionas. Piensas que has encontrado un bug en el navegador y te vienes arriba pensando en reportarlo mientras decides ponerle un nombre bonito a ese bug para que luzca bien en tu Linkedin o en tu blog. ¡Correrán ríos de píxeles contando tu historia en blogs, comunidades y redes sociales! ¡Serás una estrella en StackOverflow! Pero antes de reportar el bug decides probar en otros navegadores y ¡oh sorpresa!, el comportamiento es el mismo 😜
Va a ser que no es un bug. En efecto, es una característica.
La solución rápida a este espacio
Para los cortoplacistas que tienen mucha prisa y necesitan una solución ya, va por vosotros:
Ponedle a la imagen display:block
, display:inline-block
o al contenedor line-height:0;
Con eso debería solucionarse el problema. Si no se soluciona, entonces quizá tengáis que investigar más, que hay más opciones. Pasa al punto siguiente.
Para los que quieren saber por qué pasa esto
El origen de este comportamiento tiene que ver con cómo los navegadores calculan el interlineado y lo usan para gestionar el alineado vertical dentro de la línea de texto, según se explica en la especificación de CSS 2.1 y en el borrador de CSS 2.2.
Es bastante lioso porque influyen varios factores que no siempre dependen de nosotros (como el diseño de la fuente de texto), pero voy a intentar contarlo de una forma sencilla, directa y útil para este caso.
Para calcular el vertical-align
los navegadores no toman como referencia la altura de línea en bruto (line-height
), sino que calculan el interlineado. Este interlineado no tiene nada que ver con el interlineado en edición impresa. En el mundo de la composición y edición impresa, el interlineado se define como la distancia entre líneas base. Esto es, la línea imaginaria sobre la que descansan las letras minúsculas.
En el navegador el interlineado es el resultado de restar line-height
menos font-size
. El interlineado se divide entre dos y se añade por encima y por abajo del font-size
.
A este valor que se suma por arriba y por abajo del font size en la especificación se le llama half-leading (medio interlineado) y su valor puede llegar a ser negativo, que es cuando se montan la líneas de texto.
Bien, al sumar al font-size
el half-leading por arriba y por abajo, se define una especia de “caja” para los elementos en línea. A esta caja no le afectan el padding ni el margin, simplemente se suman a partir de ella.
Veámoslo con un ejemplo. Supongamos que tenemos definidos estos valores de tamaño de texto y de interlineado:
font-size: 20px;
line-height: 40px;
El half leading será el resultado de restar la altura de línea menos el tamaño de texto (cuyo resultado es el interlineado) y dividirlo entre dos. O sea 10px por arriba y 10px por abajo.
Los márgenes superior e inferior resultantes son los que definirán dónde se alinea un elemento con vertical-align: top;
y vertical-align: bottom;
Podría extenderme más sobre este tema del interlineado y la alineación vertical, ya que es una de las causas de que sea tan complicado encontrar un buen ritmo vertical de contenido. Pero este tema escapa al alcance de este post.
En realidad el principal problema es que esta caja del interlineado se calcula para cada glifo.
Un glifo es simplemente un símbolo. Cada letra, número, signo de puntuación o espacio que insertas con el teclado es un glifo.
Si dentro de un mismo elemento <p>
(por ejemplo) hay varios glifos de distintas tipografías probablemente te resultará difícil que queden bien alineados, ya que dos fuentes con el mismo font-size
pueden tener un tamaño totalmente diferente, y que no tiene por qué coincidir ni siquiera con la posición de las ascendentes y descendentes (o el espacio que ocupa su representación visual). Esto se ve directamente influido por cómo se ha creado una fuente.
Si te interesa este tema deja tu feedback en los comentarios. Si veo que hay interés podría profundizar en ello en un futuro post.
Pero en este caso hay una imagen, no hay texto ¿en qué influye?
Bien, es cierto que no hay texto, pero estos cálculos se hacen para todos los elementos en línea, y las imágenes son elementos en línea.
Como no hay texto, el navegador inserta un glifo de ancho cero al principio del elemento. Este elemento tiene un nombre y se llama strut.
En función del font-size
y line-height
que tengamos definido, nos aparecerá ese espacio fantasma. Que no es ningún fantasma, en realidad es el half-leading inferior del strut.
Por eso las soluciones pasan por darle a la imagen alguno de estos valores:
display:block
o display:inline-block
(ya no se calculará el alineado vertical como si fuera inline)
vertical-align
con valor top
o text-top
O al elemento de bloque:
line-height:0
, así se le añadirán 0 pixels al font-size
y el half-leading será cero.
font-size:0
o un valor muy pequeño. Pero es la solución menos recomendable si hay un image-caption
o algún otro texto dentro del elemento de bloque
Para terminar, simplemente comentar que este problema es (o era) muy habitual en los emails publicitarios maquetados con HTML, sobre todo en los típicos que se despedaza una imagen para volver a montarla por trozos en una tabla. Sobre todo en el viejo Hotmail aparecían estos huecos por doquier.
Así que, si estás maquetando un newsletter y te aparecen también estos extraños huecos al probarlo en clientes de correo, que sepas que la solución es la misma.