Центрирование плавающих div внутри другого div

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

У меня есть div, который содержит ряд других div, каждый из которых перемещается влево. Каждый из этих div содержит фотографию и подпись. Все, что я хочу, - это чтобы группа фотографий была сосредоточена внутри содержащего div.

Как видно из приведенного ниже кода, я пробовал использовать как overflow:hidden, так и margin:x auto в родительских div, а также добавил clear:both (как предложено в другой теме) после фотографий. Кажется, ничего не меняет.

Спасибо. Я ценю любые предложения.

<div style="position: relative; margin: 0 auto; overflow: hidden; text-align: center;">
    <h4>Section Header</h4>

    <div style="margin: 2em auto;">

        <div style="float: left; margin: auto 1.5em;">
            <img src="photo1.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo2.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo3.jpg" /><br />
             Photo Caption
        </div>

        <div style="clear: both; height: 0; overflow: hidden;"> </div>

    </div>

</div>

person Darren    schedule 12.08.2009    source источник
comment
возможный дубликат Как центрировать плавающие элементы?   -  person TylerH    schedule 14.10.2014
comment
@TylerH Как так? Просто посмотрите дату, когда его спросили. Похоже, что вопрос в вашей ссылке - настоящий дубликат.   -  person The Pragmatick    schedule 28.02.2015
comment
@ThePragmatick Потому что у него вдвое больше просмотров, больше ответов, больше (и более свежих) действий, и его формулировка служит лучшим каноническим вопросом, чем этот.   -  person TylerH    schedule 01.03.2015


Ответы (7)


Сначала удалите атрибут float на внутренних divs. Затем поместите text-align: center на главный внешний div. А для внутренних divs используйте display: inline-block. Также было бы разумно указать им явную ширину.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>
person Sampson    schedule 12.08.2009
comment
Основной внешний div уже использует text-align: center и, похоже, ничего не делает. Я просто добавил display: inline-block для каждой фотографии и опять же без разницы. Просто для аргументации я добавил явную ширину к div каждой фотографии. Абсолютно никакой разницы. Мне было бы любопытно посмотреть, как вы только что протестировали это, и это работает, а я просто сделал это, и это не имело никакого значения. - person Darren; 13.08.2009
comment
@Darren: ты перестал плавать, когда попробовал? Вы не сможете выполнить то, что хотите, пока вы плаваете / если / вы не установите фиксированную ширину контейнера с плавающими объектами. - person Ken Browning; 13.08.2009
comment
Нет, не знал. Я все еще плачу изображения. Для того, что я хочу - подпись по центру прямо под изображением - я думаю, что мне нужно разместить div. Но если я плаваю div, я не могу центрировать его по отношению к внешнему div? - person Darren; 13.08.2009
comment
О ... Я ошибаюсь. Удаление поплавка похоже на то, что я хочу. Не уверен, что понимаю почему, но ... Большое спасибо. - person Darren; 13.08.2009
comment
@Darren, обратите внимание, что в моем примере кода я не включил плавающий;) Прочтите внимательнее в следующий раз, это избавит вас от разочарования :) Но я рад, что вы это поняли. Продолжайте в том же духе и добро пожаловать в SO. - person Sampson; 13.08.2009
comment
Спасибо. Все, что я могу понять, это то, что я смотрел на этот блок кода самостоятельно в течение двух дней подряд, и я просто не понял того факта, что вы пропустили поплавок. В следующий раз постараюсь уделить больше внимания. Еще раз спасибо. - person Darren; 13.08.2009
comment
Этот подход начинает давать сбой, когда некоторые подписи к изображениям становятся достаточно длинными, чтобы переносить строку. Есть другие предложения? - person grae.kindel; 15.09.2011
comment
Неважно, обнаружил, что проблема с изменяющимся количеством строк в заголовках может быть решена с помощью 'vertical-align: top'. знак равно - person grae.kindel; 15.09.2011
comment
Все, чего я не знаю, есть на SO. Значит ли это, что теперь я все знаю? Спасибо! - person ThdK; 07.06.2012
comment
@ThdK Нет. Но это означает, что у вас есть доступ ко всему, о чем вы не знаете;) - person Sampson; 07.06.2012
comment
@Cerin Он должен работать нормально. Вот контрастирующие примеры: jsfiddle.net/jonathansampson/y4yhu - person Sampson; 11.03.2013
comment
есть решение без inline-block? по крайней мере, он не поддерживается в IE7 (возможно, IE8 тоже не уверен) - person Rodolfo; 29.08.2013
comment
@Rodolfo, если вы находитесь в точке, где это работает для вас в ваших современных браузерах, и вы точно знаете, что вам нужно поддерживать IE7, тогда вы можете использовать подход с использованием инфраструктуры JavaScript, такой как jQuery, для добавления специальных селекторов IE7 на вашу страницу, когда JavaScript обнаруживает IE7. Или вы можете прикрепить к своей странице таблицу стилей IE7 в условных комментариях. Как бы то ни было, это отличный ответ! - person klewis; 05.05.2014

С помощью Flexbox вы можете легко горизонтально (и вертикально) центрировать плавающих дочерних элементов внутри div .

Итак, если у вас простая разметка, например:

<div class="wpr">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>

с CSS:

.wpr
{
    width: 400px;
    height: 100px;
    background: pink;
    padding: 10px 30px;
}

.wpr span
{
    width: 50px;
    height: 50px;
    background: green;
    float: left; /* **children floated left** */
    margin: 0 5px;
}

(Это (ожидаемый - и нежелательный) РЕЗУЛЬТАТ)

Теперь добавьте в оболочку следующие правила:

display: flex;
justify-content: center; /* align horizontal */

и плавающие дочерние элементы выравниваются по центру (ДЕМО)

Просто для удовольствия, чтобы получить вертикальное выравнивание, просто добавьте:

align-items: center; /* align vertical */

ДЕМО

person Danield    schedule 06.03.2014
comment
еще нужно проверить совместимость с браузером, но это, похоже, потрясающе! - person low_rents; 23.06.2015
comment
Вы также можете использовать display: inline вместо flex для центрирования div. У Flex есть проблемы с Safari и Opera. - person YOU; 12.02.2016
comment
inline не работает для меня. Проблема этого решения заключается в том, что тогда поля не переходят на вторую строку, если они превышают ширину div. Итак, вы фактически превратили их в стол ... - person Pavel Jiri Strnad; 03.05.2019

Я выполнил вышеупомянутое, используя относительное позиционирование и плавание вправо.

HTML код:

<div class="clearfix">                          
    <div class="outer-div">
        <div class="inner-div">
            <div class="floating-div">Float 1</div>
            <div class="floating-div">Float 2</div>
            <div class="floating-div">Float 3</div>
        </div>
    </div>
</div>

CSS:

.outer-div { position: relative; float: right; right: 50%; }
.inner-div { position: relative; float: right; right: -50%; }
.floating-div { float: left; border: 1px solid red; margin: 0 1.5em; }

.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

JSFiddle: http://jsfiddle.net/MJ9yp/

Это будет работать в IE8 и выше, но не ранее (сюрприз, сюрприз!)

К сожалению, я не помню источник этого метода, поэтому я не могу отдать должное первому автору. Если кто-то еще знает, напишите ссылку!

person Kendolein    schedule 13.02.2014
comment
+1 Это прекрасно работает. Принятый ответ у меня не сработал. Это создавало проблемы с вертикальным выравниванием ... - person TimH - Codidact; 11.04.2014
comment
@TimH Поздно к вечеринке, я знаю, но проблему с вертикальным выравниванием можно исправить, добавив в контейнер 'vertical-align: top' - person Alfie; 08.03.2019
comment
Извините, я имел в виду внутренний div, а не контейнерный div * - person Alfie; 08.03.2019
comment
Работает почти идеально. При переполнении элементы переходят на следующую строку, но когда это происходит, они не центрируются. - person Pavel Jiri Strnad; 03.05.2019

Следующее решение не использует встроенные блоки. Однако для этого требуются два вспомогательных div:

  1. Контент плавает
  2. Внутренний помощник является плавающим (растягивается на столько же, сколько и содержимое)
  3. Внутренний помощник сдвигается вправо на 50% (его левый угол совпадает с центром внешнего помощника)
  4. Контент вытягивается влево на 50% (его центр выравнивается по левому краю внутреннего помощника)
  5. Внешний помощник настроен на скрытие переполнения

.ca-outer {
  overflow: hidden;
  background: #FFC;
}
.ca-inner {
  float: left;
  position: relative;
  left: 50%;
  background: #FDD;
}
.content {
  float: left;
  position: relative;
  left: -50%;
  background: #080;
}
/* examples */
div.content > div {
  float: left;
  margin: 10px;
  width: 100px;
  height: 100px;
  background: #FFF;
}
ul.content {
  padding: 0;
  list-style-type: none;
}
ul.content > li {
  margin: 10px;
  background: #FFF;
}
<div class="ca-outer">
  <div class="ca-inner">
    <div class="content">
      <div>Box 1</div>
      <div>Box 2</div>
      <div>Box 3</div>
    </div>
  </div>
</div>
<hr>
<div class="ca-outer">
  <div class="ca-inner">
    <ul class="content">
      <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
      <li>Nullam efficitur nulla in libero consectetur dictum ac a sem.</li>
      <li>Suspendisse iaculis risus ut dapibus cursus.</li>
    </ul>
  </div>
</div>

person Salman A    schedule 22.11.2014

display: inline-block; не будет работать ни в одном из браузеров IE. Вот что я использовал.

// change the width of #boxContainer to 
// 1-2 pixels higher than total width of the boxes inside:

#boxContainer {         
    width: 800px; 
    height: auto;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}

#Box{
    width: 240px; 
    height: 90px;
    background-color: #FFF;
    float: left;
    margin-left: 10px;
    margin-right: 10px;
}
person Abdulla Kaleem    schedule 20.08.2012

Решение:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Knowledge is Power</title>
        <script src="js/jquery.js"></script>
        <script type="text/javascript">
        </script>
        <style type="text/css">
            #outer {
                text-align:center;
                width:100%;
                height:200px;
                background:red;
            }
            #inner {
                display:inline-block;
                height:200px;
                background:yellow;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner">Hello, I am Touhid Rahman. The man in Light</div>
        </div>
    </body>
</html>
person Touhid Rahman    schedule 23.05.2013
comment
Это решение не по теме. Внутреннее значение должно быть float: left, чтобы соответствовать требованиям OP. - person s15199d; 06.12.2013

В моем случае я не мог получить ответ от @Sampson, чтобы он работал на меня, в лучшем случае у меня был один столбец с центром на странице. Однако в процессе я узнал, как на самом деле работает поплавок, и создал это решение. По сути, исправление очень простое, но его трудно найти, о чем свидетельствует эта ветка, у которой на момент написания этой публикации было более 146 тысяч просмотров без упоминания.

Все, что нужно, - это подсчитать ширину экрана, которую будет занимать желаемый макет, затем сделать родительский элемент такой же ширины и применить margin: auto. Вот и все!

Элементы в макете будут определять ширину и высоту «внешнего» div. Возьмите каждый «myFloat» или ширину или высоту элемента + его границы + его поля и его отступы и сложите их все вместе. Затем таким же образом сложите другие элементы. Это даст вам родительскую ширину. Все они могут быть разных размеров, и вы можете сделать это с меньшим или большим количеством элементов.

Пример (каждый элемент имеет 2 стороны, поэтому границы, поля и отступы умножаются в 2 раза)

Таким образом, элемент, имеющий ширину 10 пикселей, границу 2 пикселя, поле 6 пикселей, отступ 3 пикселя, будет выглядеть так: 10 + 4 + 12 + 6 = 32

Затем сложите вместе всю общую ширину вашего элемента.

Element 1 = 32
Element 2 = 24
Element 3 = 32
Element 4 = 24

В этом примере ширина «внешнего» div будет 112.

.outer {
  /* floats + margins + borders = 270 */
  max-width: 270px;
  margin: auto;
  height: 80px;
  border: 1px;
  border-style: solid;
}

.myFloat {
    /* 3 floats x 50px = 150px */
    width: 50px;
    /* 6 margins x 10px = 60 */
    margin: 10px;
    /* 6 borders x 10px = 60 */
    border: 10px solid #6B6B6B;
    float: left;
    text-align: center;
    height: 40px;
}
<div class="outer">
  <div class="myFloat">Float 1</div>
  <div class="myFloat">Float 2</div>
  <div class="myFloat">Float 3</div>
</div>

person dimmech    schedule 25.08.2016
comment
Это ответ, который я искал, спасибо. Как вы рассчитываете нужный вам пиксель? Мне непонятно. - person SilverSurfer; 14.02.2018