Centering in CSS Leitfaden

Avatar of Chris Coyier
Chris Coyier am

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

Das Zentrieren von Dingen in CSS ist das Paradebeispiel für CSS-Beschwerden. Warum muss das so schwer sein?, höhnen sie. Ich denke, das Problem ist nicht, dass es schwierig ist, sondern dass es so viele verschiedene Möglichkeiten gibt, es zu tun, je nach Situation, und es ist schwer zu wissen, welche man wählen soll.

Machen wir also eine Entscheidungsbaum-Struktur und hoffen, dass es einfacher wird.

Ich muss zentrieren…

Horizontal

Sind es Inline- oder Inline-* Elemente (wie Text oder Links)?

Sie können Inline-Elemente horizontal innerhalb eines Block-Level-Elternelements mit nur einem

.center {
  text-align: center;
}

Dies funktioniert für Inline, Inline-Block, Inline-Tabelle, Inline-Flex usw.

Ist es ein Block-Level-Element?

Sie können ein Block-Level-Element zentrieren, indem Sie ihm margin-left und margin-right von auto geben (und es eine festgelegte width hat, sonst wäre es Vollbreite und müsste nicht zentriert werden). Das wird oft mit Kurzschriften wie dieser gemacht

.center-me {
  margin: 0 auto;
}

Dies funktioniert unabhängig von der Breite des zu zentrierenden Block-Level-Elements oder des Elternelements.

Beachten Sie, dass Sie ein Element nicht nach rechts floaten können, um es zu zentrieren. Es gibt jedoch einen Trick.

Gibt es mehr als ein Block-Level-Element?

Wenn Sie zwei oder mehr Block-Level-Elemente haben, die horizontal in einer Reihe zentriert werden müssen, ist es wahrscheinlich besser, ihnen einen anderen display-Typ zu geben. Hier ist ein Beispiel für die Umwandlung in inline-block und ein Beispiel für Flexbox

Es sei denn, Sie meinen, dass Sie mehrere Block-Level-Elemente übereinander gestapelt haben, in diesem Fall ist die Auto-Margin-Technik immer noch in Ordnung

Vertikal

Das vertikale Zentrieren ist in CSS etwas kniffliger.

Sind es Inline- oder Inline-* Elemente (wie Text oder Links)?
Ist es eine einzelne Zeile?

Manchmal können Inline-/Textelemente vertikal zentriert erscheinen, einfach weil darüber und darunter gleicher Abstand (Padding) ist.

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}

Wenn Polsterung aus irgendeinem Grund keine Option ist und Sie Text zentrieren möchten, der sich nicht umbrechen wird, gibt es einen Trick, bei dem die line-height gleich der Höhe gesetzt wird, um den Text zu zentrieren.

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}
Sind es mehrere Zeilen?

Gleicher Abstand oben und unten kann auch für mehrere Textzeilen den zentrierten Effekt erzielen, aber wenn das aus irgendeinem Grund nicht funktioniert, kann das Element, in dem sich der Text befindet, eine Tabellenzelle sein, entweder buchstäblich oder mit CSS so behandelt werden. Die Eigenschaft vertical-align behandelt dies in diesem Fall, im Gegensatz zu dem, was sie normalerweise tut, nämlich die Ausrichtung von Elementen in einer Zeile zu handhaben. (Mehr dazu.)

Wenn etwas Tabellenähnliches nicht in Frage kommt, könnten Sie vielleicht Flexbox verwenden? Ein einzelnes Flex-Kind kann ziemlich einfach in einem Flex-Elternteil zentriert werden.

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}

Denken Sie daran, dass dies nur dann wirklich relevant ist, wenn der übergeordnete Container eine feste Höhe hat (px, %, usw.), weshalb der Container hier eine Höhe hat.

Wenn beide Techniken nicht in Frage kommen, könnten Sie die „Ghost-Element“-Technik anwenden, bei der ein vollsichtiger Pseudo-Element im Container platziert wird und der Text mit diesem vertikal ausgerichtet wird.

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}
Ist es ein Block-Level-Element?
Kennen Sie die Höhe des Elements?

Es ist ziemlich üblich, die Höhe im Layout von Webseiten nicht zu kennen, aus vielen Gründen: Wenn sich die Breite ändert, kann der Textumbruch die Höhe ändern. Unterschiede in der Textgestaltung können die Höhe ändern. Unterschiede in der Textmenge können die Höhe ändern. Elemente mit einem festen Seitenverhältnis, wie Bilder, können bei Größenänderung die Höhe ändern. Etc.

Aber wenn Sie die Höhe kennen, können Sie vertikal zentrieren, so

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}
Ist das Element von unbekannter Höhe?

Es ist immer noch möglich, es zu zentrieren, indem man es um die Hälfte seiner Höhe nach oben schiebt, nachdem man es um die Hälfte nach unten geschoben hat

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
Spielt es eine Rolle, ob sich das Element über die gesamte Höhe des Containers erstreckt?

Wenn nicht, müssen Sie nur den Inhalt darin vertikal zentrieren. Tabellen oder CSS-Display, um Elemente in Tabellen zu verwandeln, können den Trick machen.

Können Sie Flexbox verwenden?

Keine große Überraschung, das ist in Flexbox viel einfacher.

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

Sie können die Zentrierung in Flexbox auch erreichen, indem Sie margin: auto; auf dem untergeordneten Element verwenden.

Beides Horizontal & Vertikal

Sie können die obigen Techniken beliebig kombinieren, um perfekt zentrierte Elemente zu erhalten. Aber ich finde, das fällt generell in drei Lager

Hat das Element eine feste Breite und Höhe?

Durch die Verwendung negativer Margen, die der Hälfte dieser Breite und Höhe entsprechen, nachdem es absolut bei 50 % / 50 % positioniert wurde, wird es mit großartiger Cross-Browser-Unterstützung zentriert

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

  position: absolute;
  top: 50%;
  left: 50%;

  margin: -70px 0 0 -170px;
}
Hat das Element eine unbekannte Breite und Höhe?

Wenn Sie die Breite oder Höhe nicht kennen, können Sie die `transform`-Eigenschaft und eine negative `translate` von 50 % in beide Richtungen verwenden (sie basiert auf der aktuellen Breite/Höhe des Elements), um zu zentrieren

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Können Sie Flexbox verwenden?

Um in beide Richtungen mit Flexbox zu zentrieren, müssen Sie zwei Zentrierungseigenschaften verwenden

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
Können Sie Grid verwenden?

Dies ist nur ein kleiner Trick (eingereicht von Lance Janssen), der für ein einzelnes Element ziemlich gut funktioniert

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}

Fazit

Sie können Dinge in CSS absolut zentrieren.