Dlaczego wyrównanie w pionie: środek nie działa na mojej rozpiętości lub div?

247

Próbuję wyśrodkować pionowo element spanlub divelement w innym divelemencie. Jednak kiedy mówię vertical-align: middle, nic się nie dzieje. Próbowałem zmienić displaywłaściwości obu elementów i wydaje się, że nic nie działa.

Oto, co aktualnie robię na mojej stronie internetowej:

.main {
  height: 72px;
  vertical-align: middle;
  border: 1px solid black;
  padding: 2px;
}
    
.inner {
  vertical-align: middle;
  border: 1px solid red;    
}
    
.second {
  border: 1px solid blue; 
}
<div class="main">
  <div class="inner">
    This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Oto jsfiddle implementacji pokazujący, że nie działa: http://jsfiddle.net/gZXWC/

Ćwiek
źródło

Odpowiedzi:

207

Wydaje się, że to najlepszy sposób - minęło trochę czasu od mojego oryginalnego postu i teraz należy to zrobić: http://jsfiddle.net/m3ykdyds/200

/* CSS file */

.main {
    display: table;
}

.inner {
    border: 1px solid #000000;
    display: table-cell;
    vertical-align: middle;
}

/* HTML File */
<div class="main">
    <div class="inner"> This </div>
</div>
Charles Addis
źródło
2
Jak więc ktoś robi to, co chce OP?
Ryan Mortensen
Wszelkie pomysły na akapity o zmiennej linii? to znaczy. jeśli nie ma możliwości dowiedzenia się, czy będzie to jedna czy dwie linie. Czy potrzebowałbym wtedy użytkownika jQuery?
foochow
Co jeśli wysokość musi być dynamiczna, jakie jest rozwiązanie?
Murhaf Sousli
nie powinna być zaakceptowaną odpowiedzią, opiera się na znajomości wysokości „.inner”, więc nie do końca to, o co prosił PO, i kilka znacznie lepszych odpowiedzi poniżej, patrz @timbergus lub odpowiedzi Tima Perkinsa na dole.
mike-source
@ mike-source wiedząc, że wysokość wewnętrzna jest w 100% możliwa, nawet jeśli wysokość jest dynamiczna, ponieważ odrobina javascript może to ustalić i dynamicznie zmienić regułę CSS dla tego obiektu DOM.
Charles Addis
143

Za pomocą CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

.outer {
  display : flex;
  align-items : center;
  justify-content: center;
}

Uwaga: To może nie działać w starych IE

użytkownik1782556
źródło
16
Obsługują to wszystkie główne nowoczesne przeglądarki oraz najprostsze i najczystsze rozwiązanie.
Sam
2
Pamiętaj również, inline-flexaby mieć wiele elementów w rzędzie wewnątrz elementu wewnętrznego.
Dan Nissenbaum
1
W moim przypadku, ponieważ chciałem wyśrodkować zawartość .inner również poziomo, musiałem dodać .inner { width: 100%; }. W ten sposób wydaje się, że działa podobnie, .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }ale nie wymusza minimalnej szerokości.
Bart S
Kiedyś justify-content: center;wyrównywałem poziomo, co działało świetnie
Ruth Young,
140

Wypróbuj to, działa dla mnie bardzo dobrze:

/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;

/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;

/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;

/* W3C */
display:box;
box-pack:center;
box-align:center;
Mahendra Liya
źródło
4
doskonała odpowiedź, dało mi to w pełni działające rozwiązanie, które nie spowodowało innych problemów z domieszką (aplikacja korzystająca z jquerymobile + phonegap i wszystkie inne rozwiązania doprowadziły do ​​problemów z rozmiarami css i div). Wystarczy zaznaczyć, że parametry te należy dodać do bloku CSS specyficznego dla elementów, które mają być wyśrodkowane / wyśrodkowane, np .: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- zwróć uwagę, że wysokość jest ważna, aby upewnić się, że rozpiętość dziedziczy pełną wysokość kontenera (prawdopodobnie div) w przeciwnym razie nadal nie uzyskasz centrowania pionowego!
Andy Lorenz
BTW, możesz napisać standardowy kod Flexbox bez prefiksów przeglądarki, a następnie uzyskać prefiks przeglądarki za pomocą autoprefixera github.com/postcss/autoprefixer lub poprzez demo online simevidas.jsbin.com/gufoko/quiet
starikovs
2
niepoprawna wartość nieruchomości boxwdisplay
Joaquinglezsantos
Również odpowiedź @ user1782556 działa lepiej, gdy zewnętrzne pudełko ma wypełnienie.
iautomation
34

Działa również ustawienie wysokości linii na tej samej wysokości, co zawiera div

DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}
Kevin Lynch
źródło
1
Zamieściłem również link wyjaśniający tę metodę. Nie jest to jednak moja preferowana metoda, jeśli reszta układu nie ma ustalonego rozmiaru - przy tej metodzie napotkałem problemy na rzutniach o różnych rozmiarach.
Charles Addis
2
tak, technika wysokości linii działa dobrze, ale TYLKO JEŚLI masz zawartość jednowierszową. Dodatkowe linie zostaną utracone / wyleją się poza pojemnik i musisz zacząć od nowa!
Andy Lorenz
a) line-heightzmieni również wysokość elementu wewnętrznego. b) Element wewnętrzny nadal nie jest dokładnie wyśrodkowany pionowo. c) Nie działa na elementach, które nie zawierają tekstu, na przykład: <img>lub elementach o stałej wysokości.
Alph.Dev,
Może również zawieść w różnych systemach operacyjnych (Windows / Mac) z powodu różnic w renderowaniu czcionek
LocalPCGuy
1
Jest to bardzo nieprzewidywalne i często powoduje dodatkową wysokość pojemnika.
Nieuwaga
25

Jeśli nie możesz polegać na Flexbox ... Umieść go .childw .parentśrodku. Działa, gdy rozmiary pikseli są nieznane (innymi słowy zawsze) i nie ma również problemów z IE9 +.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>

kornieff
źródło
To właściwie najlepiej zrobione rozwiązanie, zwłaszcza że większość projektów, które widziałem do tej pory, wymaga zgodności z IE9
Jabberwocky,
21

Powinieneś założyć vertical-align: middleelement wewnętrzny, a nie element zewnętrzny. Ustaw line-heightwłaściwość na elemencie zewnętrznym, aby pasowała do heightwłaściwości elementu zewnętrznego. Następnie ustaw display: inline-blocki line-height: normalna elemencie wewnętrznym. W ten sposób tekst na elemencie wewnętrznym zostanie zawinięty z normalną wysokością linii. Działa w Chrome, Firefox, Safari i IE 8+

.main {
    height: 72px;
    line-height:72px;
    border: 1px solid black;
}
.inner {
    display: inline-block;
    vertical-align: middle;
    line-height: normal;
}
<div class="main">
    <div class="inner">Vertically centered text</div>
</div>

Skrzypce

Tim Perkins
źródło
Jest to prawdopodobnie najprostszy sposób ... wszystkie inne odpowiedzi na tej stronie są niepotrzebnie niezgrabne / hacky LUB nie są obsługiwane w starszych przeglądarkach LUB polegają na znajomości wysokości elementu wewnętrznego. Tak naprawdę nie potrzebujesz line-height: normal;i display:inline;też działa. Zaletą tej metody jest to, że nie przeszkadza, z text-align:center;którym używanie display: table-cell;może powodować problemy. Dość często chcemy wyrównywać zarówno poziomo, jak i pionowo. Zobacz to zredagowane skrzypce: jsfiddle.net/br090prs/36
mike-source
2
@ mike-source powód do użycia line-height: normali display: inline-blockjest tak, że tekst wewnętrzny zawinie się poprawnie. Jeśli masz pewność, że tekst w wewnętrznej div nigdy się nie zawinie, to te właściwości nie będą konieczne.
Tim Perkins
Odkąd Microsoft zakończył obsługę starszych wersji IE , korzystałem z Flexboksa do tego typu rzeczy (jak sugerował @ user1782556). Moja oryginalna odpowiedź jest odpowiednia, jeśli nadal potrzebujesz obsługi IE 10 lub starszej wersji.
Tim Perkins
Zgadzam się w 100%, ale osobiście nie zdecydowałbym się jeszcze na flex box, tylko 76% przeglądarek obsługuje go w pełni od maja 2016 r. (94%, jeśli włączysz częściowe wsparcie), patrz: caniuse.com/#search=flast% 20box . Zbliża się jednak do bycia najbardziej sensowną opcją, w zależności od bazy użytkowników.
mike-source
10

Użyłem tego, aby wyrównać wszystko na środku div otoki opakowania, na wypadek, gdyby komukolwiek to pomogło - uznałem to za najprostsze:

div.wrapper {
  /* --- This works --- */
  display: flex;
  /* Align Vertically */
  align-items: center;
  /* Align Horizontally */
  justify-content: center;
  /* --- ---------- ----- */
  width: 100%;
  height:100px;
  background-color: blue;
}
div.inner {
  width: 50px;
  height: 50px;
  background-color: orange;
}
<div class="wrapper">
  <div class="inner">
  </div>
</div>

Ruth Young
źródło
7

Oto przykład dwóch sposobów wyrównywania w pionie. Używam ich i działają całkiem dobrze. Jeden wykorzystuje pozycjonowanie bezwzględne, a drugi korzysta z Flexbox .

Przykład wyrównywania w pionie

Używając flexbox, możesz wyrównać element wewnątrz innego elementu za display: flex;pomocą align-self. Jeśli chcesz wyrównać go również w poziomie, możesz użyć align-itemsiw justify-contentpojemniku.

Jeśli nie chcesz używać Flexboksa, możesz użyć właściwości position. Jeśli uczynisz kontener względnym, a zawartość absolutnym, zawartość będzie mogła swobodnie się poruszać wewnątrz kontenera. Więc jeśli użyjesz top: 0;i left: 0;w treści, zostanie ona umieszczona w lewym górnym rogu kontenera.

Bezwzględne pozycjonowanie

Następnie, aby go wyrównać, wystarczy zmienić górne i lewe odniesienia na 50%. Spowoduje to umieszczenie zawartości w centrum kontenera od lewego górnego rogu zawartości.

Wyrównaj na środku pojemnika

Musisz to poprawić, tłumacząc zawartość o połowę mniejszą w lewo i górę.

Absolutnie wyśrodkowany

Timbergus
źródło
5

tutaj jest świetny artykuł o tym, jak wyrównać wertykalnie .. Podoba mi się pływak.

http://www.vanseodesign.com/css/vertical-centering/

HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

I odpowiedni styl:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}
Dory Zidon
źródło
3
Myślę, że jeśli zdefiniujesz wysokość #wewnętrznego bloku, to unieważni to pojęcie właściwego centrowania pionowego. OPS poprosił, aby był automatyczny, więc wyobrażam sobie, że oznacza to, że wysokość wewnętrznego pudełka nie jest znana w momencie poczęcia.
Alexis Wilke,
5

HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

#myparent {
  display: table;
}
#mychild {
  display: table-cell;
  vertical-align: middle;
}

Ustawiamy div rodzica, aby wyświetlał się jako tabela, a div potomny, aby wyświetlał się jako komórka tabeli. Następnie możemy użyć wyrównania w pionie na div div dziecka i ustawić jego wartość na środkową. Wszystko wewnątrz tego div dziecka będzie wyśrodkowane pionowo.

Brijesh Patel
źródło
4

To proste. Po prostu dodaj display:table-cellw swojej głównej klasie.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Sprawdź to jsfiddle !

RizonBarns
źródło
4

Oto najnowsze najprostsze rozwiązanie - nie musisz niczego zmieniać, po prostu dodaj trzy linie reguł CSS do swojego kontenera div, na którym chcesz się skoncentrować. Uwielbiam Flex Box#LoveFlexBox

.main {
  /* I changed height to 200px to make it easy to see the alignment. */
  height: 200px;
  vertical-align: middle;
  border: 1px solid #000000;
  padding: 2px;
  
  /* Just add the following three rules to the container of which you want to center at. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* This is true vertical center, no math needed. */
}
.inner {
  border: 1px solid #000000;
}
.second {
  border: 1px solid #000000;
}
<div class="main">
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Premia

justify-contentwartość można ustawić w kilku następujących opcji:

  • flex-start, która wyrówna div div do miejsca, w którym rozpoczyna się przepływ flex w jego kontenerze nadrzędnym. W takim przypadku pozostanie na wierzchu.

  • center, który wyrówna div dziecka do środka kontenera nadrzędnego. To jest naprawdę fajne, ponieważ nie trzeba dodawać dodatkowego div, aby owinąć wszystkie dzieci, aby umieścić opakowanie w pojemniku nadrzędnym, aby wyśrodkować dzieci. Z tego powodu jest to prawdą centrum pionowe (w column flex-direction. Podobnie, jeśli zmienisz flow-directionsię row, że staną się poziomo wycentrowany.

  • flex-end, który wyrówna div div do miejsca, w którym Flex Flex kończy się w jego kontenerze nadrzędnym. W takim przypadku przesunie się na dół.

  • space-between, który rozprzestrzeni wszystkie dzieci od początku przepływu do końca przepływu. Jeśli to demo, dodałem kolejny div div, aby pokazać, że są one rozłożone.

  • space-around, podobnie jak space-between, ale z połową miejsca na początku i na końcu przepływu.

Downhillski
źródło
Idealne rozwiązanie. Niezgodne przeglądarki mogą sprawić, że treść nie będzie wyrównywana, a użytkownik musi sobie z tym poradzić lub zaktualizować swoją przeglądarkę.
twicejr
0

Ponieważ vertical-aligndziała zgodnie z oczekiwaniami na td, możesz umieścić jedną komórkę tablew, divaby wyrównać jego zawartość.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Clunky, ale działa, o ile wiem. Może nie mieć wad innych obejść.

Smig
źródło
5
Nie, proszę, już nie stoły. CSS może to zrobić w czysty sposób. W tym przypadku nie ma potrzeby używania <tabela>.
enguerranws
0

Wystarczy umieścić zawartość w tabeli o wysokości 100% i ustawić wysokość dla głównego div

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>
Ramiro Mosquera
źródło
0

Aby pionowo wyśrodkować element przęsła lub elementu div w obrębie innego elementu div, dodaj pozycję względem elementu div elementu nadrzędnego i pozycję absolutną do elementu div elementu podrzędnego. Teraz element div elementu podrzędnego można ustawić w dowolnym miejscu wewnątrz elementu div. Przykład poniżej centruje element poziomo i pionowo.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

css:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
Toki
źródło
0

Jest to nowoczesne podejście i wykorzystuje funkcję CSS Flexbox. Możesz teraz wyrównać zawartość w pionie w kontenerze nadrzędnym, po prostu dodając te style do .mainkontenera

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

I jesteś gotowy, aby iść!

Kingsley Gyimah
źródło