Центрирование блока div без ширины - PullRequest
230 голосов
/ 12 ноября 2008

У меня проблема, когда я пытаюсь центрировать блок "продукты", потому что я не знаю заранее ширину блока. У кого-нибудь есть решение?

Обновление: у меня проблема в том, что я не знаю, сколько продуктов я буду отображать, у меня может быть 1, 2 или 3 продукта, я могу отцентрировать их, если бы это было фиксированное число, так как я знал бы ширину из родительского div, я просто не знаю, как это сделать, когда содержимое динамическое.

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

Ответы [ 21 ]

242 голосов
/ 15 июня 2011

Обновление 27 февраля 2015 г .: Мой первоначальный ответ продолжает получать голоса, но теперь вместо этого я обычно использую подход @ bobince.

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

Мой оригинальный пост в исторических целях:

Возможно, вы захотите попробовать этот подход.

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

Вот соответствующий стиль:

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

JSFiddle

Идея в том, что вы содержите контент, который хотите центрировать, в двух делениях: внешнем и внутреннем. Вы перемещаете оба элемента div, чтобы их ширина автоматически уменьшалась в соответствии с вашим содержимым. Затем вы относительно позиционируете внешний div с правым краем в центре контейнера. Наконец, вы относительно позиционируете внутренний div в противоположном направлении на половину его собственной ширины (на самом деле ширина внешнего div, но они одинаковы). В конечном итоге это центрирует контент в любом контейнере, в котором он находится.

Вам может понадобится этот пустой div в конце, если вы зависите от содержимого "product", чтобы измерить высоту для "product_container".

140 голосов
/ 12 ноября 2008

Элемент с «display: block» (так как div по умолчанию) имеет ширину, определяемую шириной его контейнера. Вы не можете сделать ширину блока зависимой от ширины его содержимого (сжать, чтобы подогнать).

(За исключением блоков, которые «float: left / right» в CSS 2.1, но для центрирования это бесполезно.)

Вы можете установить для свойства «display» значение «inline-block», чтобы превратить блок в сжатый объект, которым можно управлять с помощью свойства text-align его родителя, но поддержка браузера не является точной. В большинстве случаев это можно сделать с помощью хаков (например, см. -Moz-inline-stack), если вы хотите пойти по этому пути.

Другой путь - таблицы. Это может быть необходимо, когда у вас есть столбцы, ширина которых действительно не может быть известна заранее. Я не могу точно сказать, что вы пытаетесь сделать из примера кода - там нет ничего очевидного, что бы потребовалось бы блок для усадки - но список продуктов можно было бы считать табличным .

[PS. никогда не используйте «pt» для размеров шрифта в Интернете. «Px» более надежен, если вам действительно нужен текст фиксированного размера, в противном случае относительные единицы, такие как «%», лучше. И «clear: ccc both» - опечатка?]

.center{
   text-align:center; 
}

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

JSFiddle

93 голосов
/ 24 января 2014

Большинство браузеров поддерживают правило display: table; CSS. Это хороший прием для центрирования div в контейнере без добавления дополнительного HTML или применения к нему стилей ограничения (например, text-align: center;, который бы центрировал все остальное встроенное содержимое в контейнере), сохраняя при этом динамическую ширину для содержимого div:

HTML:

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

CSS:

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

.container {
  background-color: green;
}
.centered {
  display: table;
  margin: 0 auto;
  background-color: red;
}
<div class="container">
  <div class="centered">This content is centered</div>
</div>

Обновление (2015-03-09):

Правильный способ сделать это сегодня - использовать правила flexbox. Поддержка браузера немного более ограничена ( поддержка таблиц CSS против поддержка flexbox ), но этот метод также допускает много других вещей и является специальным правилом CSS для этого типа поведения:

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

.container {
  display: flex;
  flex-direction: column; /* put this if you want to stack elements vertically */
  background-color: green;
}
.centered {
  margin: 0 auto;
  background-color: red;
}
<div class="container">
  <div class="centered">This content is centered</div>
</div>
18 голосов
/ 23 мая 2017

шесть способов снять кожу с этой кошки:

Кнопка одна: что-либо типа display: block будет принимать полную ширину родителей. (если не объединено с float или display: flex родителем). Правда. Плохой пример.

Кнопка 2: для display: inline-block приведет к автоматической (а не полной) ширине. Затем вы можете центрировать, используя text-align: center на оберточном блоке . Вероятно, самый простой и наиболее совместимый, даже с "винтажными" браузерами ...

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

Кнопка 3: Не нужно ничего класть на пленку. Так что, возможно, это самое элегантное решение. Также работает вертикально. (Поддержка браузером для transstlate достаточно (≥IE9) в наши дни ...).

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

Кстати: также отличный способ для вертикально центрирующих блоков неизвестной высоты (в связи с абсолютным позиционированием).

Кнопка 4: Абсолютное позиционирование. Просто убедитесь, что в обертке зарезервировано достаточно высоты, так как никто другой не будет (ни clearfix, ни неявный ...)

.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

Кнопка 5: float (который приводит также элементы блочного уровня к динамической ширине) и относительное смещение. Хотя я никогда не видел этого в дикой природе. Возможно, есть и недостатки ...

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

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

Обновление: Кнопка 6: И в наши дни вы также можете использовать flex-box. Обратите внимание, что стили применяются к оболочке центрированного объекта.

.wrapSix
  display: flex
  justify-content: center

→ полный исходный код (синтаксис стилуса)

16 голосов
/ 01 июля 2011

Я нашел более элегантное решение, сочетающее «inline-block», чтобы избежать использования float и hacky clear: оба. Это все еще требует вложенных divs tho, который не очень семантический, но он просто работает ...

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

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

Надеюсь, это поможет!

4 голосов
/ 19 августа 2015
<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;
}

Если целевой элемент абсолютно позиционирован, вы можете отцентрировать его, переместив его на 50% в одном направлении (left: 50%), а затем преобразовав его на 50% в направлении противостояния (transform:translateX(-50%)). Это работает без определения ширины целевого элемента (или с width:auto). Позиция родительского элемента может быть статической, абсолютной, относительной или фиксированной.

3 голосов
/ 12 ноября 2008

По умолчанию элементы div отображаются как блочные элементы, поэтому они имеют ширину 100%, что делает их центрирование бессмысленным. В соответствии с предложением Arief, вы должны указать width, а затем вы можете использовать auto при указании margin для центрирования div.

В качестве альтернативы, вы также можете вызвать display: inline, но тогда у вас будет нечто, похожее на span вместо div, так что это не имеет большого смысла.

3 голосов
/ 16 ноября 2012

Это будет центрировать элемент, такой как упорядоченный список, или неупорядоченный список, или любой элемент. Просто оберните его Div с классом externalElement и присвойте внутреннему элементу класс innerElement.

Класс outerelement отвечает за IE, старый Mozilla и большинство новых браузеров.

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

.innerElement {
    position: relative;
    left: -50%;
} 
3 голосов
/ 21 ноября 2015

использовать css3 flexbox с 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 голос
/ 18 мая 2012

Попробуйте эту новую CSS и разметку

Вот модифицированный 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>

А вот модифицированный 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;
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...