Как стать автором
Обновить

Способ вертикального выравнивания блока с помощью настоящего vertical-align

Время на прочтение 4 мин
Количество просмотров 70K
Сегодня, верстая один макет, я, кажется, изобрел очередной небезынтересный способ вертикального выравнивания блока относительно родительского. Он не основан на превращении блоков в ячейки таблицы и не использует css-свойство position.

Требования

— Должна быть известна начальная высота родительского блока;
— Дочерний блок может иметь произвольный размер как по высоте, так и по ширине.

Возможности

— Работает в IE6+, O9+, FF2+, webkit;
— Тру vertical-align выравнивание со всеми допустимыми значениями;
— Одинаковое поведение во всех браузерах (незначительные отклонение при некоторых условиях в ие6 будут оговорены ниже);
— При вырастании дочернего блока выше «папочки», родительский блок расширяется;
— Ни грамма JavaScript.

Итак, для начала рассмотрим заготовку, которую я хочу использовать для рассказа.
Мы имеем блок .container фиксированной высоты 200px и находящийся внутри него блок с текстом, пусть для определенности нам нужно выровнять его по середине родительского контейнера. Также я добавил снизу обычный текст, который при малой ширине окна перекрывается текстом из контейнера. От этого неприятного эффекта мы тоже избавимся.

Трансформация номер раз


Know how моего метода заключается в том, что вместо того, чтобы указывать настоящую высоту блока .container, мы указываем line-height в те же 200px, а дочерний блок делаем встроенным блоком (display: inline-block;). Самая большая неприятность, которая поджидает во всем методе, заключается в том, что значение line-height наследуется на дочерний блок и для него его придется задать еще раз:
.container {
  line-height: 200px;
}
.block {
  display: inline-block;
  line-height: 1.2;
  vertical-align: middle;
}

И мы получаем вот такую страничку, уже работающую в IE8, O9+, FF3+, webkit. Как я и обещал, при уменьшении окна до такого размера, когда дочерний элемент становиться выше родительского, родительский растягивается. Я нарочно заостряю на этом внимание, так как данное поведение может очень и очень пригодиться в реальных макетах, когда маленький заголовок лучше смотрится посреди строки, а большой должен раздвигать следующий далее контент.

Трансформация номер два


Достигнув такого результат я конечно обрадовался, но естественно, я не верил в успех, пока не проверил в ие6 и 7 и, как оказалось, не зря. На самом деле не все так страшно, как кажется. Ответ на первый вопрос, который у меня возник, я знал заранее: старые ИЕ не могут применять значение display: inline-block к изначально блочным элементам. Сказано-сделано, <div class="block"> без сожаления был заменен на <span class="block">
Но в данном случае это было бестолку и я все равно имел то, что изображено на картинке слева:
image
Почесав репу я за каким-то решил проверить, что будет, если после inline-block элемента поставить настоящий инлайновый элемент, скажем текст. Как ни странно это возымело нужное действие и я получил то, что на картинке справа. Ну что-ж, запишем в копилку глюков ИЕ еще один: одиночный инлайн-блочный элемент принудительно становиться блочным. Осталось только упаковать новый инлайновый элемент так, чтобы он не мешал другим браузерам и не занимал места. Получилось как-то так:
<style type="text/css">
  .iefix {
    display: none;
  }
</style>
<!--[if lte IE 7]>
<style type="text/css">
  .iefix {
    display: inline-block;
    width: 0;
    overflow: hidden;
  }
</style>
<![endif]-->
<div class="container">
  <span class="block">
    Lorem Ipsum is simply dummy text of the printing and typesetting industry.
    Lorem Ipsum has been the industry's standard dummy text ever since the 1500s
  </span>
  <span class="iefix">&nbsp;</span>
</div>

* This source code was highlighted with Source Code Highlighter.

Оставить .iefix чисто инлайновым элементом тоже не получилось, ибо width и overflow применимо только к блочным элементам. Этот же вариант заработал в ие6 без изменений.
Теперь уже пример работал во всех браузерах, которые меня интересуют при верстке кроме FF2. Стоит отметить только один глюк в ИЕ6. Когда размер элемента с текстом уменьшается до размера самого большого слова (или другого элемента, которого невозможно разбить на несколько строк), ИЕ6 все-таки переносить элемент нулевой ширины .iefix на другую строчку, отчего высота всего блока увеличивается на 200 пикселей (величина line-height):
image

Трансформация номер три


Ну и на закуску остался FF2, который как известно, не понимает инлайн-блоков, но может это эмулировать через значение display: -moz-inline-stack;. Свойство -moz-inline-stack требует чтобы его содержимое было обернуто в еще один блок, поэтому HTML код здесь немного разрастается:
<div class="container">
  <span class="block">
    <span>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry.
      Lorem Ipsum has been the industry's standard dummy text ever since the 1500s
    </span>
  </span>
  <span class="iefix">&nbsp;</span>
</div>

* This source code was highlighted with Source Code Highlighter.

Стоит отметить, что FF2 не захотел переносить текст, поэтому пришлось явно задать блоку с текстом width: 100%; в принципе это не так страшно, скорее всего реальная страница будет подразумевать конкретные значения для ширины текста.

В результате получился отличный способ вертикального выравнивания во всех популярных браузерах.
Теги:
Хабы:
+68
Комментарии 59
Комментарии Комментарии 59

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн