Как вертикально выровнять по середине плавающие элементы неизвестной высоты?

У меня есть (горизонтально) центрированный внешний div, содержащий два элемента неизвестной ширины:

<div style='width:800px; margin:0 auto'>
  <div style='float:left'>...</div>
  <div style='float:right'>...</div>
</div>

Оба поплавка по умолчанию выравниваются по верхнему краю и имеют разную/неизвестную и разную высоту. Есть ли способ сделать их вертикально центрированными?

В конце концов я сделал внешний div

display: table

и внутренние дивы

display: table-cell;
vertical-align: middle;
text-align: left/right;

но мне просто любопытно, есть ли способ сделать это с поплавками.


person Yang    schedule 24.09.2012    source источник
comment
Вертикальное выравнивание в html/css более чем уродливо, и основной источник моего болезненного желания шлепнуть весь W3C гниющим трупом IE6, а затем скормить им этот труп.   -  person Marc B    schedule 24.09.2012
comment
@MarcB Вы не одиноки, но это то, с чем нам приходится работать ....   -  person Yang    schedule 24.09.2012


Ответы (3)


Вы не можете сделать это напрямую, потому что поплавки выровнены по верхнему краю. :

Если есть линейный блок, внешняя верхняя часть плавающего блока выравнивается с верхней частью текущего строкового блока.

Точные правила говорят (выделено мной):

  1. внешний верх плавающего блока не может быть выше верха его содержащий блок.
  2. внешняя вершина плавающего блока не может быть выше, чем верхняя часть любого блока или плавающий блок, сгенерированный элементом ранее в исходном документе.
  3. внешний верх плавающего блока элемента не может быть выше, чем верхняя часть любого line-box, содержащего блок, сгенерированный элемент ранее в исходном документе.

  1. Плавающий блок должен быть размещен как можно выше.

That said, you can take advantage of rule #4:

  • Поместите каждый элемент с плавающей запятой внутрь элементов inline-level, которые устанавливают новый < href="https://www.w3.org/TR/CSS21/visuren.html#block-formatting" rel="noreferrer">контекст форматирования блока /BFC), например display: inline-block.
  • Эти оболочки будут содержать числа с плавающей запятой, потому что они устанавливают BFC, и будут располагаться одна рядом с другой, потому что они встроенного уровня.
  • Используйте vertical-align, чтобы выровнять эти оболочки по вертикали.

Имейте в виду, что между оболочками встроенных блоков может появиться некоторое пространство. См. Как удалить пробел между элементами встроенного блока?, чтобы исправить это.

.float-left {
  float: left;
}

.float-right {
  float: right;
}

#main {
  border: 1px solid blue;
  margin: 0 auto;
  width: 500px;
}

/* Float wrappers */
#main > div {
  display: inline-block;
  vertical-align: middle;
  width: 50%;
}
<div id="main">
  <div>
    <div class="float-left">
      <p>AAA</p>
    </div>
  </div>
  <div>
    <div class="float-right">
      <p>BBB</p>
      <p>BBB</p>
    </div>
  </div>
</div>

person Oriol    schedule 24.09.2012
comment
это решение работает, потому что вы помещаете width:49%; даже без float div, оно будет работать. - person Youssef; 29.05.2014
comment
Долго искал подобное решение. Спасибо! - person Mosh Feu; 14.07.2014
comment
Я понимаю, что у этого определенно есть приложения, но мне это кажется обманом. единственное, что здесь делает float: right, — это оправдывает содержание BBB. это display: inline-block и vertical-align: middle, которые на самом деле делают центрирование. на самом деле это не вертикальное центрирование плавающего контента. - person Simon_Weaver; 28.07.2014
comment
Поплавок даже не должен использоваться здесь. Это не служит никакой цели, кроме как оправдать контент, как упоминал @Simon_Weaver. Вместо этого было бы лучше использовать text-align: right, чтобы высота div была частью потока страницы без использования clearfix. - person newms87; 22.12.2014
comment
@ newms87 Возможно, это правда. Но тогда не будет поплавка, так что это не ответит на вопрос. Теперь я думаю, что отвечу на него, даже если немного обману. - person Oriol; 22.12.2014
comment
иногда в читерстве нет ничего плохого (или больше, чем иногда в CSS) ;-) но просто важно, чтобы люди не копировали вслепую такие фрагменты кода, не понимая их по-настоящему, иначе позже они получат неожиданные и запутанные побочные эффекты. - person Simon_Weaver; 24.12.2014
comment
Это не работает по другой причине — содержимое центрировано по вертикали. Если вы измените высоту контейнера вручную, вы увидите, что обе части действительно находятся наверху контейнера. - person greenoldman; 01.01.2015
comment
@greenoldman Если родительский элемент имеет явную высоту, вы можете вставить псевдоэлемент встроенного уровня с height: 100% и vertical-align: middle (сосредоточившись на неизвестной технике). - person Oriol; 02.04.2016

Другим подходом было бы использование flex — это может быть заменой float, если у вас есть две части. Один (плавающий) будет иметь автоматический размер, а второй будет увеличиваться, чтобы занимать весь контейнер. На поперечной оси вы выбираете center и вуаля, у вас есть эффект плавающих и центрированных элементов.

Вот красивая шпаргалка по flex: http://jonibologna.com/flexbox-cheatsheet/

person greenoldman    schedule 01.01.2015
comment
Конечно, вы сталкиваетесь с ужасом IE, когда пытаетесь использовать flex. :-| - person T.J. Crowder; 12.07.2015
comment
Эта шпаргалка очень полезна. - person Ghost Echo; 01.11.2016

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

person Trent Stewart    schedule 24.09.2012
comment
А если у кого-то аллергия на использование таблиц для верстки, можно использовать и css-таблицы (хотя внутри это все еще таблицы). - person jahu; 09.04.2015
comment
Таблица не так хороша, если вам нужен адаптивный макет, который будет естественным образом отображаться под левым элементом на узких окнах просмотра. - person Joel Coehoorn; 26.02.2016
comment
@JoelCoehoorn, это совершенно неверно, если вы используете таблицы CSS. Просто измените отображение таблицы на блочное отображение, когда это необходимо, в правильном запросе CSS. - person NoobishPro; 09.09.2016
comment
@Babydead весь стол... конечно. Для отдельных элементов td в одной строке это странно. - person Joel Coehoorn; 09.09.2016
comment
@JoelCoehoorn, конечно. Однако идея таблицы заключается в том, что все ваши данные представлены одинаково. Я не могу представить ситуацию, когда вам нужно, чтобы элементы вели себя иначе, чем другие, когда они выровнены одинаково в неотзывчивой форме. Я создал более 250 адаптивных веб-сайтов и ни разу не сталкивался с такой проблемой. Я хотел бы увидеть пример, если он у вас есть. Довольно любопытно! - person NoobishPro; 09.09.2016