Центрирование блока div без ширины

241

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

Обновление: у меня проблема в том, что я не знаю, сколько продуктов я буду отображать, у меня может быть 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>

Нян
источник
В чем конкретно проблема у вас?
anand.trex

Ответы:

256

Обновление 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 в конце, если вы зависите от содержимого «product» для определения высоты для «product_container».

Майк М. Лин
источник
1
Если вы не обеспечиваете overflow:hiddenдля DIV будет перекрывать другое близлежащее содержимое справа от него. Любые ссылки или кнопки справа не будут работать. Попробуйте цвет фона, чтобы понять необходимость . Это было предложенное редактирование Сицилом Томасом.product_containerouter-centerouter-centerouter-centeroverflow :hidden
Бенджол
Этот подход идеально подходит для настольных веб-сайтов ... на мобильных, однако, inner-div, похоже, прикрепляются вправо. Есть ли решение?
Миш Дарт
3
Расскажи мне об этом! Иногда нам просто нужно решение, и мы не можем позволить себе роскошь выбирать. Таблица с одной ячейкой - это еще один вариант, хотя таблица с одной ячейкой на самом деле не является таблицей, не так ли?
Майк М. Лин
@fgysin Согласен, это нелогичный хак. И дизайнеры задаются вопросом, почему люди все еще думают о том, чтобы вернуться к макетам на основе таблиц.
Yuck
1
Этому вопросу пять лет. Этот ответ устарел, но никогда не был очень элегантным с самого начала. Что вы должны сделать, это использовать display: inline-block
Wray Bowling
140

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

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

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

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

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

.center{
   text-align:center; 
}

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

JSFiddle

bobince
источник
53
parent -> text-align: center | child-> display: inline-block
mdskinner
5
display: inline-blockне поддерживается в IE7 и более ранних версиях Firefox
Джейк Уилсон
1
@Jakobud, для IE7 используйте «display: inline; zoom: 1;» вместо «display: inline-block;». Работает для блочных элементов.
Михаил Харитонов
1
Проверьте эту ссылку для получения дополнительной информации о том, как использовать этот метод кросс-браузер - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke
1
Я использовал этот scss для его реализации, который будет работать до тех пор, пока существует ваша HTML-структура для его поддержки: .center {text-align: center; &: first-child {display: inline-block; }}
Довев Хефец
95

Большинство браузеров поддерживают 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; }


Обновление (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; }

Максим Россини
источник
11
Я думаю, что это определенно лучшее решение. Не включает в себя какие-либо странные хаки с плавающими вложенными элементами div или что-то в этом роде. Я думаю, что единственная причина, по которой он не оценивается выше, заключается в том, что люди зашли слишком далеко против таблиц. Это не таблица, поэтому я думаю, что это совершенно законный метод.
Дэн Джонс
1
Согласитесь, это, кажется, лучшее решение. Хотя решение @ bobince также простое, оно имеет побочный эффект изменения стилей во внутреннем элементе.
Хорхе
Этот display: table;вариант идеален для псевдоэлементов ( ::before, ::after), где вы не можете добавить дополнительную разметку и хотите избежать нарушения стилей смежных элементов.
Walf
20

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

Кнопка первая: все, что имеет тип 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

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

Фрэнк Нок
источник
17

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

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

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

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

JavierIEH
источник
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;
}

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

West1
источник
1
Это будет смещено от центра на половину ширины центрируемой вещи.
4imble
@ 4imble Нет, не будет. Свойство left перемещает его на 50% (50% ширины его родителя), а translateX (-50%) перемещает его на 50% в другую сторону (50% ширины целевого элемента).
West1
Ах да, я пропустил переводчик. Не уверен, что это надежно в любом IE до IE 11. Но вы правы.
4
3

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

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

Адам Беллер
источник
3

Это будет центрировать элемент, такой как упорядоченный список, или неупорядоченный список, или любой элемент. Просто оберните его 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%;
} 
Грег Беннер
источник
Пожалуйста, добавьте описание с вашим кодом. Размещение кода самостоятельно не будет много значить для будущих посетителей SO.
Рен
3

используйте 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;
}
zloctb
источник
1

Небольшая вариация ответа Майка М. Линя

Если вы добавите overflow: auto;(или hidden) к div.product_container, то вам не нужно div.clear.

Это происходит из этой статьи -> http://www.quirksmode.org/css/clearing.html

Вот модифицированный HTML:

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

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

Причина, почему лучше без div.clear (кроме того, что иметь пустой элемент кажется неправильным), заключается в чрезмерном усердии в Firefox.

Если, например, у вас есть этот 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>

затем в Firefox (8.0 на момент написания) вы увидите 11pxполе ранее product_container . Хуже всего то, что вы получите вертикальную полосу прокрутки для всей страницы, даже если контент хорошо вписывается в размеры экрана.

Александр Погребняк
источник
1

Попробуйте эту новую 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;
}

Шинов Т
источник
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;
}

Если вы не предоставите «overflow: hidden» для «.product_container», div «external-center» будет перекрывать другое близлежащее содержимое справа от него. Любые ссылки или кнопки справа от "внешнего центра" не будут работать. Попробуйте цвет фона для «external-center», чтобы понять необходимость «overflow: hidden»

Сисил Томас
источник
1

Я нашел интересное решение, я делал слайдер, и мне нужно было центрировать элементы управления слайдом, и я сделал это, и он отлично работает. Вы также можете добавить относительную позицию к родителю и переместить дочернюю позицию по вертикали. Посмотрите 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

Есть display:table;и установить marginнаauto

Важный бит кода:

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

Независимо от того, сколько элементов у вас сейчас, оно будет автоматически выровнено по центру

Пример во фрагменте кода:

хахаха
источник
0

Боюсь, единственный способ сделать это без явного указания ширины - это использовать (задыхаться) таблицы.

Kon
источник
5
Перефразировано: если вы не хотите тратить следующий час, пробуя все виды комбинаций CSS, вложенных DIV и браузеров, перейдите непосредственно к таблицам.
Эдуардо Молтени
Таблицы не предназначены для использования в качестве элементов дизайна. Это плохой стиль.
Sebi2020
0

Дрянное исправление, но оно работает ...

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

Простое исправление, которое работает в старых браузерах (но использует таблицы и требует установки высоты):

<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>
Craigo
источник
0
<style type="text/css">
.container_box{
    text-align:center
}
.content{
    padding:10px;
    background:#ff0000;
    color:#ffffff;

}

используйте span istead внутренних элементов div

<div class="container_box">
   <span class="content">Hello</span>
</div>
кто-то
источник
0

Я знаю, что этот вопрос старый, но я не согласен с ним. Очень похоже на ответ Бобинса, но с примером рабочего кода.

Сделайте каждый продукт встроенным блоком. Центрируйте содержимое контейнера. Готово.

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>

Смотрите также: Центрирование встроенных блоков с динамической шириной в CSS

Wray Bowling
источник
Разве этот ответ уже не дает того же решения? stackoverflow.com/a/284064/547733
Максим Россини
1
ты прав, сумасшедший! Это не так надежно, хотя. Также я понимаю, что установка выравнивания текста по левому или правому краю означает, что это никогда не будет работать на сайте с переводами, которые включают переключение порядка чтения слева направо на право слева направо. text-align для выравнивания текста, а не элементов. В идеале в ближайшем будущем мы будем зависеть от показа: flex для такого рода вещей.
Wray Bowling
0

Это один из способов центрировать что-либо внутри div, не зная внутренней ширины элементов.

#product_15{
    position: relative;
    margin: 0 auto;
    display: table;
}
.price, img{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
Ширли Эшби
источник
-1

мое решение было:

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

.product {
    width: 240px;
    margin-left: auto;
    height: 127px;
    margin-right: auto;
}
Byron
источник
-7

добавьте эту CSS в ваш класс product_container

    margin: 0px auto;
    padding: 0px;
    border:0;
    width: 700px;
Arief
источник
Вопрос, в частности, говорит: «без ширины»
Дез Удезуе