Відцентрування ділового блоку без ширини


241

У мене виникають проблеми, коли я намагаюся зосередити діловий блок "товари", оскільки я не знаю заздалегідь ширину div. У когось є рішення?

Оновлення: Проблема в тому, що я не знаю, скільки продуктів я покажу, я можу мати 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 вам може знадобитися наприкінці, якщо ви залежите від вмісту "продукту", щоб розмір був висотою для "product_container".


1
Якщо ви не забезпечуєте overflow:hiddenдля DIV буде перекривати інше сусіднє вміст праворуч від нього. Будь-які посилання або кнопки праворуч від звичаю працюють. Спробуйте колір тла, щоб зрозуміти необхідність . Це було запропоновано редагувати Cicil Thomas.product_containerouter-centerouter-centerouter-centeroverflow :hidden
Benjol

Такий підхід ідеально підходить для веб-сайтів настільних комп'ютерів ... На мобільних пристроях, здається, внутрішні діви здаються праворуч. Чи є рішення?
Міч Дарт

3
Розкажи мені про це! Іноді нам просто потрібне рішення і нам не вистачає розкоші - вибрати хороший варіант. Таблиця з одноклітинками - це ще один варіант, хоча таблиця з однією коміркою насправді не є таблицею, чи не так?
Майк М. Лін

@fgysin Погодився, це контр-інтуїтивний злом. І дизайнерам цікаво, чому люди все ще розглядають можливість повернутися до макетів на основі столів.
Юк

1
Це питання п’ять років. Ця відповідь застаріла, але ніколи не була дуже елегантною для початку. Що вам слід зробити, це використовувати display: inline-block
Wray Bowling

140

Елемент з 'display: block' (як div за замовчуванням) має ширину, визначену шириною контейнера. Ви не можете зробити ширину блоку залежно від ширини його вмісту (зменшити до розміру).

(За винятком блоків "float: left / right" у CSS 2.1, але це не корисно для центрування.)

Ви можете встановити властивість "display" на "inline-block", щоб перетворити блок на об'єкт, що відповідає стисненню, який може управлятися властивістю батьківського вирівнювання тексту, але підтримка веб-переглядача є точковою. Ви можете в основному позбутися цього, використовуючи хаки (наприклад, див. -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


53
parent -> вирівнювання тексту: center | child-> display: inline-block
mdskinner

5
display: inline-blockне підтримується в IE7 та старіших версіях Firefox
Jake Wilson

1
@Jakobud, для IE7 використовуйте "display: inline; zoom: 1;" замість "display: inline-block;" Він працює для блокових елементів.
mihail-haritonov

1
ознайомтеся з цим посиланням для отримання додаткової інформації про те, як використовувати цей метод крос-браузер - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
клавіша

1
Я використовував цей scss для його реалізації, який буде працювати до тих пір, поки існує ваша HTML-структура для його підтримки: .center {text-align: center; &: перша дитина {дисплей: вбудований блок; }}
Довєв Гефец

95

Більшість браузерів підтримує display: table; правило CSS. Це хороший трюк, щоб центрувати дів у контейнері, не додаючи зайвий 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):

Правильний спосіб зробити це сьогодні - це фактично використовувати правила флексокса. Підтримка веб-переглядача трохи обмежена ( підтримка таблиці CSS vs підтримки 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
Я думаю, що це, безумовно, найкраще рішення. Не пов’язано жодних дивних злому з плаваючими вкладеними дівами чи подібним. Я думаю, що єдина причина, що його не оцінюють вище, - це те, що люди зайшли занадто далеко проти таблиць. Це не таблиця, тому я думаю, що це абсолютно законний метод.
Ден Джонс

1
Погоджено, це, здається, найкраще рішення. Хоча рішення @ bobince також просте, воно має побічний ефект зміни стилів у внутрішньому елементі.
jorgeh

display: table;Варіант ідеально підходить для псевдо-елементів ( ::before, ::after) , де ви не можете додати додаткову розмітку, і ви хочете , щоб порушення , уникайте суміжних стилів елементів.
Вальф

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: Не потрібно нічого класти на обгортку. Тож, мабуть, це найелегантніше рішення. Також працює вертикально. (Підтримка браузера для траншлату досить хороша (≥IE9) в наші дні ...).

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

Btw: Також чудовий спосіб вертикального центрування блоків невідомої висоти (у зв'язку з абсолютним позиціонуванням).

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

.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: поплавок (який також наближає елементи рівня блоку до динамічної ширини) та відносний зсув. Хоча я ніколи цього не бачив у дикій природі. Можливо, є і недоліки ...

.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

Я знайшов більш елегантне рішення, поєднуючи "inline-block", щоб уникнути використання float та hacky clear: і те, і інше. Це все ще вимагає вкладених ді-тхо, що не дуже семантично, але це просто працює ...

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

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

Сподіваюся, це допомагає!


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). Позиція батьківського елемента може бути статичною, абсолютною, відносною або фіксованою.


1
Це буде від центру на половину ширини речі, яку ви орієнтуєте.
4imble

@ 4imble Ні, це не буде. Властивість "ліворуч" переміщує його на 50% (50% ширини батьків), а translateX (-50%) переміщує його на 50% в інший бік (50% від ширини цільового елемента).
West1

Ага так, я пропустив translateX. Не впевнений, що це надійно в будь-якому ІЕ до IE 11. Але ви праві.
4imble

3

За замовчуванням divелементи відображаються як елементи блоку, тому вони мають 100% ширину, що робить їх центрування безглуздим. Як запропоновано Коротким, ви повинні вказати a, widthа потім можете використовувати його autoпри вказівці marginдля центрування adiv .

Крім того, ви також можете змусити display: inline, але тоді у вас буде щось, що майже поводиться як spanзамість div, так що це не має великого сенсу.


3

Це буде центрувати такий елемент, як упорядкований список або не упорядкований список, або будь-який елемент. Просто оберніть його Div класом externalElement і дайте внутрішньому елементу клас InternalElement.

Клас перешкоджання припадає на 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 з виправданням-контентом: центр;

    <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

Незначна варіація відповіді Майка М. Ліна

Якщо ви додасте 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'es.

Якщо, наприклад, у вас є цей 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", розділ "external-center" перекриє інший сусідній вміст праворуч від нього. Будь-які посилання або кнопки праворуч від "зовнішнього центру" не будуть працювати. Спробуйте колір фону для "зовнішнього центру", щоб зрозуміти необхідність "переповнення: приховано"


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

Я боюся, що єдиний спосіб зробити це без чітко вказаної ширини - використовувати (задихатись) таблиці.


5
перефразоване: Якщо ви не хочете витрачати наступну годину на випробування різного роду комбінацій CSS, вкладених DIV та браузерів, перейдіть безпосередньо до таблиць.
Едуардо Молтені,

Столи не розроблені для використання в якості елементів дизайну. Це поганий стиль.
Sebi2020

0

Crappy виправлення, але це працює ...

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>

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

}

використовувати проміжок істеад внутрішніх дівок

<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


Чи не відповідає ця відповідь тим самим рішенням? stackoverflow.com/a/284064/547733
Максим Россіні

1
ти маєш рацію, мадмокс! Це не так надійно. Також я розумію, що встановлення вирівнювання тексту вліво або вправо означає, що це ніколи не буде працювати на сайті з перекладами, що включають перемикання порядку читання зліва направо на право наліво. Вирівнювання тексту - це для вирівнювання тексту, а не елементів. В ідеалі найближчим часом ми будемо залежати від дисплея: flex для подібних речей.
Wray Bowling

0

Це один із способів зосередити що-небудь в межах діва, не знаючи внутрішньої ширини елементів.

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

-7

додайте цей css до класу product_container

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

Питання конкретно говорить "без ширини"
Dez Udezue
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.