Solo llévame a las soluciones, por favor.
Crear una fila horizontal de objetos que sean equidistantes entre sí es otra de esas cosas en el diseño web que es mucho más difícil de lo que debería ser. Esto puede ser algo muy útil, especialmente en diseños de ancho fluido cuando intenta aprovechar al máximo cualquier espacio horizontal que tenga.
Estos son los objetivos que estamos tratando de lograr:
- El objeto más a la izquierda es alineado a la izquierda con su elemento padre.
- El objeto más a la derecha es alineado a la derecha con su elemento padre.
- cada objeto es equidistante unos de otros en todo momento.
- Los objetos serán dejar de superponerse entre sí a medida que la ventana del navegador se estrecha.
- Los objetos no se envolverá hacia abajo a medida que la ventana del navegador se estrecha.
- La técnica funcionará en un entorno de ancho fluido. Incluso uno que es centrado.
Probé varias técnicas diferentes para tratar de lograr esto. Repasemos todos mis fracasos y luego la técnica final que parece funcionar bastante bien.
FALLO: Dar a cada objeto un porcentaje de posición a la izquierda
Primero le di a cada imagen una clase única:
<img src="https://css-tricks.com/equidistant-objects-with-css/images/shape-red.png" class="first-r">
<img src="images/shape-green.png" class="second-r">
<img src="images/shape-yellow.png" class="third-r">
<img src="images/shape-blue.png" class="fourth-r">
Luego le di un posicionamiento a la izquierda basado en porcentajes a cada una de esas clases:
img.first-r { left: 0%; position: relative; }
img.second-r { left: 25%; position: relative; }
img.third-r { left: 50%; position: relative; }
img.third-r { left: 75%; position: relative; }
Observe el posicionamiento relativo. Esto es necesario para que la imagen que se encuentra más a la izquierda respete el elemento principal, suponiendo que el contenido esté centrado y no alineado a la izquierda. El problema con esto es que el margen izquierdo que se aplica al objeto más a la derecha es el 75% del ancho de la ventana del navegador, pero se aplica comenzando a la izquierda del elemento principal, no de la ventana del navegador. Esto puede hacer que el elemento más a la derecha se salga de la pantalla (sin respetar el borde derecho del elemento principal). Además, inexplicablemente, estos elementos eventualmente se ajustarán si mueve la ventana del navegador lo suficientemente estrecha.
Si cambia al posicionamiento absoluto aquí, resuelve algunos de los problemas anteriores, pero luego sus objetos se alinearán a la izquierda e ignorarán por completo la posición izquierda de los elementos principales. Además, en tamaños de ventana del navegador lo suficientemente estrechos, las imágenes se superpondrán. Pero bueno, ¡al menos los objetos eran equidistantes!
FALLO: Dar a los objetos un margen de porcentaje izquierdo común
Mi siguiente intento fue darle a cada elemento, excepto el primero, un margen izquierdo de porcentaje común.
<span class="do-not-wrap">
<img src="https://css-tricks.com/equidistant-objects-with-css/images/shape-red.png">
<img src="images/shape-green.png" class="mover">
<img src="images/shape-yellow.png" class="mover">
<img src="images/shape-blue.png" class="mover">
</span>
Aplicando el margen:
img.mover {
margin-left: 15%;
}
Al mirar ese porcentaje, debería poder decir que esta técnica está condenada. Simplemente elegí un porcentaje que parecía funcionar mejor. No hay nada matemático que se me ocurra que funcione aquí. Debido a que el elemento principal es un porcentaje del ancho de la ventana del navegador, y el margen es un porcentaje de la ventana del navegador, no del elemento principal, las tasas de crecimiento serán muy difíciles de igualar. Observe también el lapso “sin envoltura”, que es necesario para evitar… espérelo… que se envuelva. Pero bueno, ¡al menos los objetos eran equidistantes!
FALLO: ¡Solo usa una tabla!
Incluso “tirar la toalla” en CSS no parece funcionar aquí. Pensé que esto funcionaría con seguridad, ya que las tablas tienen esa capacidad a veces útil y a veces exasperante de espaciar automáticamente sus celdas de manera uniforme.
<table>
<tr>
<td class="leftalign">
<img src="https://css-tricks.com/equidistant-objects-with-css/images/shape-red.png">
</td>
<td>
<img src="images/shape-green.png">
</td>
<td>
<img src="images/shape-yellow.png">
</td>
<td class="rightalign">
<img src="images/shape-blue.png">
</td>
</tr>
</table>
Observe las clases de alineación adicionales en la primera y la última celda. Si todas las celdas están centradas, eso permite que los objetos sean equidistantes pero entonces ni el objeto de la izquierda ni el objeto de la derecha están alineados con el borde del elemento principal. Esto se puede solucionar aplicando una alineación a la izquierda a la celda más a la izquierda y una alineación a la derecha a la celda más a la derecha: pero entonces los objetos ya no son equidistantes. De vuelta a la mesa de dibujo.
APROBADO: Justificación de Flexbox
Estoy agregando esto en junio de 2015 (¡siete años después!) porque es la mejor solución (si puede usar flexbox).
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
.container {
display: flex;
justify-content: space-between;
}
Vea los objetos equidistantes de pluma de Chris Coyier (@chriscoyier) en CodePen.
PASA: Primero a la izquierda, flota el resto a la derecha en cajas del mismo tamaño
Afortunadamente, la idea de la mesa provocó algunos pensamientos. La primera imagen debe estar alineada a la izquierda, pero todas las demás podrían estar alineadas a la derecha. De hecho, si lo están, y también dentro de cajas que dividen el resto de ese espacio de manera uniforme, eso podría funcionar. Quizás esto se explique mejor visualmente:
HTML:
<img src="https://css-tricks.com/equidistant-objects-with-css/images/shape-red.png">
<div id="movers-row">
<div><img src="images/shape-green.png"></div>
<div><img src="images/shape-yellow.png"></div>
<div><img src="images/shape-blue.png"></div>
</div>
CSS:
#movers-row {
margin: -120px 0 0 120px;
}
#movers-row div {
width: 33.3%;
float: left;
}
#movers-row div img {
float: right;
}
Hay una página de ejemplo, donde estaba trabajando esto. No es bonito… pero puedes ver al ganador en la parte inferior. Estoy seguro de que algunos de ustedes tienen mejores soluciones para esto, ¡así que déjenme tenerlas!
APROBADO: uso de bloques en línea y texto justificado
Esto se puede hacer ajustando los elementos a display: inline-block;
y el elemento padre para text-align: justify;
. Bueno, es un poco más complicado y lo que yo llamaría un truco CSS de buena fe. Agrega un elemento adicional (a través de un pseudo elemento) que tiene un 100% de ancho y los bloques en línea anteriores se alinearán.
<div id="container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
#container {
height: 125px;
text-align: justify;
border: 10px solid black;
font-size: 0.1px; /* IE 9/10 don't like font-size: 0; */
min-width: 600px;
}
#container div {
width: 150px;
height: 125px;
display: inline-block;
background: red;
}
#container:after {
content: '';
width: 100%; /* Ensures there are at least 2 lines of text, so justification works */
display: inline-block;
}
Manifestación:
Check out this Pen!