Menggunakan margin: auto untuk meratakan div secara vertikal

113

Jadi saya tahu kita bisa memusatkan div secara horizontal jika kita menggunakannya margin:0 auto;. Sebaiknyamargin:auto auto; bekerja menurut saya seharusnya bekerja? Memusatkan juga secara vertikal?

Mengapa tidak vertical-align:middle;berhasil?

.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

penyelamat
sumber
1
Sangat disarankan untuk membaca dan mengimplementasikan jawaban @ zpr di bawah ini terkait dengan Flexbox. Ini cukup didukung dengan baik pada hari ini dan css Anda akan jauh lebih bersih.
Govind Rai
jika ((Tanggal baru ()). getFullYear ()> 2017) useFlexBox = true;
Brandito

Jawaban:

173

Perbarui Agustus 2020

Meskipun di bawah ini masih layak dibaca untuk info berguna, kami telah memiliki Flexbox untuk beberapa waktu sekarang, jadi gunakan saja, sesuai jawaban ini .


Anda tidak dapat menggunakan:

vertical-align:middlekarena itu tidak berlaku untuk elemen level blok

margin-top:autodan margin-bottom:autokarena nilai yang digunakan akan dihitung sebagai nol

margin-top:-50%karena nilai margin berbasis persentase dihitung relatif terhadap lebar blok penampung

Sebenarnya, sifat dari aliran dokumen dan algoritma penghitungan ketinggian elemen membuat tidak mungkin menggunakan margin untuk memusatkan elemen secara vertikal di dalam induknya. Setiap kali nilai margin vertikal diubah, itu akan memicu penghitungan ulang tinggi elemen induk (aliran ulang), yang pada gilirannya akan memicu pusat kembali elemen asli ... menjadikannya pengulangan tak terbatas.

Kamu bisa memakai:

Beberapa solusi seperti ini yang sesuai untuk skenario Anda; ketiga elemen tersebut harus bersarang seperti ini:

.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 berfungsi dengan baik menurut .

ov
sumber
10
#adalah hack yang aturannya diawali dengan itu hanya ditafsirkan oleh IE7 dan di bawahnya. Anda mungkin lebih suka memasukkan aturan ini ke dalam lembar gaya khusus IE dengan menggunakan komentar bersyarat, dll.
ov
2
1 untuk mengutip alasan mengapa hal ini terjadi, perhitungan persentase margin berdasarkan lebarnya sangat membuka mata.
ricosrealm
2
Saya ragu tentang pernyataan 'putaran tak terbatas'.
Barun
105
Umat ​​manusia telah pergi ke bulan bertahun-tahun yang lalu dan kita masih harus berurusan dengan omong kosong ini. menyelaraskan hal-hal secara vertikal di browser, yesus
user151496
3
Dalam usia> = IE9, position: absolute; top: 50%; transform: translateY(-50%);juga layak dan cukup populer ... (tidak seperti top:50%;margin: - $halfHeightAnda tidak perlu mengetahui ketinggian sebelumnya ...)
Frank Nocke
112

Karena pertanyaan ini ditanyakan pada tahun 2012 dan kami telah berkembang pesat dengan dukungan browser untuk flexboxes, saya merasa jawaban ini wajib.

Jika tampilan penampung induk Anda adalah flex, maka yes , margin: auto auto(juga dikenal sebagai margin: auto) akan bekerja untuk memusatkannya baik secara horizontal maupun vertikal, terlepas dari apakah itu elemen inlineatau block.

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

Perhatikan bahwa lebar / tinggi tidak harus ditentukan secara mutlak, seperti dalam contoh ini jfiddle yang menggunakan ukuran relatif terhadap viewport.

Meskipun dukungan browser untuk flexboxes selalu tinggi pada saat posting, banyak browser masih tidak mendukungnya atau membutuhkan prefiks vendor. Lihat http://caniuse.com/flexbox untuk informasi dukungan browser terbaru.

Memperbarui

Karena jawaban ini mendapat sedikit perhatian, saya juga ingin menunjukkan bahwa Anda tidak perlu menentukan marginsama sekali jika Anda menggunakan display: flexdan ingin memusatkan semua elemen dalam wadah:

#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
sumber
4
induk {display: flex; } anak {margin: auto 0; } cukup bagus.
Arek Kostrzeba
OMG bung, kamu adalah seorang rockstar, sialan aku tidak bisa memberi suara lebih dari sekali !!!
PirateApp
Ini jawaban yang bagus ketika Anda mungkin juga bingung dengan masalah konten yang sesuai. Dengan menyetel flex pada container, div konten tidak memerlukan properti apa pun untuk disetel.
Eric
1
Sejauh ini, ini adalah solusi terbaik dan elegan untuk bekerja di tahun 2018, terima kasih.
SilverSurfer
Saya ingin menambahkan bahwa, mulai Mei 2018, dengan solusi ini, teks tidak sejajar vertikal di tengah di IE 11.
Yefu
62

Inilah solusi terbaik yang saya temukan: http://jsfiddle.net/yWnZ2/446/ Bekerja di Chrome, Firefox, Safari, IE8-11 & Edge.

Jika Anda telah dideklarasikan height( height: 1em, height: 50%, dll) atau itu merupakan elemen mana browser tahu ketinggian ( img, svg, atau canvasmisalnya), maka semua yang Anda butuhkan untuk centering vertikal adalah ini:

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

Anda biasanya ingin menentukan satu widthatau max-widthlebih konten tidak meregangkan seluruh panjang layar / wadah.

Jika Anda menggunakan ini untuk modal yang Anda inginkan selalu berpusat di area pandang yang tumpang tindih dengan konten lain, gunakan position: fixed;untuk kedua elemen, bukan position: absolute. http://jsfiddle.net/yWnZ2/445/

Berikut artikel yang lebih lengkap: http://codepen.io/shshaw/pen/gEiDt

shshaw
sumber
3
Ini tidak perlu memusatkannya di elemen induknya. Retas bagus jika Anda hanya menginginkannya di tengah halaman.
Joel Mellon
2
Cukup tambahkan position: relativeke induk, dan elemen akan dipusatkan di dalam induk. Saya membuat artikel yang jauh lebih besar di Smashing Magazine tentang teknik ini jika Anda ingin membaca lebih lanjut: coding.smashingmagazine.com/2013/08/09/…
shshaw
Terkadang absolut didasarkan pada satu atau dua orang tua (vs tubuh) dan kerabat dapat menjadi kakek atau nenek buyut (vs orang tua). Mungkin mereka yang tahu kapan atau mengapa hal itu terjadi dapat mengontrol teknik ini dengan lebih baik - saya tidak pernah benar-benar melihat masalah itu, tetapi saya tahu bahwa beralih dari absolut ke relatif bukanlah solusi untuk membuat ini berfungsi. Saya membaca sedikit artikel Anda dan sepertinya absolut dan relatif naik ke leluhur absolut atau relatif pertama, apakah itu benar?
Joel Mellon
Aku sedikit lamban. Saya baru saja membaca kembali komentar Anda di atas. Saya tidak melihat Anda mengatakan untuk menambahkannya ke parent- mengerti. Terima kasih banyak!
Joel Mellon
1
@commonpike Satu-satunya masalah dengan IE8 / 9 adalah jika Anda menggunakan display: tableuntuk konten tinggi variabel. Jika tidak, metode ini akan berfungsi seperti yang diharapkan. Baca melalui Langgan untuk rincian lebih lanjut secara keseluruhan. Anda juga harus dapat menguji tampilan penuh di IE8 / 9 untuk melihat apakah ada masalah.
shshaw
22

Sunting: ini tahun 2020, saya akan menggunakan kotak fleksibel sebagai gantinya.

Jawaban asli:

Html

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

CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Gal Margalit
sumber
tidak akan berfungsi untuk IE 8 dan versi yang lebih lama dari yaitu. Karena transform properyty didukung (dengan awalan -ms-) dari versi 9.0 dan yang lebih baru. (mis. 10 tidak perlu awalan lagi).
DevWL
5
Benar, saya tidak peduli tentang IE8
Gal Margalit
Dan penulis memberi tag html5 untuk pertanyaannya ☺
Gal Margalit
9

Saya tahu pertanyaannya berasal dari tahun 2012, tetapi saya menemukan cara termudah yang pernah ada, dan saya ingin berbagi.

HTML:

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

dan CSS:

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

Jika Anda mengetahui tinggi div yang ingin dipusatkan , Anda dapat memposisikannya secara absolut di dalam induknya lalu menyetel topnilainya ke 50%. Itu akan menempatkan bagian atas div anak 50% dari jalan ke bawah induknya, yaitu terlalu rendah. Tarik kembali dengan mengaturnyamargin-top setengah tingginya. Jadi sekarang Anda memiliki titik tengah vertikal div turunan yang berada di titik tengah vertikal induk - berpusat secara vertikal!

Contoh:

.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/

tufa
sumber
1
margin-toptidak dapat disetel dalam% relatif terhadap tinggi elemen, jadi Anda akan mendapatkan penetapan tergantung dimensi
ov
1
Yang mana ... persis seperti yang saya katakan dalam jawaban saya? "Jika Anda tahu ketinggian div yang ingin Anda pusatkan". Dan saya tidak mengatakan bahwa OP harus menggunakan% dalam margin-top.
tuff
Saya tidak setuju dengan solusinya karena itu mengunci Anda ke ketinggian elemen yang telah ditentukan sebelumnya - tetapi komentar Anda masuk akal. Anda mungkin ingin merefleksikannya dalam jawaban
ov
3
Oke, saya telah menebalkan bagian yang Anda abaikan, semoga itu lebih jelas sekarang.
tuff
1
@ov: Jika elemen tidak memiliki tinggi tetap, Anda bisa menggunakan JS untuk mendapatkan tinggi yang dihitung dan kemudian menyetel margin atas negatif yang sesuai. Ini masih merupakan metode terbaik untuk pemusatan vertikal, menurut saya.
daGUY
3

Kedua solusi tersebut hanya membutuhkan dua elemen bersarang.
Pertama - Pemosisian relatif dan absolut jika kontennya statis (tengah manual).

.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/

atau untuk desain yang lancar - untuk penggunaan pusat konten yang tepat seperti contoh di bawah ini:

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

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

Anda perlu menyetel 'min-height' jika konten melebihi 50% dari tinggi jendela. Anda juga dapat memanipulasi ketinggian ini dengan kueri media untuk perangkat seluler dan tablet. Namun hanya jika Anda bermain dengan desain responsif.

Saya kira Anda bisa melangkah lebih jauh dan menggunakan skrip JavaScript / JQuery sederhana untuk memanipulasi min-height atau fixed height jika ada kebutuhan karena alasan tertentu.

Kedua - jika konten dapat mengalir, Anda juga dapat menggunakan properti css tabel dan sel tabel dengan perataan vertikal dan rata tengah teks:

/*in a wrapper*/  
display:table;   

dan

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

Berfungsi dan menskalakan dengan sempurna, sering digunakan sebagai solusi desain web responsif dengan tata letak kisi dan kueri media yang memanipulasi lebar objek.

.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/

Saya lebih suka solusi tabel untuk pemusatan konten yang tepat, tetapi dalam beberapa kasus, pemosisian relatif absolut akan melakukan pekerjaan yang lebih baik terutama jika kita tidak ingin mempertahankan proporsi yang tepat dari penyelarasan konten.

DevWL
sumber
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
sumber
Bisakah Anda berbagi dengan kami, tentang bagaimana solusi ini? Plus, saya melihat "pesan popup" Anda di bagian bawah bukan di tengah
Alex
Saya memang melewatkan sesuatu, tetapi sekarang lebih baik untuk menjaga div di tengah secara vertikal. Anda dapat memeriksanya sekarang.
Seetpal singh
0

Tidak ada satu cara mudah untuk memusatkan div secara vertikal yang akan melakukan trik dalam setiap situasi.

Namun, ada banyak cara untuk melakukannya tergantung situasinya.

Berikut ini beberapa di antaranya:

  • Setel padding atas dan bawah dari elemen induk misalnya padding: 20px 0px 20px 0px
  • Gunakan tabel, sel tabel memusatkan isinya secara vertikal
  • Tetapkan posisi elemen induk relatif dan div yang ingin Anda pusatkan secara vertikal ke absolut dan beri gaya sebagai top: 50px; bawah: 50px; sebagai contoh

Anda juga dapat menggunakan Google untuk "pemusatan vertikal css"

hasu
sumber
0

tinggi variabel, margin atas dan bawah otomatis

.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>

tinggi variabel, margin atas dan bawah otomatis

pengguna3668456
sumber
0

Menggunakan 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 */
}

Lihat hasil

DanielBlazquez
sumber
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
sumber