Wie kann man Inhalte mit variabler Höhe innerhalb eines Div vertikal zentrieren?

158

Was ist der beste Weg, um den Inhalt eines Div vertikal zu zentrieren, wenn die Höhe des Inhalts variabel ist? In meinem speziellen Fall ist die Höhe des Containers div festgelegt, aber es wäre großartig, wenn es eine Lösung gäbe, die in Fällen funktioniert, in denen der Container auch eine variable Höhe hat. Außerdem würde ich eine Lösung lieben, bei der CSS-Hacks und / oder nicht-semantisches Markup nicht oder nur sehr wenig verwendet werden.

Alt-Text

Jessegavin
quelle
Die Methode in diesem Artikel fällt in Safari (4.0.5) auseinander: S
7
@ ripper234 Nicht genau, da diese Frage über variable Höhe div ist
Rauli Rajande
9
Auch diese Frage wurde zuerst gestellt.
Gui Imamura
1
Mögliches Duplikat von Wie zentriere ich ein Div für alle Browser vertikal?
Sandy Joshi

Antworten:

147

Einfach hinzufügen

position: relative;
top: 50%;
transform: translateY(-50%);

zum inneren div.

Es bewegt den oberen Rand des inneren Div auf die halbe Höhe des äußeren Div ( top: 50%;) und dann den inneren Div um die Hälfte seiner Höhe ( transform: translateY(-50%)). Dies funktioniert mit position: absoluteoder relative.

Beachten Sie dies transformund verwenden Sie translateHerstellerpräfixe, die der Einfachheit halber nicht enthalten sind.

Codepen: http://codepen.io/anon/pen/ZYprdb

BlackCetha
quelle
6
Ich habe mich nur gefragt, warum dies unter Chrome und Firefox funktioniert, aber nicht für Safari. Dann habe ich festgestellt, dass die meisten transformverwandten Dinge -webkit-vorangestellt sind und jetzt funktioniert es. Nur zur Erinnerung: Vergessen Sie nicht, auch das -webkit-Präfix hinzuzufügen .
Miho
5
Verwenden Sie ein Tool wie github.com/postcss/autoprefixer , um die Präfixe für Sie zu verarbeiten.
Jamie Chong
6
Diese Antwort sollte oben stehen.
Jose Faeti
3
Dies sollte viel mehr positive Stimmen haben! Übrigens funktioniert es auch mit position: absolute, nicht wahr?
Caw
4
Diese Methode hat in Chrome einen unglücklichen Nebeneffekt: Wenn Ihr Wrapper eine ungerade Anzahl von Pixeln hat, translatewird alles verschwommen, wenn er versucht, die Höhe von 0,5 Pixel für alles zu verarbeiten.
Keith
157

Dies scheint die beste Lösung zu sein, die ich für dieses Problem gefunden habe, solange Ihr Browser das Pseudoelement unterstützt ::before: CSS-Tricks: Zentrieren im Unbekannten .

Es erfordert kein zusätzliches Markup und scheint sehr gut zu funktionieren. Ich konnte die display: tableMethode nicht verwenden , da tableElemente der max-heightEigenschaft nicht gehorchen .

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>

Fadi
quelle
3
Nun, das ist eine brillante Lösung. Vielen Dank für die Veröffentlichung!
Troy Alford
Wie bei der anderen Antwort wäre diese viel besser, wenn sie den Ansatz beschreibt und Code aus dem Link enthält.
KatieK
3
+1, Diese Lösung ist wirklich ziemlich genial! Übrigens können Sie .block { white-space: nowrap; font-size: 0; line-height: 0; }den negativen rechten Rand zum Pseudoelement hinzufügen und belassen. Sie müssen nur fs und lh auf .centered zurücksetzen. Auf diese Weise stellen Sie sicher, dass das Element korrekt positioniert wird, auch wenn es breiter als das Ansichtsfenster ist (und don Ich muss das Imo nicht verwenden (ein bisschen chaotisch negativer Rand).
Simon
@ Jessegavin - Ihrer Meinung nach ... wie kann sich das Folgende gegen den von Ihnen skizzierten Ansatz
behaupten
1
Dies bricht auch zusammen, wenn der äußere Containerblock eine minimale Höhe anstelle einer Höhe hat.
Lincoln B
16

Dies ist etwas, was ich schon oft tun musste, und für eine konsistente Lösung müssen Sie immer noch ein wenig nicht-semantisches Markup und einige browserspezifische Hacks hinzufügen. Wenn wir Browser-Unterstützung für CSS 3 erhalten, erhalten Sie Ihre vertikale Zentrierung ohne Sünde.

Zur besseren Erklärung der Technik können Sie den Artikel lesen, aus dem ich ihn angepasst habe. Im Grunde geht es jedoch darum, ein zusätzliches Element hinzuzufügen und verschiedene Stile in IE und Browsern anzuwenden, die position:table\table-cellNicht-Tabellenelemente unterstützen.

<div class="valign-outer">
    <div class="valign-middle">
        <div class="valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

Es gibt viele Möglichkeiten (Hacks), Stile in bestimmten Browsersätzen anzuwenden. Ich habe bedingte Kommentare verwendet, aber schauen Sie sich den oben verlinkten Artikel an, um zwei andere Techniken zu sehen.

Hinweis: Es gibt einfache Möglichkeiten, eine vertikale Zentrierung zu erzielen, wenn Sie einige Höhen im Voraus kennen, wenn Sie versuchen, eine einzelne Textzeile zu zentrieren, oder in mehreren anderen Fällen. Wenn Sie mehr Details haben, werfen Sie diese ein, da es möglicherweise eine Methode gibt, die keine Browser-Hacks oder nicht-semantisches Markup erfordert.

Update: Wir beginnen, eine bessere Browserunterstützung für CSS3 zu erhalten, indem wir sowohl Flex-Box als auch Transformationen als alternative Methoden für die vertikale Zentrierung (unter anderem) anbieten. Weitere Informationen zu modernen Methoden finden Sie in dieser anderen Frage. Beachten Sie jedoch, dass die Browserunterstützung für CSS3 immer noch lückenhaft ist.

Prestaul
quelle
Ja, ich habe diesen Artikel heute gefunden und konnte ihn für meine spezielle Situation nicht zum Laufen bringen. Vielleicht muss ich das weiter untersuchen.
Jessegavin
Vielleicht können Sie den Code posten, den Sie verwenden und der nicht funktioniert?
Chris Marasti-Georg
Ist dies immer noch die beste Lösung für dieses Problem?
Ripper234
Dieser Artikel scheint unter Chrome 23, Firefox 16 und IE 9 nicht zu funktionieren. Diese Antwort scheint eine bessere Lösung zu sein.
Fernando Correia
Nein, dieser Artikel funktioniert immer noch in den neuesten Chrome und Firefox vom 24. Februar 2013
OMA
9

Mit der Kinderauswahl habe ich Fadis unglaubliche Antwort oben auf nur eine CSS-Regel reduziert, die ich anwenden kann. Jetzt muss ich nur noch den contentCenteredKlassennamen zu den Elementen hinzufügen, die ich zentrieren möchte:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class="contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

Forked CodePen: http://codepen.io/dougli/pen/Eeysg

Dougli
quelle
Cool. Danke für das Teilen. Ein Hinweis zur Vorsicht ist, dass der *Selektor schlechter abschneidet als die akzeptierte Antwort. Könnte kein Problem sein, ist aber erwähnenswert. stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin
Vielen Dank. Ja, es wird wahrscheinlich schlechter abschneiden, aber heutzutage haben CSS-Regeln wahrscheinlich keinen großen Einfluss auf die Dinge. Wir können dies wahrscheinlich verbessern, indem wir > divstattdessen auf auswählen . calendar.perfplanet.com/2011/…
dougli
Einfach und großartig. Funktioniert perfekt für mich.
Lovro
4

Bestes Ergebnis für mich bisher:

div zentriert werden:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;
Leo Dimuccio
quelle
Arbeitete wie ein Zauber
m4heshd
3

Sie können margin auto verwenden. Mit Flex scheint das Div auch vertikal zentriert zu sein.

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class="site">
  <div class="box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>
Loïc G.
quelle
Anzeige: Flex ist praktisch immer noch ein experimentelles Merkmal; noch kein Browser unterstützt es richtig
andreszs
1

Für mich ist der beste Weg, dies zu tun:

.container{
  position: relative;
}

.element{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Der Vorteil ist, dass die Höhe nicht explizit angegeben werden muss

Leandro Castro
quelle
0

Dies ist meine großartige Lösung für eine divmit einer dynamischen (prozentualen) Höhe.

CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

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

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

HTML

<div class="footer">
    <div class="vertical_placer">
        <div class="inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

Versuchen Sie es selbst.

user3432605
quelle
0

Sie können eine flexible Anzeige wie den folgenden Code verwenden:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class="example">
    <h6>Some text</h6>
</div>

Hassan Yousefi
quelle