Bir div içinde değişken yükseklikte içerik dikey olarak nasıl ortalanır?


158

İçeriğin yüksekliği değişken olduğunda div içeriğini dikey olarak ortalamanın en iyi yolu nedir? Benim özel durumumda, konteyner divinin yüksekliği sabittir, ancak kabın da değişken bir yüksekliğe sahip olduğu durumlarda işe yarayacak bir çözüm olsaydı harika olurdu. Ayrıca, CSS kesmek ve / veya semantik olmayan işaretleme kullanmamak veya çok az kullanmak isteyen bir çözümü çok isterim.

alternatif metin


bu makaledeki yöntem Safari'de (4.0.5)

7
@ ripper234 Tam olarak, bu soru değişken yükseklik div hakkında olduğu için
Rauli Rajande

9
Ayrıca, önce bu soru soruldu.
Gui Imamura

Yanıtlar:


147

Sadece ekle

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

iç div.

Yaptığı şey, iç div'in üst kenarlığını dış div ( top: 50%;) ' nin yarı yüksekliğine ve daha sonra iç div'in yüksekliğinin yarısı kadar ( transform: translateY(-50%)) hareket ettirilmesidir . Bu position: absoluteveya ile çalışır relative.

Unutmayın transformve translatebasitlik için dahil edilmeyen satıcı ön eklerine sahip olun.

Kod kalemi: http://codepen.io/anon/pen/ZYprdb


6
Bunun neden Chrome ve Firefox'ta çalıştığını, ancak Safari için çalışmadığını merak ettim. Sonra en transformalakalı şeylerin -webkit-ön ekinin geldiğini ve şimdi işe yaradığını fark ettim . Bir hatırlatma olarak: -webkit-Öneki de eklemeyi unutmayın .
miho

5
Sizin için önekleri işlemek için github.com/postcss/autoprefixer gibi bir araç kullanın .
Jamie Chong

6
Bu cevap en üstte olmalıdır.
Jose Faeti

3
Bu çok daha fazla oy olmalı! Bu arada, aynı zamanda çalışıyor position: absolute, değil mi?
gak

4
Bu yöntemin Chrome'da talihsiz bir yan etkisi vardır - paketleyicinizde tek sayıda piksel varsa translate, her şeyde .5px yüksekliğini işlemeye çalışırken her şeyi bulanık bir şekilde oluşturur.
Keith

157

Tarayıcınız ::beforesözde öğeyi desteklediği sürece bu soruna bulduğum en iyi çözüm gibi görünüyor : CSS-Tricks: Bilinmeyende Merkezleme .

Herhangi bir ekstra işaretleme gerektirmez ve son derece iyi çalışıyor gibi görünüyor. display: tableMetodu kullanamadım çünkü tableelemanlar max-heightmülkiyete uymuyor .

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


3
Şimdi -bu- bir -BRILLIANT- çözümü. Bunu gönderdiğin için çok teşekkürler!
Troy Alford

Diğer cevapta olduğu gibi, bu yaklaşımı açıklar ve bağlantıdan kod eklerse çok daha iyi olurdu.
KatieK

3
+1, Bu çözüm gerçekten oldukça dahice! Btw .block { white-space: nowrap; font-size: 0; line-height: 0; }, sözde öğeye negatif sağ kenar boşluğunu ekleyebilir ve bırakabilirsiniz, sadece fs ve lh'yi .centered üzerinde sıfırlamanız gerekir ... bunun gibi, öğenin görünüm penceresinden daha geniş olsa bile doğru konumlandırılmasını sağlarsınız (ve don imo'yu biraz dağınık negatif marj kullanmak zorunda değilsiniz).
Simon

@jessegavin - sizce ... Ana hatlarıyla belirlediğiniz yaklaşıma karşı aşağıdakiler nasıl
toplanır

1
Ayrıca, dış kap .block yüksekliği yerine minimum yüksekliğe sahip olduğunda bu parçalanır.
Lincoln B

16

Bu, birçok kez yapmam gereken bir şeydir ve tutarlı bir çözüm hala semantik olmayan bir işaretleme ve bazı tarayıcıya özgü kesmek eklemenizi gerektirir. Css 3 için tarayıcı desteği aldığımızda, günah işlemeden dikey merkezlemenizi alırsınız.

Tekniğin daha iyi bir açıklaması için, onu uyarladığım makaleye bakabilirsiniz , ancak temel olarak, ekstra bir öğe eklemeyi ve IE'de ve position:table\table-celltablo olmayan öğeler üzerinde destekleyen tarayıcılarda farklı stiller uygulamayı içerir .

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

Belirli tarayıcı gruplarına stil uygulamak için birçok yol (kesmek) vardır. Koşullu yorumlar kullandım, ancak diğer iki tekniği görmek için yukarıda bağlantılı makaleye bakın.

Not: Önceden bazı yükseklikleri biliyorsanız, tek bir metin satırını ortalamaya çalışıyorsanız veya diğer bazı durumlarda dikey merkezleme almanın basit yolları vardır. Daha fazla ayrıntıya sahipseniz, tarayıcı saldırıları veya semantik olmayan işaretleme gerektirmeyen bir yöntem olabileceğinden bunları atın.

Güncelleme: CSS3 için daha iyi tarayıcı desteği almaya başlıyoruz, hem dikey kutuyu hem de dönüşümleri dikey merkezleme (diğer efektlerin yanı sıra) almak için alternatif yöntemler olarak getiriyor. Modern yöntemler hakkında daha fazla bilgi için bu diğer soruya bakın , ancak tarayıcı desteğinin CSS3 için hala kabataslak olduğunu unutmayın.


Evet, bugün bu makaleyi buldum ve özel durumum için çalışmasını sağlayamadım. Belki de bu konuya daha fazla bakmalıyım.
jessegavin

Belki kullandığınız kodu işe yaramazsa gönderebilirsiniz?
Chris Marasti-Georg

Bu hala bu sorun için en iyi çözüm mü?
ripper234

Bu makale Chrome 23, Firefox 16 ve IE 9'da çalışmıyor gibi görünüyor. Bu yanıt daha iyi bir çözüm gibi görünüyor.
Fernando Correia

Hayır, bu makale 24 Şubat 2013 itibariyle en son Chrome ve Firefox'ta hala çalışıyor
OMA

9

Çocuk seçiciyi kullanarak, Fadi'nin yukarıdaki inanılmaz cevabını aldım ve uygulayabileceğim sadece bir CSS kuralına indirdim. Şimdi tek yapmam gereken ortalamak contentCenteredistediğim öğelere sınıf adını eklemektir :

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

Çatallı CodePen: http://codepen.io/dougli/pen/Eeysg


Güzel. Paylaşım için teşekkürler. Dikkat edilmesi gereken bir nokta, *seçicinin kabul edilen yanıttan daha kötü performans göstereceğidir. Bir sorun olmayabilir, ama kayda değer. stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin

Teşekkürler. Evet, muhtemelen daha kötü performans gösterecektir, ancak günümüzde CSS kuralları muhtemelen işleri çok fazla etkilemez. > divBunun yerine seçeneğini seçerek bunu muhtemelen geliştirebiliriz . calendar.perfplanet.com/2011/…
dougli

Basit ve harika. Benim için mükemmel çalışıyor.
Lovro

4

Şimdiye kadarki en iyi sonuç:

ortalanacak div:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

Bir cazibe gibi çalıştı
m4heshd

3

Otomatik kenar boşluğu kullanabilirsiniz. Flex ile div de dikey olarak ortalanmış gibi görünüyor.

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>

görüntüleme: flex hala pratik olarak deneysel bir özelliktir; tarayıcı henüz doğru bir şekilde desteklemiyor
andreszs

1

Benim için bunu yapmanın en iyi yolu:

.container{
  position: relative;
}

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

Avantajı yüksekliği açık yapmak zorunda değil


0

Bu, divdinamik (yüzde) yüksekliğe sahip bir a için harika bir çözümdür .

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>  

Bunu kendiniz deneyin.


0

aşağıdaki kodu gibi flex ekran kullanabilirsiniz:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.