CSS – inline-block and baseline alignment
When we use display:inline-block to place elements next to each other, by default their baseline is aligned to to parent baseline unless vertical-align property of these element is set to something other than baseline .
Here are some examples on how baseline alignment work.
inline-block baseline alignment basic example
The baseline of div element is the baseline of its last line box in the normal flow. Here both divs are aligned based on last text line.
inline-block baseline alignment – empty div
In case div is empty, its baseline is bottom margin edge. Here last text line of first div is aligned with bottom margin edge of second div (as it is empty).
inline-block baseline alignment – div with overflow
In case div has overflow other than visible (e.g. scroll, hidden), its baseline is bottom margin edge. Here last text line of first div is aligned with bottom margin edge of second div (as it has overflow:scroll ).
Кроссбраузерный inline-block
Разрешите представить вам перевод статьи «Cross-Browser Inline-Block», написанной Райном Доэрти холодным февралем 2009 года. В статье рассказывается о верстке элементов списка с установкой для свойства display значения inline-block. Статья об этом, а также о трудностях, возникающих в процессе достижения результата и о методах их «лечения».
Inline-block, заманчивое значение для свойства display, которое обещает очень много, а выполняет совсем мало. Очень часто я получал PSD-файлы, подобные этому:
и плакал.
Обычно такой способ отображения не вызывает проблем. Фиксированная ширина, фиксированная высота, float: left и готово. Если бы не одно, но! Дизайн должен отображаться корректно при любом количестве содержимого. В нашем случае, если в одном из блоков окажется чуть больше данных, то он «сломает» всю сетку.
Так как первый элемент выше следующих, пятый становится не под ним, как нам того хотелось бы, а «обтекает» по правому краю. В общем, нам необходима эластичность таблицы, но в правильной, семантичной верстке.
Начнем с простого примера, где у пунктов списка для свойства display установлено значение inline-block:
This is awesome
.
li
Результат выглядит корректно в Firefox 3, Safari 3 и в Opera:
Кажется, будто что-то не так с вертикальным выравниванием. Говоря по правде, никаких ошибок нет, это как раз корректное поведение браузера, но совсем не тот результат, которого мы бы хотели.
А происходит здесь следующее, базовая линия (baseline) каждого элемента выравнивается с базовой линией родительского элемента . Вы спросите, что такое базовая линия? Лучше один раз увидеть, чем сто раз услышать:
Базовая линия на рисунке выше обозначена линией, идущей через основание символов. Значением по-умолчанию для свойства vertical-align у inline и inline-block элементов является baseline. Это значит, что базовая линия элементов выравнивается с базовой линией родителя. На рисунке ниже представлен пример такого выравнивания:
Как видите, каждая базовая линия блоков на рисунке выше выравнена по базовой линии текста «This is the baseline», который не является элементом . Это просто текстовый узел, находящийся непосредственно в , помещенный туда в качестве индикатора расположения базовой линии элемента .
Получить желаемый изначально вариант выравнивания довольно просто, достаточно для свойства vertical-align указать значение top и получить в результате отличную сетку:
Вот только это не работает в Firefox 2, IE 6 и 7:
Для начала займемся Firefox 2.
Firefox 2 не поддерживает значение inline-block, зато отлично понимает специфичное для Мозиллы значение -moz-inline-stack для свойства display. Оно приводит к результатам, подобным действию inline-block. Когда мы добавляем его перед display: inline-block, то Firefox 2 игнорирует вышеуказанное, так как не понимает его, и использует -moz-inline-stack. Другие браузеры используют inline-block, игнорируя непонятное для них -moz-inline-stack.
К сожалению, это вызывает небольшой баг:
Честно, я не знаю, что является его причиной. К счастью, лечится он довольно просто обертыванием всего содержимого элемента дополнительным .
This is awesome
Теперь перейдем к IE 7. Он тоже не поддерживает inline-block, но мы можем использовать трюк, благодаря которому элементы будут выводиться на экран так, будто используют значение inline-block. Как? Будем использовать hasLayout, волшебное свойство IE, делающее доступными многие манипуляции. Вы не можете явно указать для элемента hasLayout: true или сделать это каким-либо подобным простым образом, однако можете запустить механизм, указав zoom: 1.
Технически элементы с hasLayout, установленным в значение true сами отвечают за рендеринг самих себя и дочерних элементов. Объедините это с min-height и width, и получите результат, очень близкий к display: block. Это как магический порошок, заставляющий исчезать все появляющиеся при отображении проблемы.
Когда мы добавим zoom: 1 и *display: inline (звездочка является хаком для IE 6 и IE 7) для элементов , то научим IE 7 отображать их совсем как inline-block:
Почти готово. Остался лишь IE 6:
IE 6 не поддерживает min-height, но взамен мы можем использовать его неверное обращение к свойству height. Установим для _height (обратите внимание на подчеркивание спереди) значение в 250px и получим все элементы с нужной высотой. Если же содержимое превысит указанную величину, то просто растянет свой контейнер. Все остальные браузеры проигнорируют _height.
Финальный CSS и HTML выглядит так:
li
This is awesome