Rand verwenden: Auto, um ein Div vertikal auszurichten

113

Ich weiß also, dass wir ein Div horizontal zentrieren können, wenn wir es verwenden margin:0 auto;. Sollte margin:auto auto;funktionieren, wie ich denke, dass es funktionieren sollte? Auch vertikal zentrieren?

Warum funktioniert das auch nicht vertical-align:middle;?

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

JSFiddle

Sparer
quelle
1
Es wird dringend empfohlen, die unten stehende Antwort von @ zpr zu Flexbox zu lesen und umzusetzen. Es wird ab heute ziemlich gut unterstützt und Ihr CSS wird viel, viel sauberer sein.
Govind Rai
if ((neues Datum ()). getFullYear ()> 2017) useFlexBox = true;
Brandito

Antworten:

173

Update August 2020

Obwohl das Folgende für die nützlichen Informationen immer noch lesenswert ist, haben wir Flexbox schon seit einiger Zeit. Verwenden Sie es einfach gemäß dieser Antwort .


Sie können nicht verwenden:

vertical-align:middleweil es nicht für Elemente auf Blockebene gilt

margin-top:autound margin-bottom:autoweil ihre verwendeten Werte als Null berechnet würden

margin-top:-50%weil prozentuale Randwerte relativ zur Breite des enthaltenen Blocks berechnet werden

Tatsächlich machen es die Algorithmen zur Berechnung des Dokumentenflusses und der Elementhöhe unmöglich, Ränder zum vertikalen Zentrieren eines Elements innerhalb seines übergeordneten Elements zu verwenden. Wenn der Wert eines vertikalen Randes geändert wird, wird eine Neuberechnung der Höhe des übergeordneten Elements (Reflow) ausgelöst, die wiederum eine Neuzentrierung des ursprünglichen Elements auslöst. Dies macht es zu einer Endlosschleife.

Sie können verwenden:

Einige solche Problemumgehungen, die für Ihr Szenario funktionieren. Die drei Elemente müssen so verschachtelt sein:

.container {
    display: table;
    height: 100%;
    position: absolute;
    overflow: hidden;
    width: 100%;
}
.helper {
    #position: absolute;
    #top: 50%;
    display: table-cell;
    vertical-align: middle;
}
.content {
    #position: relative;
    #top: -50%;
    margin: 0 auto;
    width: 200px;
    border: 1px solid orange;
}
<div class="container">
    <div class="helper">
        <div class="content">
            <p>stuff</p>
        </div>
    </div>
</div

JSFiddle funktioniert laut Browsershot einwandfrei .

ov
quelle
10
#ist ein Hack, dem die Regel vorangestellt wird, die nur von IE7 und darunter interpretiert wird. Sie bevorzugen stattdessen diese Regeln in einem IE-spezifischen Sheet enthalten bedingten Kommentare mit usw.
ov
2
+1 Für die Angabe der Gründe, warum dies der Fall ist, war die Berechnung des Randprozentsatzes basierend auf der Breite sehr aufschlussreich.
Ricosrealm
2
Ich bezweifle die Aussage 'Endlosschleife'.
Barun
104
Die Menschheit war schon vor Jahren auf dem Mond und wir müssen uns immer noch mit diesem Bullcrap auseinandersetzen. vertikal ausrichten Dinge in einem Browser, Jesus
Benutzer151496
3
Im> = IE9-Alter position: absolute; top: 50%; transform: translateY(-50%);ist es auch machbar und sehr beliebt ... (im Gegensatz dazu muss top:50%;margin: - $halfHeightman die Größe nicht im Voraus kennen ...)
Frank Nocke
112

Da diese Frage 2012 gestellt wurde und wir mit der Browserunterstützung für Flexboxen einen langen Weg zurückgelegt haben, hatte ich das Gefühl, dass diese Antwort obligatorisch ist.

Wenn die Anzeige des übergeordneten Containers ist flex, dann ja , margin: auto auto(auch bekannt margin: auto) arbeiten wird es zum Zentrum sowohl horizontal als auch vertikal, unabhängig davon , ob es ein ist inlineoder blockElement.

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
}
#child {
    margin: auto auto;
}
<div id="parent">
    <div id="child">hello world</div>
</div>

Beachten Sie, dass die Breite / Höhe nicht unbedingt angegeben werden muss, wie in diesem Beispiel jfiddle, bei dem die Größe relativ zum Ansichtsfenster verwendet wird.

Obwohl die Browserunterstützung für Flexboxen zum Zeitpunkt der Veröffentlichung auf einem Allzeithoch ist, wird sie von vielen Browsern immer noch nicht unterstützt oder es werden Herstellerpräfixe benötigt. Aktuelle Informationen zur Browserunterstützung finden Sie unter http://caniuse.com/flexbox .

Aktualisieren

Da diese Antwort ein wenig Beachtung fand, möchte ich auch darauf hinweisen, dass Sie überhaupt nicht angeben müssen, marginob Sie verwenden, display: flexund alle Elemente im Container zentrieren möchten:

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
    align-items: center; /* horizontal */
    justify-content: center; /* vertical */
}
<div id="parent">
    <div>hello world</div>
</div>

zpr
quelle
4
Eltern {Anzeige: Flex; } child {margin: auto 0; } ist einfach toll.
Arek Kostrzeba
OMG Alter, du bist ein Rockstar, verdammt, ich kann dich nicht mehr als einmal unterstützen !!!
PirateApp
Dies ist eine gute Antwort, wenn Sie möglicherweise auch mit dem Problem des Fit-Inhalts verwechselt werden. Durch Festlegen von Flex für den Container benötigt das Inhalts-Div keine Eigenschaften zum Festlegen.
Eric
1
Dies ist bei weitem die beste und eleganteste Lösung für 2018, danke.
SilverSurfer
Ich möchte hinzufügen, dass ab Mai 2018 mit dieser Lösung der Text nicht vertikal in der Mitte in IE 11 ausgerichtet ist.
Yefu
62

Hier ist die beste Lösung, die ich gefunden habe: http://jsfiddle.net/yWnZ2/446/ Funktioniert in Chrome, Firefox, Safari, IE8-11 und Edge.

Wenn Sie ein erklärt haben height( height: 1em, height: 50%usw.) oder es ist ein Element , auf dem der Browser die Höhe weiß ( img, svg, oder canvaszum Beispiel), dann alles , was Sie für die vertikale Zentrierung benötigen , ist dies:

.message {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    margin: auto;
}

Normalerweise möchten Sie ein widthoder max-widthso angeben, dass sich der Inhalt nicht über die gesamte Länge des Bildschirms / Containers erstreckt.

Wenn Sie dies für ein Modal verwenden, das immer im Ansichtsfenster zentriert sein soll und andere Inhalte überlappt, verwenden Sie es position: fixed;für beide Elemente anstelle von position: absolute. http://jsfiddle.net/yWnZ2/445/

Hier ist eine vollständigere Beschreibung: http://codepen.io/shshaw/pen/gEiDt

shshaw
quelle
3
Dies zentriert es nicht unbedingt in seinem übergeordneten Element. Netter Hack, wenn Sie es nur in der Mitte der Seite wollen.
Joel Mellon
2
Fügen Sie einfach position: relativezum übergeordneten Element hinzu , und das Element wird im übergeordneten Element zentriert. Ich habe im Smashing Magazine einen viel größeren Artikel über die Technik geschrieben, wenn Sie mehr lesen möchten
shshaw
Manchmal basiert Absolut auf einem oder zwei Elternteilen (gegen den Körper) und Verwandte können Groß- oder Urgroßeltern (gegen den Elternteil) sein. Vielleicht könnten diejenigen, die wissen, wann oder warum dies geschieht, diese Technik besser kontrollieren - ich habe mich nie wirklich mit diesen Problemen befasst, aber ich weiß, dass der Wechsel von absolut zu relativ an sich keine Lösung ist, um diese Arbeit zu machen. Ich habe ein wenig von Ihrem Artikel gelesen und es sieht so aus, als ob absolut und relativ zum ersten absoluten oder relativen Vorfahren aufsteigen. Ist das richtig?
Joel Mellon
Ich bin ein wenig langsam. Ich habe gerade Ihren Kommentar oben noch einmal gelesen. Ich habe nicht bemerkt, dass du gesagt hast, du sollst es dem hinzufügen parent. Vielen Dank!
Joel Mellon
1
@commonpike Das einzige Problem mit IE8 / 9 ist, wenn Sie display: tablefür Inhalte mit variabler Höhe verwenden. Andernfalls sollte diese Methode wie erwartet funktionieren. Lesen Sie die Beschreibung durch, um weitere Einzelheiten zu erfahren . Sie sollten auch in der Lage sein, die vollständige Ansicht in IE8 / 9 zu testen, um festzustellen, ob Probleme vorliegen.
Shshaw
21

Bearbeiten: Es ist 2020, ich würde stattdessen Flexbox verwenden.

Ursprüngliche Antwort:

Html

<body>
  <div class="centered">
  </div>
</body>

CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Gal Margalit
quelle
würde nicht für IE 8 und ältere Versionen von dh funktionieren. Da die Transformationseigenschaft (mit dem Präfix -ms-) ab Version 9.0 unterstützt wird. (dh 10 brauchen kein Präfix mehr).
DevWL
5
Es stimmt, ich interessiere mich nicht für IE8
Gal Margalit
Und der Autor hat html5 für seine Frage markiert
Gal
9

Ich weiß, dass die Frage aus dem Jahr 2012 stammt, aber ich habe den einfachsten Weg aller Zeiten gefunden und wollte ihn teilen.

HTML:

<div id="parent">
     <div id="child">Content here</div>
</div>

und CSS:

#parent{
     height: 100%;
     display: table;
}    
#child {
     display: table-cell;
     vertical-align: middle; 
}
Paula Fleck
quelle
7

Wenn Sie die Höhe des Divs kennen, das Sie zentrieren möchten , können Sie es absolut innerhalb des übergeordneten Div positionieren und dann den topWert auf setzen 50%. Dadurch wird die Spitze des Kindes 50% des Weges des Elternteils gesenkt, dh zu niedrig. Ziehen Sie es wieder nach oben, indem Sie es auf die margin-topHälfte seiner Höhe einstellen . Jetzt haben Sie den vertikalen Mittelpunkt des untergeordneten Divs am vertikalen Mittelpunkt des Elternteils - vertikal zentriert!

Beispiel:

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
    position: absolute;
    top: 50%;
    margin-top: -25px;
    height: 50px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

http://jsfiddle.net/yWnZ2/2/

Tuff
quelle
1
margin-topkann nicht in% bezogen auf die Elementhöhe eingestellt werden, so dass Sie mit einem Maße abhängig fix am Ende dann
ov
1
Welches ist ... genau das, was ich in meiner Antwort gesagt habe? "Wenn Sie die Höhe des Div kennen, möchten Sie zentrieren". Und ich habe nicht gesagt, dass OP% in verwenden soll margin-top.
Tuff
Ich bin mit der Lösung nicht einverstanden, da sie Sie an eine vordefinierte Elementhöhe bindet - aber Ihr Kommentar ist sinnvoll. Sie können , dass in der Antwort reflektieren wollen
ov
3
OK, ich habe den Teil, den Sie übersehen haben, fett gedruckt, hoffentlich ist das jetzt klarer.
Tuff
1
@ov: Wenn das Element keine feste Höhe hat, können Sie einfach JS verwenden, um die berechnete Höhe abzurufen und dann den negativen oberen Rand entsprechend festzulegen. Dies ist meiner Meinung nach immer noch die beste Methode zur vertikalen Zentrierung.
daGUY
3

Diese beiden Lösungen erfordern nur zwei verschachtelte Elemente.
Erstens - Relative und absolute Positionierung, wenn der Inhalt statisch ist (manuelle Mitte).

.black {
    position:relative;
    min-height:500px;
    background:rgba(0,0,0,.5);

}
.message {
    position:absolute;
    margin: 0 auto;
    width: 180px;
    top: 45%; bottom:45%;  left: 0%; right: 0%;
}

https://jsfiddle.net/GlupiJas/5mv3j171/

oder für flüssiges Design - für das genaue Content Center verwenden Sie stattdessen das folgende Beispiel:

.message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

https://jsfiddle.net/GlupiJas/w3jnjuv0/

Sie müssen die Mindesthöhe festlegen, falls der Inhalt 50% der Fensterhöhe überschreitet. Sie können diese Höhe auch mit einer Medienabfrage für Mobil- und Tablet-Geräte bearbeiten. Aber nur, wenn Sie mit Responsive Design spielen.

Ich denke, Sie könnten noch weiter gehen und ein einfaches JavaScript / JQuery-Skript verwenden, um die Mindesthöhe oder die feste Höhe zu ändern, wenn dies aus irgendeinem Grund erforderlich ist.

Zweitens : Wenn der Inhalt flüssig ist, können Sie auch CSS-Eigenschaften für Tabellen und Tabellenzellen mit vertikaler Ausrichtung und zentrierter Textausrichtung verwenden:

/*in a wrapper*/  
display:table;   

und

/*in the element inside the wrapper*/
display:table-cell;
vertical-align: middle;
text-align: center;

Funktioniert und skaliert perfekt und wird häufig als reaktionsschnelle Webdesign-Lösung mit Rasterlayouts und Medienabfragen verwendet, die die Breite des Objekts beeinflussen.

.black {
    display:table;
    height:500px;
    width:100%;
    background:rgba(0,0,0,.5);

}
.message {
    display:table-cell;
    vertical-align: middle;
    text-align: center;
}

https://jsfiddle.net/GlupiJas/4daf2v36/

Ich bevorzuge eine Tabellenlösung für die exakte Inhaltszentrierung, aber in einigen Fällen ist die relative absolute Positionierung besser geeignet, insbesondere wenn wir den exakten Anteil der Inhaltsausrichtung nicht beibehalten möchten.

DevWL
quelle
2

.black {
    display:flex;
    flex-direction: column;
    height: 200px;
    background:grey
}
.message {
    background:yellow;
    width:200px;
    padding:10px;
    margin: auto auto;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

Seetpal singh
quelle
Könnten Sie uns bitte mitteilen, worum es bei dieser Lösung geht? Außerdem sehe ich Ihre "Popup-Nachricht" unten nicht zentriert
Alex
Ich habe etwas verpasst, aber jetzt ist es verfeinert, das Div vertikal in der Mitte zu halten. Sie können jetzt überprüfen.
Seetpal singh
0

Es gibt keine einfache Möglichkeit, div vertikal zu zentrieren, die in jeder Situation den Trick macht.

Es gibt jedoch viele Möglichkeiten, dies je nach Situation zu tun.

Hier sind einige davon:

  • Legen Sie die obere und untere Auffüllung des übergeordneten Elements fest, z. B. die Auffüllung: 20px 0px 20px 0px
  • Verwenden Sie Tabelle, Tabellenzelle zentriert den Inhalt vertikal
  • Stellen Sie die relative Position des übergeordneten Elements und die Divs, die Sie vertikal zentrieren möchten, auf absolut ein und formatieren Sie sie wie oben: 50px; unten: 50px; beispielsweise

Sie können auch für "CSS vertikale Zentrierung" googeln

hasu
quelle
0

variable Höhe, Rand oben und unten automatisch

.black {background:rgba(0,0,0,.5);
width: 300px;
height: 100px;
display: -webkit-flex; /* Safari */
display: flex;}
.message{
background:tomato;
margin:auto;
padding:5%;
width:auto;
}
<div class="black">
<div class="message">
    This is a popup message.
</div>

variable Höhe, Rand oben und unten automatisch

user3668456
quelle
0

Verwenden der Flexbox:

HTML:

<div class="container">
  <img src="http://lorempixel.com/400/200" />
</div>

CSS:

.container {
  height: 500px;
  display: flex;
  justify-content: center; /* horizontal center */
  align-items: center;     /* vertical center */
}

Zeige Ergebnis

DanielBlazquez
quelle
0
.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background:yellow;
    width:200px;
    padding:10px;
}

 - 


----------


<div class="black">
<div class="message">
    This is a popup message.
</div>
Sudipto Chakraborty
quelle