Div bloğunu genişlik olmadan ortalama


241

Önceden div genişliğini bilmediğim için div bloğunu "ürünleri" ortalamaya çalıştığımda bir sorunum var. Birinin çözümü olan var mı?

Güncelleme: Sorun, kaç tane ürün göstereceğimi bilmiyorum, 1, 2 veya 3 ürünüm olabilir, ebeveynin genişliğini bildiğim gibi sabit bir sayı olsaydı onları ortalayabilirim div, içerik dinamik olduğunda nasıl yapacağımı bilmiyorum.

.product_container {
  text-align: center;
  height: 150px;
}

.products {
  height: 140px;
  text-align: center;
  margin: 0 auto;
  clear: ccc both; 
}
.price {
  margin: 6px 2px;
  width: 137px;
  color: #666;
  font-size: 14pt;
  font-style: normal;
  border: 1px solid #CCC;
  background-color:	#EFEFEF;
}
<div class="product_container">
  <div class="products" id="products">
    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>   

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>
  </div>
</div>


Yaşadığınız sorun tam olarak nedir?
anand.trex

Yanıtlar:


256

Güncelleme 27 Şub 2015: Orijinal cevabım oylanmaya devam ediyor, ancak şimdi normalde bunun yerine @ bobince'nin yaklaşımını kullanıyorum.

.child { /* This is the item to center... */
  display: inline-block;
}
.parent { /* ...and this is its parent container. */
  text-align: center;
}

Tarihi amaçlar için orijinal gönderim:

Bu yaklaşımı denemek isteyebilirsiniz.

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div class="clear"/>
</div>

Eşleşen stil:

.outer-center {
    float: right;
    right: 50%;
    position: relative;
}
.inner-center {
    float: right;
    right: -50%;
    position: relative;
}
.clear {
    clear: both;
}

JSFiddle

Buradaki fikir, merkezlemek istediğiniz içeriği bir dış ve bir iç olmak üzere iki bölüm halinde içermenizdir. Her iki div öğesini de kaydırırsınız, böylece genişlikleri içeriğinize uyacak şekilde otomatik olarak küçülür. Daha sonra, dış div'i sağ kenarı kabın ortasında olacak şekilde nispeten konumlandırırsınız. Son olarak, iç div'i ters yöne kendi genişliğinin yarısına göre konumlandırırsınız (aslında dış div'in genişliği, ancak aynıdır). Sonuçta, içeriği içinde bulunduğu kapta ortalar.

Sen olabilir Eğer boyuta "ürün" içeriğine "product_container" için yükseklik bağlıysa sonunda bu boş div gerekir.


1
Verdiğiniz daha dont Eğer overflow:hiddeniçin div sağında yakındaki diğer içerikleri üst üste gelecektir. Alışkanlık sağındaki herhangi bir bağlantı veya düğmeler çalışmaz. İhtiyacınızı anlamak için arka plan rengini deneyin . Bu tarafından önerilen bir düzenleme oldu Cicil Thomas.product_containerouter-centerouter-centerouter-centeroverflow :hidden
Benjol

Bu yaklaşım masaüstü web siteleri için mükemmel ... mobil cihazlarda iç div'ler sağa yapışıyor gibi görünüyor. Bir çözüm var mı?
Mich Dart

3
Bana bundan bahset! Bazen sadece bir çözüme ihtiyacımız vardır ve seçim için iyi bir çözüm bulma lüksüne sahip değiliz. Tek hücreli bir tablo başka bir seçenektir, ancak tek hücreli bir tablo gerçekten bir tablo olmasa da, öyle değil mi?
Mike M. Lin

@fgysin Anlaşıldı, bu sezgisel bir saldırı. Ve tasarımcılar insanların neden hala tablo tabanlı düzenlere geri dönmeyi düşündüklerini merak ediyorlar .
Yuck

1
Bu soru beş yaşında. Bu cevap güncel değil, ancak başlamak hiç bu kadar şık olmamıştı. Yapmanız gereken şey display: inline-block
Wray Bowling

140

'Display: block' olan bir öğenin (div varsayılan olarak olduğu gibi) kabının genişliğine göre belirlenen bir genişliğe sahiptir. Bir bloğun genişliğini, içeriğinin genişliğine bağlı hale getiremezsiniz (sığacak şekilde daralt).

(CSS 2.1'de 'kayan: sol / sağ' olan bloklar hariç, ancak bu merkezleme için bir kullanım değildir.)

Bir bloğu üst öğesinin metin hizalama özelliği tarafından kontrol edilebilecek bir sığacak nesneye dönüştürmek için 'display' özelliğini 'inline-block' olarak ayarlayabilirsiniz, ancak tarayıcı desteği sivilceli. Bu şekilde gitmek istiyorsanız, çoğunlukla kesmek kullanarak (örneğin, bkz. -Moz-inline-stack) ondan kurtulabilirsiniz.

Diğer yol ise tablolar. Bu, genişliği gerçekten önceden bilinemeyen sütunlarınız olduğunda gerekli olabilir. Örnek koddan ne yapmaya çalıştığınızı gerçekten söyleyemiyorum - orada daralan bir bloğa ihtiyaç duyacak belirgin bir şey yok - ancak bir ürün listesi muhtemelen tablo olarak kabul edilebilir.

[PS. web'deki yazı tipi boyutları için asla 'pt' kullanmayın. 'px' gerçekten sabit boyutlu metne ihtiyacınız varsa daha güvenilirdir, aksi takdirde '%' gibi göreceli birimler daha iyidir. Ve “açık: her ikisi de ccc” - bir yazım hatası mı?]

.center{
   text-align:center; 
}

.center > div{ /* N.B. child combinators don't work in IE6 or less */
   display:inline-block;
}

JSFiddle


53
ebeveyn -> metin hizalama: merkez |
çocuk-

5
display: inline-blockIE7 ve Firefox'un eski sürümlerinde desteklenmez
Jake Wilson

1
@ Jakobud, IE7 için "display: inline; zoom: 1;" "display: inline-block;" yerine. Blok elemanlar için çalışır.
mihail-haritonov

1
bu yöntemin çapraz tarayıcısının nasıl kullanılacağı hakkında daha fazla bilgi için bu bağlantıya göz atın
blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block

1
Ben html yapısı desteklemek için var olduğu sürece çalışacak uygulamak için bu scss kullandım: .center {text-align: center; &: ilk çocuk {display: satır içi blok; }}
Dovev Hefetz

95

Çoğu tarayıcı display: table;CSS kuralını destekler . text-align: center;İçindeki div için dinamik genişliği korurken, fazladan HTML eklemeden veya kapsayıcıya kısıtlama stilleri uygulamadan (kaptaki diğer tüm satır içi içeriği ortalayacak gibi) bir kapsayıcıda bir div'ı ortalamak için iyi bir hiledir :

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.centered { display: table; margin: 0 auto; }


Güncelleme (2015-03-09):

Bugün bunu yapmanın doğru yolu aslında flexbox kurallarını kullanmaktır. Tarayıcı desteği biraz daha kısıtlıdır ( CSS tablo desteği vs flexbox desteği ), ancak bu yöntem başka birçok şeye de izin verir ve bu tür davranışlar için özel bir CSS kuralıdır:

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: column; /* put this if you want to stack elements vertically */
}
.centered { margin: 0 auto; }


11
Bence bu kesinlikle en iyi çözüm. Kayan yuvalanmış div içeren garip bir hack veya bunun gibi bir şey içermez. Bence daha yüksek puan değil tek neden insanlar tablolara karşı çok ileri gitmiş olmasıdır. Bu bir tablo değil, bu yüzden mükemmel bir meşru yöntem.
Dan Jones

1
Kabul ediyorum, bu en iyi çözüm gibi görünüyor. @ Bobince'nin çözümü de basit olsa da, iç elemanda stilleri değiştirmenin yan etkisi vardır.
jorgeh

display: table;Varyant sözde elemanlar (için idealdir ::before, ::aftersen fazladan kod olamaz) ve bitişik eleman stillerine önlemek bozulma istiyorum.
Walf

20

o kediyi almanın altı yolu:

Birinci düğme: türdeki herhangi bir şey display: blocktam ebeveyn genişliğini varsayacaktır. ( floatveya bir display: flexebeveynle birleştirilmedikçe ). Doğru. Kötü örnek.

Düğme 2: İleri gitmek display: inline-blockotomatik (tam değil) genişliğe yol açar. Daha sonra text-align: center kaydırma bloğunu kullanarak ortalayabilirsiniz . Muhtemelen en kolay ve en geniş çapta uyumlu, 'eski' tarayıcılarda bile ...

.wrapTwo
  text-align: center;
.two
  display: inline-block; // instantly shrinks width

Düğme 3: Sargıya herhangi bir şey koymaya gerek yok. Belki de bu en zarif çözüm. Ayrıca dikey olarak çalışır. (Transtlate için tarayıcı desteği bu günlerde yeterince iyi (≥IE9) ...).

position: relative;
display: inline-block; // instantly shrinks width
left: 50%;
transform: translateX(-50%);

Btw: Yüksekliği bilinmeyen blokları dikey olarak ortalamanın harika bir yolu (mutlak konumlandırma ile bağlantılı olarak).

Düğme 4: Mutlak konumlandırma. Sadece sarıcıda yeterli yükseklik ayırdığınızdan emin olun, çünkü başka kimse olmayacaktır (ne temizleme ne de örtük ...)

.four
  position absolute
  top 0
  left 50%
  transform translateX(-50%)
.wrapFour
  position relative // otherwise, absolute positioning will be relative to page!
  height 50px // ensure height
  background lightgreen // just a marker

Düğme 5: şamandıra (blok düzeyinde öğeleri dinamik genişliğe de getirir) ve göreli bir kaydırma. Bunu vahşi doğada hiç görmemiş olmama rağmen . Belki dezavantajları vardır ...

.wrapFive
  &:after // aka 'clearfix'
    content ''
    display table
    clear both

.five  
  float left
  position relative
  left 50%
  transform translateX(-50%)

Güncelleme: Düğme 6: Ve günümüzde flex-box da kullanabilirsiniz. Stillerin ortalanmış nesnenin sarmalayıcısı için geçerli olduğunu unutmayın.

.wrapSix
  display: flex
  justify-content: center

→ tam ​​kaynak kodu (dijital kalem sözdizimi)


17

Şamandıra ve hacky net kullanmaktan kaçınmak için "inline-block" u birleştirerek daha zarif bir çözüm buldum: her ikisi de. Hala çok semantik olmayan iç içe div gerektirir, ama sadece çalışır ...

div.outer{
    display:inline-block;
    position:relative;
    left:50%;
}

div.inner{
    position:relative;
    left:-50%;
}

Umarım yardımcı olur!


4
<div class="outer">
   <div class="target">
      <div class="filler">
      </div>
   </div>
</div>

.outer{
   width:100%;
   height: 100px;
}

.target{
   position: absolute;
   width: auto;
   height: 100px;
   left: 50%;
   transform: translateX(-50%);
}

.filler{
   position:relative;
   width:150px;
   height:20px;
}

Hedef eleman kesinlikle konumlandırılmışsa,% 50'yi bir yönde ( left: 50%) hareket ettirip ardından% 50'yi karşıt yönde ( transform:translateX(-50%)) dönüştürerek ortalayabilirsiniz . Bu, hedef öğenin genişliğini (veya ile width:auto) tanımlamaksızın çalışır . Üst öğenin konumu statik, mutlak, göreli veya sabit olabilir.


1
Bu, merkezlediğiniz şeyin genişliğinin yarısı kadar merkez dışında olacaktır.
resim

@ 4imble Hayır olmayacak. "Left" özelliği onu% 50 (üst genişliğinin% 50'si) hareket ettirir ve translateX (-50%) diğer yolu% 50 hareket ettirir (hedef öğenin genişliğinin% 50'si).
West1

Ahh evet, translateX'i kaçırdım. Bu IE 11 önce herhangi bir IE güvenilir emin değilim. Ama haklısın.
resim

3

Varsayılan olarak, divöğeler blok öğeleri olarak görüntülenir, böylece% 100 genişliğe sahiptirler, bu da onları ortalamayı anlamsız hale getirir. Arief önerdiği gibi, bir belirtmelisiniz widthve daha sonra kullanabilirsiniz autobelirtirken marginmerkez a amacıyla div.

Alternatif olarak, zorlayabilirsiniz display: inline, ancak o zaman bir spanyerine bir şey gibi davranırsınız div, bu yüzden çok mantıklı değildir.


3

Bu, Sıralı Liste veya Sırasız Liste gibi bir öğeyi veya herhangi bir öğeyi ortalar. Sadece outerElement sınıfıyla bir Div ile sarın ve iç öğeye innerElement sınıfını verin.

Dış sınıf, IE, eski Mozilla ve en yeni tarayıcıları oluşturur.

 .outerElement {
        display: -moz-inline-stack;
        display: inline-block;
        vertical-align: middle;
        zoom: 1;
        position: relative;
        left: 50%;
    }

.innerElement {
    position: relative;
    left: -50%;
} 

Lütfen kodunuzla birlikte bir açıklama ekleyin. Kodun kendi başına gönderilmesi, SO'nun gelecekteki ziyaretçileri için çok fazla bir şey ifade etmeyecektir.
Ren

3

justify-content: center ile css3 flexbox kullanın;

    <div class="row">
         <div class="col" style="background:red;">content1</div>
          <div class="col" style="">content2</div>
    </div>


.row {
    display: flex; /* equal height of the children */
    height:100px;
    border:1px solid red;
    width: 400px;
    justify-content:center;
}

1

Mike M. Lin'in cevabında hafif farklılıklar

Eğer eklerseniz overflow: auto;(veya hidden) eklerseniz div.product_container, buna ihtiyacınız yoktur div.clear.

Bu, bu makaleden türetilmiştir -> http://www.quirksmode.org/css/clearing.html

İşte değiştirilmiş HTML:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
</div>

Ve işte değiştirilmiş CSS:

.product_container {
  overflow: auto;
  /* width property only required if you want to support IE6 */
  width: 100%;
}

.outer-center {
  float: right;
  right: 50%;
  position: relative;
}

.inner-center {
  float: right;
  right: -50%;
  position: relative;
}

Olmadan daha iyi olmasının nedeni div.clear(boş bir öğeye sahip olmanın yanlış olduğunu düşünmek dışında) Firefox'un aşırı derecede marj atamasıdır.

Örneğin, şu html'ye sahipseniz:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div style="clear: both;"></div>
</div>
<p style="margin-top: 11px;">Some text</p>

daha sonra, Firefox'ta (yazma noktasında 8.0), daha önce11px marj göreceksiniz . Daha da kötüsü, içerik ekran boyutlarına iyi uysa bile tüm sayfa için dikey bir kaydırma çubuğu elde etmenizdir. product_container


1

Bu yeni css ve işaretlemeyi deneyin

İşte değiştirilmiş HTML:

<div class="product_container">
<div class="products" id="products">
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>   
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
</div>

Ve işte değiştirilmiş CSS:

<pre>
.product_container 
 {
 text-align:    center;
 height:        150px;
 }

.products {
    left: 50%;
height:35px;
float:left;
position: relative;
margin: 0 auto;
width:auto;
}
.products .products_box
{
width:auto;
height:auto;
float:left;
  right: 50%;
  position: relative;
}
.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}


1
<div class="product_container">
<div class="outer-center">
<div class="product inner-center">
    </div>
</div>
<div class="clear"></div>
</div>

.outer-center
{
float: right;
right: 50%;
position: relative;
}
.inner-center 
{
float: right;
right: -50%;
position: relative;
}
.clear 
{
clear: both;
}

.product_container
{
overflow:hidden;
}

".Product_container" için "taşma: gizli" sağlamazsanız, "dış merkez" div, sağındaki diğer yakındaki içeriklerle çakışır. "Dış merkez" in sağındaki bağlantı veya düğmeler çalışmaz. "Taşma: gizli" ihtiyacını anlamak için "dış merkez" için arka plan rengini deneyin


1

İlginç bir çözüm buldum, kaydırıcı yapıyordum ve slayt kontrollerini ortalamak zorunda kaldım ve bunu yaptım ve iyi çalışıyor. Ayrıca üst öğeye göreli konum ekleyebilir ve alt konumu dikey olarak taşıyabilirsiniz. Bir göz atın http://jsfiddle.net/bergb/6DvJz/

CSS:

#parent{
        width:600px;
        height:400px;
        background:#ffcc00;
        text-align:center;
    }

#child{
        display:inline-block;
        margin:0 auto;
        background:#fff;
    }  

HTML:

<div id="parent">
    <div id="child">voila</div>
</div>

1

Do display:table;ve set marginiçinauto

Önemli kod kısmı:

.relatedProducts {
    display: table;
    margin-left: auto;
    margin-right: auto;
}

Şimdi kaç elemanınız olursa olsun, merkezde otomatik olarak hizalanacaktır

Kod pasajındaki örnek:


0

Korkarım açıkça genişliği belirtmeden bunu yapmanın tek yolu (gasp) tabloları kullanmaktır.


5
rephrased: Bir sonraki saati her türlü CSS, iç içe DIV ve tarayıcı kombinasyonunu deneyerek geçirmek istemiyorsanız, doğrudan tablolara gidin.
Eduardo Molteni

Tablolar tasarım öğeleri olarak kullanılmak üzere tasarlanmamıştır. Bu kötü bir tarz.
Sebi2020

0

Berbat bir düzeltme ama işe yarıyor ...

CSS:

#mainContent {
    position:absolute;
    width:600px;
    background:#FFFF99;
}

#sidebar {
    float:left;
    margin-left:610px;
    max-width:300;
    background:#FFCCCC;
}
#sidebar{


    text-align:center;
}

HTML:

<center>
<table border="0" cellspacing="0">
  <tr>
    <td>
<div id="mainContent">
1<br/>
<br/>
123<br/>
123<br/>
123<br/>
</div><div id="sidebar"><br/>
</div></td>
</tr>
</table>
</center>

0

Eski tarayıcılarda çalışan (ancak tabloları kullanan ve ayarlanması gereken bir yükseklik gerektiren) basit düzeltme:

<div style="width:100%;height:40px;position:absolute;top:50%;margin-top:-20px;">
  <table style="width:100%"><tr><td align="center">
    In the middle
  </td></tr></table>
</div>

0
<style type="text/css">
.container_box{
    text-align:center
}
.content{
    padding:10px;
    background:#ff0000;
    color:#ffffff;

}

iç divlerin açıklığını kullan

<div class="container_box">
   <span class="content">Hello</span>
</div>

0

Bu sorunun eski olduğunu biliyorum, ama bir çatlak alıyorum. Bobince'nin cevabına çok benzer, ancak çalışma kodu örneği ile.

Her ürünü bir satır içi blok haline getirin. Kabın içindekileri ortalayın. Bitti.

http://jsfiddle.net/rgbk/6Z2Re/

<style>
.products{
    text-align:center;
}

.product{
    display:inline-block;
    text-align:left;

    background-image: url('http://www.color.co.uk/wp-content/uploads/2013/11/New_Product.jpg');
    background-size:25px;
    padding-left:25px;
    background-position:0 50%;
    background-repeat:no-repeat;
}

.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}
</style>


<div class="products">
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
</div>

Ayrıca bkz: CSS'de dinamik genişliğe sahip satır içi blokları ortala


Bu cevap zaten aynı çözümü sunmuyor mu? stackoverflow.com/a/284064/547733
Maxime Rossini

1
haklısın, madmox! Gerçi sağlam değil. Ayrıca, metin hizalamasını sola veya sağa ayarlamanın, soldan sağa okuma sırasını sağdan sola değiştirmeyi içeren çeviriler içeren bir sitede asla çalışmayacağı anlamına gelir. text-align, öğeleri değil metni hizalamak içindir. İdeal olarak yakın gelecekte gösterime bağlı olacağız: bu tür şeyler için esnek.
Wray Bowling

0

Bu, öğelerin iç genişliğini bilmeyen bir div içindeki herhangi bir şeyi ortalamanın bir yoludur.

#product_15{
    position: relative;
    margin: 0 auto;
    display: table;
}
.price, img{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

-1

benim çözümüm şuydu:

.parent {
    display: flex;
    flex-wrap: wrap;
}

.product {
    width: 240px;
    margin-left: auto;
    height: 127px;
    margin-right: auto;
}

-7

bu css'yi product_container sınıfınıza ekleyin

    margin: 0px auto;
    padding: 0px;
    border:0;
    width: 700px;

Soru özellikle "genişlik olmadan" diyor
Dez Udezue
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.