Bagaimana cara memusatkan konten secara vertikal dengan tinggi variabel dalam div?

158

Apa cara terbaik untuk memusatkan konten div secara vertikal saat ketinggian konten bervariasi. Dalam kasus khusus saya, ketinggian div wadah tetap, tetapi akan lebih bagus jika ada solusi yang akan bekerja dalam kasus-kasus di mana wadah memiliki ketinggian variabel juga. Juga, saya akan menyukai solusi tanpa, atau menggunakan sangat sedikit peretasan CSS dan / atau markup non-semantik.

teks alternatif

jessegavin
sumber
metode dalam artikel tersebut berantakan di Safari (4.0.5): S
7
@ ripper234 Tidak persis, karena pertanyaan ini adalah tentang div ketinggian variabel
Rauli Rajande
9
Juga, pertanyaan ini ditanyakan terlebih dahulu.
Gui Imamura

Jawaban:

147

Cukup tambahkan

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

ke div batin.

Apa yang dilakukannya adalah memindahkan batas atas div dalam ke setengah ketinggian div luar ( top: 50%;) dan kemudian div dalam naik setengah tingginya ( transform: translateY(-50%)). Ini akan bekerja dengan position: absoluteatau relative.

Perlu diingat bahwa transformdan translatememiliki awalan vendor yang tidak termasuk untuk kesederhanaan.

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

BlackCetha
sumber
6
Hanya ingin tahu mengapa ini bekerja di Chrome dan Firefox, tetapi tidak untuk Safari. Lalu saya perhatikan bahwa sebagian besar transformhal terkait -webkit-diawali dan sekarang berfungsi. Jadi hanya sebagai pengingat: Jangan lupa untuk menambahkan -webkit-awalan juga.
miho
5
Gunakan alat seperti github.com/postcss/autoprefixer untuk menangani awalan untuk Anda.
Jamie Chong
6
Jawaban ini harus di atas.
Jose Faeti
3
Ini seharusnya memiliki lebih banyak suara positif! Ngomong-ngomong, itu juga bekerja dengan baik position: absolute, bukan?
gak
4
Metode ini memiliki efek samping yang tidak menguntungkan di Chrome - jika pembungkus Anda memiliki jumlah piksel ganjil maka translateakan membuat semuanya buram saat mencoba menangani ketinggian .5px pada semuanya.
Keith
157

Ini tampaknya menjadi solusi terbaik yang saya temukan untuk masalah ini, selama browser Anda mendukung ::beforeelemen pseudo: CSS-Trik: Pemusatan di Unknown .

Tidak memerlukan markup tambahan dan tampaknya berfungsi dengan sangat baik. Saya tidak bisa menggunakan display: tablemetode ini karena tableelemen tidak mematuhi max-heightproperti.

.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
sumber
3
Sekarang -yang- adalah solusi -BRILLIANT-. Terima kasih banyak telah memposting ini!
Troy Alford
Seperti jawaban yang lain, jawaban ini akan jauh lebih baik jika menggambarkan pendekatan dan menyertakan kode dari tautan.
KatieK
3
+1, solusi ini sangat cerdik! Btw Anda bisa menambahkan .block { white-space: nowrap; font-size: 0; line-height: 0; }dan meninggalkan margin kanan negatif pada elemen pseudo, Anda hanya perlu mengatur ulang fs dan lh di .centered ... seperti ini Anda memastikan bahwa elemen akan diposisikan dengan benar bahkan jika itu lebih lebar dari viewport (dan tidak harus menggunakan imo margin negatif agak berantakan).
Simon
@jessegavin - menurut pendapat Anda ... bagaimana cara berikut ini bertentangan dengan pendekatan yang telah Anda uraikan: stackoverflow.com/questions/396145/…
pulkitsinghal
1
Juga, ini rusak ketika wadah luar .block memiliki ketinggian min, bukan tinggi.
Lincoln B
16

Ini adalah sesuatu yang perlu saya lakukan berkali-kali dan solusi yang konsisten masih mengharuskan Anda menambahkan markup non-semantik dan beberapa peretas khusus peramban. Ketika kami mendapatkan dukungan browser untuk css 3, Anda akan mendapatkan pemusatan vertikal tanpa dosa.

Untuk penjelasan teknik yang lebih baik, Anda dapat melihat artikel yang saya adaptasi , tetapi pada dasarnya melibatkan penambahan elemen tambahan dan menerapkan gaya yang berbeda di IE dan browser yang mendukung position:table\table-cellelemen non-tabel.

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

Ada banyak cara (retasan) untuk menerapkan gaya pada set browser tertentu. Saya menggunakan komentar kondisional tetapi melihat artikel yang terhubung di atas untuk melihat dua teknik lainnya.

Catatan: Ada cara sederhana untuk mendapatkan pemusatan vertikal jika Anda mengetahui ketinggian sebelumnya, jika Anda mencoba memusatkan satu baris teks, atau dalam beberapa kasus lainnya. Jika Anda memiliki perincian lebih lanjut, masukkan saja karena mungkin ada metode yang tidak memerlukan peramban peramban atau markup non-semantik.

Pembaruan: Kami mulai mendapatkan dukungan browser yang lebih baik untuk CSS3, menjadikan flex-box dan transformasi sebagai metode alternatif untuk mendapatkan pemusatan vertikal (di antara efek lainnya). Lihat pertanyaan lain ini untuk informasi lebih lanjut tentang metode modern, tetapi perlu diingat bahwa dukungan browser masih samar untuk CSS3.

Prestaul
sumber
Ya, saya menemukan artikel itu hari ini dan belum dapat membuatnya berfungsi untuk situasi khusus saya. Mungkin saya perlu melihat lebih jauh.
jessegavin
Mungkin Anda dapat memposting kode yang Anda gunakan yang tidak berfungsi?
Chris Marasti-Georg
Apakah ini masih solusi terbaik untuk masalah ini?
ripper234
Artikel itu sepertinya tidak berfungsi di Chrome 23, Firefox 16 dan IE 9. Jawaban ini tampaknya menjadi solusi yang lebih baik.
Fernando Correia
Tidak, artikel itu masih TIDAK berfungsi di Chrome dan Firefox terbaru pada 24 Februari 2013
OMA
9

Menggunakan pemilih anak, saya telah mengambil jawaban Fadi yang luar biasa di atas dan mengubahnya menjadi hanya satu aturan CSS yang dapat saya terapkan. Sekarang yang harus saya lakukan adalah menambahkan contentCenterednama kelas ke elemen yang saya ingin pusatkan:

.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
sumber
Keren. Terima kasih telah berbagi. Satu catatan kehati-hatian adalah bahwa *pemilih akan berkinerja lebih buruk daripada jawaban yang diterima. Mungkin tidak menjadi masalah, tetapi patut dicatat. stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin
Terima kasih. Ya, itu mungkin akan berkinerja lebih buruk, tetapi saat ini aturan CSS mungkin tidak terlalu memengaruhi banyak hal. Kami mungkin dapat meningkatkan ini dengan memilih pada > divsebagai gantinya. calendar.perfplanet.com/2011/…
dougli
Sederhana dan hebat. Bekerja untuk saya dengan sempurna.
Lovro
4

Hasil terbaik untuk saya sejauh ini:

div untuk dipusatkan:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;
Leo Dimuccio
sumber
Bekerja seperti pesona
m4heshd
3

Anda dapat menggunakan margin otomatis. Dengan flex, div juga tampaknya terpusat secara vertikal.

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.
sumber
display: flex praktis masih merupakan fitur eksperimental; belum ada browser yang
mendukungnya
1

Bagi saya cara terbaik untuk melakukan ini adalah:

.container{
  position: relative;
}

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

Keuntungannya adalah tidak harus membuat ketinggian eksplisit

Leandro Castro
sumber
0

Ini adalah solusi luar biasa saya untuk divyang dinamis (persentase) tinggi.

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>  

Coba ini sendiri.

pengguna3432605
sumber
0

Anda dapat menggunakan tampilan fleksibel seperti kode di bawah ini:

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