Centrowanie bloku div bez szerokości


241

Mam problem, gdy próbuję wyśrodkować „produkty” bloku div, ponieważ nie znam z góry szerokości div. Czy ktoś ma rozwiązanie?

Aktualizacja: Mam problem z tym, że nie wiem, ile produktów będę wyświetlać, mogę mieć 1, 2 lub 3 produkty, mogę je wyśrodkować, jeśli byłby to stały numer, ponieważ wiedziałbym szerokość rodzica div, po prostu nie wiem, jak to zrobić, gdy treść jest dynamiczna.

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


Jaki dokładnie masz problem?
anand.trex

Odpowiedzi:


256

Aktualizacja 27 lutego 2015 r .: Moja pierwotna odpowiedź wciąż jest poddawana głosowaniu, ale teraz zamiast tego zwykle używam podejścia @ bobince.

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

Mój oryginalny post do celów historycznych:

Możesz spróbować tego podejścia.

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

Oto pasujący styl:

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

JSFiddle

Chodzi o to, abyś zawierał zawartość, którą chcesz wyśrodkować w dwóch divach, zewnętrznej i wewnętrznej. Przesuwasz oba divy tak, aby ich szerokości automatycznie zmniejszały się w celu dopasowania do treści. Następnie relatywnie ustawiasz div div z jego prawą krawędzią na środku kontenera. Na koniec, względnie pozycjonujesz wewnętrzny div w przeciwnym kierunku o połowę jego własnej szerokości (w rzeczywistości szerokość zewnętrznego div, ale są one takie same). Ostatecznie to centruje zawartość w dowolnym pojemniku, w którym się znajduje.

Państwo może trzeba, że pusty div na końcu, jeśli zależy na „produkt” treści do wielkości wysokość dla „product_container”.


1
Jeśli dont dostarczyć overflow:hiddendo div będą nakładać się na inne pobliskie zawartość na prawo od niego. Wszelkie linki lub przyciski po prawej stronie nie będą działać. Wypróbuj kolor tła, aby zrozumieć potrzebę . To była sugerowana edycja autorstwa Cicila Thomasa.product_containerouter-centerouter-centerouter-centeroverflow :hidden
Benjola,

To podejście jest idealne dla witryn na komputery ... na urządzeniach mobilnych jednak wewnętrzne div-div wydają się dołączać po prawej stronie. Czy jest jakieś rozwiązanie?
Mich Dart

3
Opowiedz mi o tym! Czasami po prostu potrzebujemy rozwiązania i nie mamy luksusu wyboru dobrego. Tabela z pojedynczą komórką to kolejna opcja, chociaż tabela z jedną komórką nie jest tak naprawdę tabelą, prawda?
Mike M. Lin

@fgysin Zgadzam się, to jest anty-intuicyjny hack. A projektanci zastanawiają się, dlaczego ludzie wciąż zastanawiają się nad powrotem do układów opartych na tabelach.
Fuj

1
To pytanie ma pięć lat. Ta odpowiedź jest nieaktualna, ale na początku nigdy nie była zbyt elegancka. Co powinieneś zrobić, to użyj display: inline-block
Wray Bowling

140

Element z „display: block” (ponieważ div jest domyślnie) ma szerokość określoną przez szerokość kontenera. Nie można uzależnić szerokości bloku od szerokości jego zawartości (dopasowanie zmniejszone).

(Z wyjątkiem bloków, które są „zmiennoprzecinkowe: lewy / prawy” w CSS 2.1, ale nie nadaje się to do centrowania.)

Możesz ustawić właściwość „display” na „inline-block”, aby zmienić blok w obiekt dopasowany do rozmiaru, który może być kontrolowany przez właściwość wyrównywania tekstu jego rodzica, ale obsługa przeglądarki jest nierówna. Możesz przede wszystkim uciec, używając hacków (np. Patrz -moz-inline-stack), jeśli chcesz pójść tą drogą.

Innym sposobem są tabele. Może to być konieczne, gdy masz kolumny, których szerokości naprawdę nie można z góry poznać. Naprawdę nie potrafię powiedzieć, co próbujesz zrobić z przykładowego kodu - nie ma w tym nic oczywistego, co wymagałoby skurczu, aby dopasować blok - ale listę produktów można by uznać za tabelaryczną.

[PS. nigdy nie używaj „pt” dla rozmiarów czcionek w Internecie. „px” jest bardziej niezawodny, jeśli naprawdę potrzebujesz tekstu o stałym rozmiarze, w przeciwnym razie lepsze są jednostki względne, takie jak „%”. I „wyczyść: ccc oba” - literówka?]

.center{
   text-align:center; 
}

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

JSFiddle


53
parent -> text-align: center | child-> display: inline-block
mdskinner

5
display: inline-blocknie jest obsługiwany w IE7 i starszych wersjach Firefoksa
Jake Wilson

1
@Jobobud, dla IE7 użyj „display: inline; zoom: 1;” zamiast „display: inline-block;”. Działa dla elementów blokowych.
mihail-haritonov

1
sprawdź ten link, aby uzyskać więcej informacji na temat korzystania z tej metody w różnych przeglądarkach - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke

1
Użyłem tego scss, aby go zaimplementować, który będzie działał, dopóki twoja struktura HTML będzie go obsługiwać: .center {text-align: center; &: first-child {display: blok wbudowany; }}
Dovev Hefetz

95

Większość przeglądarek obsługuje display: table;regułę CSS. Jest to dobra sztuczka, aby wyśrodkować element div w kontenerze bez dodawania dodatkowego kodu HTML ani stosowania stylów ograniczających do kontenera (podobnie jak w text-align: center;przypadku wszystkich innych treści wstawianych w kontenerze) przy jednoczesnym zachowaniu dynamicznej szerokości zawartego elementu div:

HTML:

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

CSS:

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


Aktualizacja (2015-03-09):

Właściwym sposobem na zrobienie tego dzisiaj jest użycie reguł Flexbox. Obsługa przeglądarki jest nieco bardziej ograniczona ( obsługa tabeli CSS vs. obsługa Flexbox ), ale ta metoda pozwala również na wiele innych rzeczy i jest dedykowaną regułą CSS dla tego typu zachowania:

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
Myślę, że to zdecydowanie najlepsze rozwiązanie. Nie wymaga żadnych dziwnych hacków z pływającymi zagnieżdżonymi divami ani nic podobnego. Myślę, że jedynym powodem, dla którego nie oceniono go wyżej, jest to, że ludzie posunęli się zbyt daleko w stosunku do tabel. To nie jest tabela, więc myślę, że jest to całkowicie uzasadniona metoda.
Dan Jones

1
Zgadzam się, wydaje się to najlepszym rozwiązaniem. Chociaż rozwiązanie @ bobince jest również proste, ma efekt uboczny zmiany stylów w elemencie wewnętrznym.
jorgeh

Ten display: table;wariant jest idealny dla pseudoelementów ( ::before, ::after), w których nie można dodawać dodatkowych znaczników i chcesz uniknąć zakłóceń w stylach sąsiednich elementów.
Walf

20

sześć sposobów na skórowanie tego kota:

Przycisk pierwszy: cokolwiek typu display: blockprzyjmie pełną szerokość rodziców. (chyba że w połączeniu z floatlub display: flexrodzicem). Prawdziwe. Zły przykład.

Przycisk 2: przejście display: inline-blockspowoduje automatyczną (a nie pełną) szerokość. Następnie można wyśrodkować za pomocą text-align: center bloku owijającego . Prawdopodobnie najłatwiejsza i najbardziej kompatybilna, nawet z przeglądarkami „vintage” ...

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

Przycisk 3: Nie musisz niczego umieszczać na opakowaniu. Być może jest to najbardziej eleganckie rozwiązanie. Działa również pionowo. (Obsługa transtlate przez przeglądarkę jest obecnie wystarczająca (≥IE9) w dzisiejszych czasach ...).

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

Btw: Świetny sposób na pionowe centrowanie bloków o nieznanej wysokości (w połączeniu z absolutnym pozycjonowaniem).

Przycisk 4: Pozycjonowanie absolutne. Pamiętaj tylko, aby zarezerwować wystarczającą wysokość w opakowaniu, ponieważ nikt inny tego nie zrobi (ani poprawki, ani domniemania ...)

.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

Przycisk 5: zmiennoprzecinkowy (który powoduje także dynamiczne szerokości elementów na poziomie bloku) i względne przesunięcie. Chociaż nigdy nie widziałem tego na wolności. Być może są wady ...

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

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

Aktualizacja: Przycisk 6: A w dzisiejszych czasach można również użyć Flex-Box. Pamiętaj, że style mają zastosowanie do opakowania wyśrodkowanego obiektu.

.wrapSix
  display: flex
  justify-content: center

→ pełny kod źródłowy (składnia rysika)


17

Znalazłem bardziej eleganckie rozwiązanie, łącząc „wbudowany blok”, aby uniknąć używania float i hacky clear: oba. Nadal wymaga zagnieżdżonych div div, co nie jest bardzo semantyczne, ale po prostu działa ...

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

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

Mam nadzieję, że to pomoże!


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

Jeśli element docelowy jest ustawiony absolutnie, możesz go wyśrodkować, przesuwając go o 50% w jednym kierunku ( left: 50%), a następnie przekształcając go o 50% w kierunku przeciwnym ( transform:translateX(-50%)). Działa to bez definiowania szerokości elementu docelowego (lub za pomocą width:auto). Pozycja elementu nadrzędnego może być statyczna, bezwzględna, względna lub stała.


1
To będzie poza środkiem o połowę szerokości rzeczy, którą centrujesz.
4imble

@ 4imble Nie, nie będzie. Właściwość „left” przesuwa ją o 50% (50% szerokości elementu nadrzędnego), a translateX (-50%) przesuwa ją o 50% w drugą stronę (50% szerokości elementu docelowego).
Zachód 1

Ach tak, brakowało mi translateX. Nie jestem pewien, czy jest to wiarygodne w dowolnym IE przed IE 11. Ale masz rację.
4imble,

3

Domyślnie divelementy są wyświetlane jako elementy blokowe, więc mają 100% szerokości, dzięki czemu ich centrowanie nie ma znaczenia. Jak sugeruje Arief, musisz określić a, widtha następnie możesz użyć go autopodczas określania margin, aby wyśrodkować adiv .

Alternatywnie możesz również wymusić display: inline, ale wtedy miałbyś coś , co właściwie zachowuje się jak spanzamiast div, więc nie ma to większego sensu.


3

Spowoduje to wyśrodkowanie elementu, takiego jak lista uporządkowana, lista nieuporządkowana lub dowolny element. Wystarczy owinąć go Div z klasą outerElement i nadać elementowi wewnętrznemu klasę innerElement.

Klasa outerelement dla IE, starej Mozilli i większości nowszych przeglądarek.

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

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

Dodaj opis wraz ze swoim kodem. Sam kodowanie nie będzie wiele znaczyło dla przyszłych użytkowników SO.
Ren

3

użyj css3 flexbox z justify-content: center;

    <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

Nieznaczne różnice w odpowiedzi Mike'a M. Lin

Jeśli dodasz overflow: auto;(lub hidden) do div.product_container, nie potrzebujesz div.clear.

Wynika to z tego artykułu -> http://www.quirksmode.org/css/clearing.html

Oto zmodyfikowany HTML:

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

I tutaj jest zmodyfikowany 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;
}

Powód, dla którego lepiej bez niego div.clear (poza tym, że posiadanie pustego elementu wydaje się niewłaściwe), jest nadgorliwe przydzielanie marginesów przez Firefox.

Jeśli na przykład masz ten kod HTML:

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

Następnie Firefox (8.0 w punkcie piśmie), widać 11pxmargines wcześniej product_container . Co gorsza, otrzymasz pionowy pasek przewijania dla całej strony, nawet jeśli zawartość ładnie pasuje do wymiarów ekranu.


1

Wypróbuj nowy css i znaczniki

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

I tutaj jest zmodyfikowany 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;
}

Jeśli nie podasz „przepełnienie: ukryte” dla „.product_container”, div z „zewnętrznego centrum” nałoży się na inne znajdujące się w pobliżu treści po prawej stronie. Wszelkie linki lub przyciski po prawej stronie „zewnętrznego centrum” nie będą działać. Wypróbuj kolor tła dla „zewnętrznego centrum”, aby zrozumieć potrzebę „przepełnienia: ukryty”


1

Znalazłem ciekawe rozwiązanie, robiłem suwak i musiałem wyśrodkować sterowanie suwakiem, zrobiłem to i działa dobrze. Możesz także dodać pozycję względną do rodzica i przesunąć pozycję dziecka w pionie. Spójrz 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

Zrób display:table;i ustaw marginnaauto

Ważna część kodu:

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

Bez względu na to, ile elementów masz teraz, automatycznie wyrówna się do środka

Przykład we fragmencie kodu:


0

Obawiam się, że jedynym sposobem na zrobienie tego bez wyraźnego określenia szerokości jest użycie tabel (wstrzymania oddechu).


5
przeformułowany: Jeśli nie chcesz spędzić następnej godziny na próbowaniu wszelkiego rodzaju kombinacji CSS, zagnieżdżonych DIV i przeglądarek, przejdź bezpośrednio do tabel.
Eduardo Molteni

Tabele nie są przeznaczone do stosowania jako elementy projektu. To zły styl.
Sebi2020

0

Nędzne rozwiązanie, ale działa ...

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

Prosta poprawka, która działa w starych przeglądarkach (ale korzysta z tabel i wymaga ustawienia wysokości):

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

}

użyj przęsła istead wewnętrznych div

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

0

Wiem, że to pytanie jest stare, ale łamię sobie je. Bardzo podobny do odpowiedzi Bobina, ale z działającym przykładem kodu.

Niech każdy produkt będzie blokiem wbudowanym. Wyśrodkuj zawartość pojemnika. Gotowe.

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>

Zobacz także: Wyśrodkuj bloki wbudowane o dynamicznej szerokości w CSS


Czy ta odpowiedź nie zapewnia już tego samego rozwiązania? stackoverflow.com/a/284064/547733
Maxime Rossini

1
masz rację, madmox! Jednak nie jest tak solidny. Zdaję sobie również sprawę, że ustawienie wyrównywania tekstu do lewej lub prawej oznacza, że ​​to nigdy nie zadziała w witrynie z tłumaczeniami, które obejmują przełączanie kolejności czytania od lewej do prawej na od prawej do lewej. text-align służy do wyrównywania tekstu, a nie elementów. Idealnie w niedalekiej przyszłości będziemy polegać na wyświetlaniu: flex dla tego rodzaju rzeczy.
Wray Bowling

0

Jest to jeden ze sposobów wyśrodkowania czegokolwiek w div, który nie zna wewnętrznej szerokości elementów.

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

-1

moim rozwiązaniem było:

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

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

-7

dodaj ten css do swojej klasy product_container

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

Pytanie wyraźnie mówi „bez szerokości”
Dez Udezue
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.