Äquidistante Objekte mit CSS

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Bringen Sie mich bitte direkt zu den Lösungen.

Eine horizontale Reihe von Objekten zu erstellen, die gleichmäßig voneinander entfernt sind, ist eine weitere dieser Aufgaben im Webdesign, die viel schwieriger ist, als sie sein sollte. Dies kann sehr nützlich sein, insbesondere in Layouts mit fließender Breite, wenn Sie den horizontalen Platz optimal nutzen möchten.

equidistant.png

Hier sind die Ziele, die wir erreichen wollen

  • Das am weitesten links stehende Objekt ist linksbündig mit seinem Elternelement ausgerichtet.
  • Das am weitesten rechts stehende Objekt ist rechtsbündig mit seinem Elternelement ausgerichtet.
  • Jedes Objekt ist stets gleichmäßig voneinander entfernt.
  • Die Objekte überlappen sich nicht, wenn sich das Browserfenster verengt.
  • Die Objekte springen nicht nach unten, wenn sich das Browserfenster verengt.
  • Die Technik funktioniert in einer fließenden Umgebung. Selbst wenn sie zentriert ist.

Ich habe verschiedene Techniken ausprobiert, um dies zu erreichen. Gehen wir durch all meine Fehlschläge und dann zur endgültigen Technik, die ziemlich gut zu funktionieren scheint.

FEHLSCHLAG: Jedem Objekt eine prozentuale linke Position geben

Zuerst gab ich jedem Bild eine eindeutige Klasse

<img src="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">

Dann gab ich diesen Klassen eine prozentuale linke Positionierung

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; }

Beachten Sie die relative Positionierung. Diese ist erforderlich, damit das am weitesten links stehende Bild das Elternelement berücksichtigt, vorausgesetzt, der Inhalt ist zentriert und nicht linksbündig. Das Problem dabei ist, dass der linke Rand, der auf das am weitesten rechts stehende Objekt angewendet wird, 75 % der Breite des Browserfensters beträgt, aber beginnend links vom Elternelement und nicht vom Browserfenster aus angewendet wird. Dies kann dazu führen, dass das am weitesten rechts stehende Element vom Bildschirm verschwindet (ohne den rechten Rand des Elternelements zu beachten). Außerdem springen diese Elemente unerklärlicherweise irgendwann um, wenn Sie das Browserfenster ausreichend verengen.

Wenn Sie hier zur absoluten Positionierung wechseln, lösen Sie einige der oben genannten Probleme, aber dann sind Ihre Objekte linksbündig und ignorieren die linke Position des Elternelements vollständig. Außerdem überlappen sich die Bilder bei ausreichend schmalen Browserfenstergrößen. Aber hey, zumindest waren die Objekte gleichmäßig verteilt!

FEHLSCHLAG: Den Objekten einen gemeinsamen linken prozentualen Rand geben

Mein nächster Versuch war, jedem Element, mit Ausnahme des ersten, einen gemeinsamen prozentualen linken Rand zu geben.

<span class="do-not-wrap">
  <img src="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>

Anwenden des Rands

img.mover {
  margin-left: 15%;
}

Sie sollten anhand des prozentualen Wertes erkennen können, dass diese Technik zum Scheitern verurteilt ist. Ich habe nur einen Prozentwert gewählt, der am besten zu funktionieren schien. Mir fiel nichts Mathematisches ein, das hier funktionieren würde. Da das Elternelement ein Prozentsatz der Breite des Browserfensters ist und der Rand ein Prozentsatz des Browserfensters und nicht des Elternelements ist, sind die Wachstumsraten sehr schwer abzugleichen. Beachten Sie auch den "no-wrap"-Span, der notwendig ist, um... warten Sie es ab... Umbruch zu verhindern. Aber hey, zumindest waren die Objekte gleichmäßig verteilt!

FEHLSCHLAG: Verwenden Sie einfach eine Tabelle!

Selbst wenn man CSS aufgibt, scheint es hier nicht zu funktionieren. Ich dachte, das würde sicher funktionieren, da Tabellen die manchmal nützliche, manchmal ärgerliche Fähigkeit haben, ihre Zellen automatisch gleichmäßig zu verteilen.

<table>
	<tr>
		<td class="leftalign">
			<img src="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>

Beachten Sie die zusätzlichen Ausrichtungsklassen in der ersten und letzten Zelle. Wenn alle Zellen zentriert sind, können die Objekte gleichmäßig verteilt werden, aber weder das linke noch das rechte Objekt ist am Rand des Elternelements ausgerichtet. Dies ist lösbar, indem der äußersten linken Zelle eine linke Ausrichtung und der äußersten rechten Zelle eine rechte Ausrichtung zugewiesen wird – aber dann sind die Objekte nicht mehr gleichmäßig verteilt. Zurück an den Zeichentisch.

BESTANDEN: Flexbox-Justierung

Ich füge dies im Juni 2015 hinzu (sieben Jahre später!), da es die beste Lösung ist (wenn Sie Flexbox verwenden können).
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>​
.container {
  display: flex;
  justify-content: space-between;
}

Siehe den Pen Equidistant Objects von Chris Coyier (@chriscoyier) auf CodePen.

BESTANDEN: Zuerst links, den Rest rechts in gleich großen Boxen schweben lassen

Glücklicherweise hat die Tabellenidee zu einigen Überlegungen angeregt. Das erste Bild muss linksbündig ausgerichtet sein, aber alle anderen könnten rechtsbündig ausgerichtet sein. Tatsächlich, wenn sie es sind und auch in Boxen liegen, die den restlichen Platz gleichmäßig aufteilen, könnte das ausreichen. Vielleicht lässt sich das am besten visuell erklären

floatytechnqiue.png

HTML

<img src="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;
}

Es gibt eine Beispielseite, auf der ich daran gearbeitet habe. Sie ist nicht schön... aber Sie können den Gewinner unten sehen. Ich bin sicher, einige von Ihnen haben bessere Lösungen dafür, also lassen Sie es mich wissen!

BESTANDEN: Verwendung von Inline-Block und Blocksatztext

Dies kann durch Setzen der Elemente auf display: inline-block; und des Elternelements auf text-align: justify; erreicht werden. Nun, es ist etwas komplizierter und was ich einen echten CSS-Trick nenne. Sie fügen ein zusätzliches Element hinzu (über ein Pseudo-Element), das 100 % breit ist, und die vorherigen Inline-Blöcke werden ausgerichtet.

<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;
}

Demo

Check out this Pen!