Display: inline-block y su empeño en dejar espacios en blanco de separación. 8 soluciones.

8 forma diferentes, usando css o vía html, de eliminar la separación que quedan entre items con display: inline-block y una explicación del porqué sucede

display:inline-block y sus espacios en blancoLo siguiente seguro que lo has sufrido. Hacer uso de display: inline-block y encontrarte con esos px de separación entre los distintos elementos que mandan al traste nuestro diseño.
Desesperante.
Para quienes esto les resulte nuevo, es lo siguiente: 4 hijos con esta posición y una anchura del 25%. A priori deberían colocarse adyacentes en la misma línea horizontal. Pero oh! sorpresa, nos encontramos esto:


1º hijo
2º hijo
3º hijo
4º hijo

El ejemplo anterior responde a a los siguientes códigos:

<div class="pater"> <div>1º hijo</div> <div>2º hijo</div> <div>3º hijo</div> <div>4º hijo</div> </div>

Y su css asociado:

.pater > div { display: inline-block; width: 25%; /*** Sólo a efectos de visualización ***/ background: #F3F3A1; margin: 0; }

Soluciones vía html

Todo junto y sin espacios

Es la que te encontrarás en la mayoría de las respuestas. Consiste en escribir en el html todos los items sin espacios en blanco ni saltos de línea:

<div class="pater"><div>1º hijo</div><div>2º hijo</div><div>4º hijo</div><div>4º hijo</div></div>
1º hijo
2º hijo
2º hijo
4º hijo

Eureka! Conseguido! uno a continuación del otro, sin nada que los separe y todos en la misma línea. Pero... se fue al traste todo nuestro empeño de tener nuestro html bien tabulado y estructurado.

Aprovecha las "particularidades" de html5

Como sabrás, html5 permite no cerrar las etiquetas. Así que podemos utilizarlo para anular el espacio entre items en inline-block. Basta con optar por dejar el código del ejemplo con el que abría este artículo de la siguiente forma:

<ul class="pater"> <li>1º hijo <li>2º hijo <li>3º hijo <li>4º hijo </div>

Manteniendo el mismo Css para ver los inline-block sin separación entre ellos:

  • 1º hijo
  • 2º hijo
  • 3º hijo
  • 4º hijo

Descompón la forma de escribir el html

Cambia la forma en que normalmente introduces los saltos de línea entre los elementos del html. Deja la apertura de un item a continuación del cierre de la precedente:

<ul class="pater"> <li>1º hijo</li><li> 2º hijo</li><li> 3º hijo</li><li> 4º hijo</li> </div>
  • 1º hijo
  • 2º hijo
  • 3º hijo
  • 4º hijo

Añadiendo comentarios vacíos

<ul class="pater"> <li>1º hijo</li><!-- --><li>2º hijo</li><!-- --><li>3º hijo</li><!-- --><li>4º hijo</li> </div>
  • 1º hijo
  • 2º hijo
  • 3º hijo
  • 4º hijo

Soluciones vía Css

Pero si estamos ante una particularidad que genera Css, éste debería aportar alguna vía para arreglarlo. Y sí, las hay.

Pues vamos a ver los distintos métodos para vía Css corregir este bug.

White-space: nowrap y Overflow: hidden

Echamos manos del "viejo" Css2.1 y su control de los espacios en blanco white-space junto al control de los desbordes con overflow para conseguirlo... a medias.
Todos alineados pero el espacio permanece. Y además hay una pequeña "trampa": quita el overflow y verás qué ocurre con el último hijo.

div.nowrap { overflow: hidden; white-space: nowrap; } div.nowrap > div.white-space { display: inline-block; white-space: normal; }
1º hijo
2º hijo
3º hijo
4º hijo

Márgenes negativos

Consiste en declarar un margin-right con valor negativo a los elementos declarados como inline-block. En las distintas pruebas que he hecho el valor está comprendido entre -0.26em a -0.29em. Un valor que podría ser válido curándonos en salud sería -0.3em

Separación entre letras negativa

Atacando el problema por lo escrito, que se lee. La separación también desaparece con un valor negativo para letter-spacing aplicado al contenedor y compensado en los hijos

.padre {letter-spacing: -0.35em} .hijo {letter-spacing: normal;}

Pero esta vía tiene su problema. La separación necesaria es función de cada tipo. Así para verdana=-0.33em / arial y times new roman=-0.28em / tahoma=-0.33em según mis pruebas.

Tamaño de la fuente

Y para terminar la guerra a los espacios en blanco de los elementos con position: inline-block nada como reducir el font-size del padre a cero (0) y compensarlo en los hijos.

.padre {font-size:0;} .hijo {font-size: 1rem;}
1º hijo
2º hijo
3º hijo
4º hijo

Si te fijas en este último ejemplo, el tamaño de la fuente en el hijo la he declarado en rem. La razón es obvia. No puedes usar "em" para el hijo, el cómputo se haría sobre el tamaño del padre, y 0*X=0 siempre.
Hay que desechar las unidades que el consorcio define como "relativas" y los "porcentajes" y usar las de "medida" (px, pt, mm...) o las de "tamaño absoluto" ( xx-small | x-small | small | medium | large | x-large | xx-large )

Actualizado: 04/2012

La técnica del font-size:0; no funciona en el navegador de Android pre-Jellybean. En los posteriores a Jellybean sí los suprime, pero por desgracia no lo hace con todos. Ver pen.

El porqué y de dónde provienen los espacios

Lo que ahora me queda pendiente es averiguar de dónde o el porqué de esos espacios en blanco.
Este comportamiento de los items con el valor inline-block de dejar un hueco entre cada uno de ellos creo que puede ser a que aplica la propiedad letter-spacing del padre a los hijos, pues en ese aspecto es dominante la parte que el hijo conserva de elemento en línea.
Pero es una suposición. ¿Tú que opinas y cómo ves estos parches?

Comparte y difunde. Es gratis y agradecido

El Autor del Blog


Un Ramajero a la verita del Tormes.
Aprendiz de todo y Enredique Amanuense de Css.
Argonauta virtual por esos bagos pazco:

14 comentarios:

  1. Curiosas e ingeniosas soluciones. Gracias!

    ResponderEliminar
  2. Me he divertido con esto, muchas gracias!

    ResponderEliminar
  3. Hola tengo un problema cuando dentro de los div hijos pongo un H2 o H3 o cualquier H y un parrafo p y les pongo margin:0 o algun otro valor, el hijo contenedor genera un margen arriba y la caja(hijo) se baja como puedo solucionar esto, el error aparece solamante cuando modifico el margen de los H o P

    ResponderEliminar
  4. Hola CristiandR
    Como habrá observado, el blog no está enfocado ni tampoco cuenta con las herramientas necesarias para ser un lugar de consultas y resolución de problemas concretos de sus usuarios.
    En la web encontrará multitud de sitios que sí cumplen y tienen ese objetivo.

    Además es imposible localizar qué lo produce y cómo solventarlo sin analizar el código.

    No obstante todo lo anterior quizás le convenga leer sobre el concepto "margin-collapse":
    http://www.w3.org/TR/CSS2/box.html

    ResponderEliminar
  5. Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar
  6. Anónimo19/8/12

    Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar
  7. Anónimo3/11/12

    Capoooo GRACIAS con mayusculas.

    ResponderEliminar
  8. Anónimo30/11/12

    buenos hacks a tener en cuenta

    ResponderEliminar
  9. mmfilesi16/12/12

    muy buen artículo, gracias por las pistas.

    ResponderEliminar
  10. Pues estaba viendo y probando y también puedes arreglando usando display: table-cell y border:collapse

    ResponderEliminar
  11. Cada valor conlleva unas características que le son propias y en el momento que cambias el valor de display... ya es otro tema.

    Gracias por la aportación, Alejandro

    ResponderEliminar
  12. De gran ayuda =) quisiera saber si la forma quitando el final de la etiqueta li ,trae problemas adelante.Graciassss

    ResponderEliminar
  13. Muchas Gracias,me sirvio bastante.Quisiera saber si la forma de solucionar esto,quitando el final de la etiqueta li, trae problemas mas adelante en el tema de porcentaje o adaptabilidad de la web.Gracias

    ResponderEliminar
    Respuestas
    1. Hola Jonatan
      De entrada recuerda que esa práctica depende del doctype que se utilice. Sólo permitido con Html5.

      De todas formas soy de la vieja escuela, de aquel mantra que dice: "Cierra todo lo que abras"

      Puedes ampliar un poc el tema en el artículo "No es lo mismo, no da igual, elemento que tag"

      Un saludo

      Eliminar

Suscríbete a los comentarios del artículo, así recibirás un aviso en tu correo cuando otro lector publique una respuesta.
En las entradas con más de 60 días están moderados.