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

142

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

У меня есть 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>
Даррен
источник
@TylerH Как получилось? Просто посмотрите дату, когда его спросили. Похоже, вопрос в вашей ссылке является реальным дубликатом.
Прагматик
@ThePragmatick Поскольку у этого в два раза больше просмотров, больше ответов, больше (и больше) активности, и его формулировка служит лучшим каноническим вопросом, чем этот.
TylerH

Ответы:

266

Сначала удалите floatатрибут на внутренней стороне divs. Затем наденьте text-align: centerглавное внешнее div. А для внутреннего divс, используйте 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>
Сэмпсон
источник
6
@Darren: ты перестал плавать, когда попробовал? Вы не сможете выполнить то, что вы хотите, пока вы плаваете /, если / вы не установили фиксированную ширину для контейнера с плавающей точкой.
Кен Браунинг
1
Ох ... я ошибаюсь. Удаление поплавка выглядит так, как будто оно выполняет именно то, что я хочу. Я не уверен, что понимаю почему, но ... Большое спасибо.
Даррен
9
@Darren, обратите внимание, в моем примере кода я не включил плавающее значение;) В следующий раз читайте внимательнее, это избавит вас от некоторого разочарования :) Рад, что вы все поняли. Продолжайте в том же духе, и добро пожаловать в SO.
Сэмпсон
2
Этот подход начинает терпеть неудачу, когда некоторые из надписей изображения достаточно длинные, чтобы перенести строку. Любые другие предложения?
greg.kindel
3
Неважно, обнаружил, что проблема с заголовками с переменным количеством строк может быть исправлена ​​с помощью 'vertical-align: top'. =)
greg.kindel
33

С 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 */

и плавающие дети выровнены по центру ( DEMO )

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

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

DEMO

Danield
источник
все еще должен проверить совместимость браузера, но это, кажется, удивительно!
low_rents
Вы также можете использовать display: inline вместо flex для центрирования div. У Flex есть проблемы с сафари и Opera.
ВЫ
встроенный не работает для меня. Проблема этого решения состоит в том, что тогда ящики не переходят на 2-ю строку, если они превышают ширину div. Таким образом, вы на самом деле превратили их в стол ...
Павел Иржи Стрнад
10

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

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 и выше, но не раньше (сюрприз, сюрприз!)

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

Kendolein
источник
+1 Это прекрасно работает. Принятый ответ не работал для меня. Это создало проблемы с вертикальным выравниванием ...
TimH - Codidact
@TimH Поздно, я знаю, но на вечеринке проблему с вертикальным выравниванием можно решить, добавив в контейнер «вертикальное выравнивание: верх»
Алфи
Извините, я имел в виду внутренний div, а не контейнерный div *
Alfie
Это почти идеально работает. Элементы переходят на следующую строку, если переполнены, но когда они это делают, они не центрируются.
Павел Иржи Стрнад,
5

Следующее решение не использует встроенные блоки. Однако для этого требуется два вспомогательных элемента 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>

Салман А
источник
4

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;
}
Абдулла Калим
источник
3

Решение:

<!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>
Тухид Рахман
источник
Это решение не по теме. Внутренняя часть должна быть плавающей: оставлена ​​для соответствия требованиям ФП.
s15199d
1

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

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

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

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

Таким образом, элемент шириной 10px, границей 2px, полем 6px, отступом 3px будет выглядеть так: 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>

dimmech
источник
Это ответ, который я искал, спасибо. Как вы рассчитываете px вам нужно? Мне не понятно.
SilverSurfer