FoxWeb

софт для студентов

Рецепты вёрстки. Кроссбраузерный inline-block

Раздел: Интернет, веб-технологии Автор: Антон Грахов
E-mail: спаму - нет! Www: http://grakhov.com
Просмотров: 20906 Дата: 24.04.2009
Перевод статьи http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block

Давно я по этой теме ничего не постил. Сегодня будет перевод статьи, которая 2 месяца назад была опубликована в блоге Мозиллы. Она про эмуляцию табличного поведения блоками с помощью display: inline-blockЯ еще тогда хотел её перевести, но было лень. Итак, поехали.

Ох уж это выравнивание блоков в одну линию, столь красиво выглядещее на экране, но с которым так много проблем. Достаточно часто ко мне поступают PSD-файлы следующего вида:

Gallery Design

и я готов расплакаться.

Как правило, выставляется фиксированная ширина, высота и каждому элементу float: left. Но по дизайну каждый элемент может иметь разное количество контента, что приведет к разрыву верстки:

Broken Layout with float:left

Поскольку 1-ая картинка в этой галерее длиннее, чем остальные, то 5-ая картинка, начинающая следующую строку, будет обтекать ее. По сути нам нужна растягивающаяся таблица, но в семантической разметке.

Начнем с того, что создадим ненумерованный список, и присвоим элементам этого списка display: inline-block;

<ul>
<li>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
alt="lobster" width="75" height="75"/>
</li>
...
<ul>

<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: inline-block;
margin: 5px;
}
</style>

И это будет хорошо выглядеть в браузерах Firefox 3, Safari 3 и в Opera:

Step 1

Очевидно, что что-то не так с вертикальным выравниванием. На самом же деле это правильное поведение (inline-элемента, прим. переводчика), но это не то, что нам нужно.

Так что же происходит с базовой линией (baseline) всех элементов <li>, когда они были выровнены по базовой линии элемента <ul>? И что вообще такое «базовая линия», спросите вы. Лучше один раз увидеть, чем сто раз услышать:

Baseline

Вот как раз та линия, подчеркивающая текст, и называется базовой. По умолчанию значение вертикального выравнивания у элемента inline или элемента inline-block равно baseline, что означает, что базовая линия этих элементов будет совмещена с базовой линией родительского элемента. Ниже проведена базовая линия для нашего примера:

Baseline illustration

Как вы видите, базовая линия каждого элемента совпадает с базовой линией текста “This is the baseline”. Этот текст не помещён в элемент <li>, просто он так же находится внутри элемента <ul> (с семантической точки зрения так делать нельзя, прим. переводчика), который для всех элементов внутри него является базовым.

Во всяком случае, эту проблему легко устранить, выравнив все дочерние элементы по верхнему краю с помощью vertical-align: top. В результате получаем то, что нужно:

Inline block 2

Но это еще не будет работать в браузерах Firefox 2, IE 6 и 7:

inline-block-ff2

Начнем с Firefox 2.

Этот браузер не поддерживает inline-block, зато поддерживает специфичное -moz-inline-stack, которое даёт аналогичный эффект. И когда мы добавляем его до display: inline-block, FF2 проигнорирует второе объявление и будет использовать -moz-inline-stack, так как не поддерживает значение inline-block. Браузеры, понимающие inline-block будут использовать его и проигнорируют свойство со специфичным только для FF значением.

<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
}
</style>

К сожалению, у решения есть небольшой баг:

Inline Block in Firefox 2

Честно говоря, я не знаю, чем вызван этот баг, но зато предлагаю вам простое решение этой проблемы. Необходимо содержимое каждого элемента <li> завернуть в <div>:

<li>
<div>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
alt="lobster" width="75" height="75"/>
</div>
</li>

Это выглядит как «сбрасывание» (reset) всего внутри элементов <li> и делает их отображение правильным.

Inline block 2

Добрались до IE 7. Этот браузер так же не поддерживает inline-block, но мы можем использовать трюк, позволяющий выводить элементы <li> также, как если бы мы использовали тот самый inline-block. Как? HasLayout, магическое свойство IE, позволяющее решать многие проблемы. Вы не можете явно задать этот самый HasLayout, написав что-то вроде HasLayout: true, или что-то наподобие этого, но вы можете задать его другими путями, например с помощью zoom: 1.

Результатом использования hasLayout является элемент, с установленным hasLayout в true, влияющим на вывод этого элемента и его дочерних элементов (совместив это с минимальной высотой и шириной, получаем нечто похожее на display: block). В некоторых ситуациях достаточно всего лишь навсего использовать hasLayout и проблема сама исчезает.

Когда мы добавили zoom: 1 и *display: inline (star hack для IE 6 и 7) к элементам <li>, мы заставили в IE 7 вести себя их так, как если бы они были строчными (inline-block).

<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
}
</style>

inline-block-ie7

Уф! Почти разобрались. Осталось только IE 6 образумить:

inline-block-ie6

IE 6 не поддерживает указание минимальной высоты, но благодаря неверной работе этого браузера с высотой, мы можем обойти эту проблему. Зададим _height (IE6 underscore hack) в 250px дающую всем элементам <li> высоту в те самые 250px, и если контент превышает эту высоту, то блок будет растягиваться по высоте, чтобы вместить этот контент полностью. Все другие браузеры будут игнорировать указанную таким образом высоту.

Итак, после всей проделанной нами работы взглянем на окончательный CSS и HTML:

<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
_height: 250px;
}
</style>

<li>
<div>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
alt="lobster" width="75" height="75"/>
</div>
</li>

Вот в принципе и вся статья. Кроме оригинала статьи, можно там же почитать и комменты к ней.

Комментарии

Комментариев пока нет.
Но ты можешь стать первым :)

Оставить комментарий

Ваше имя

Ваш комментарий

Код   Защитный код. Если вы не видите здесь рисунок - обновите страницу.
Оценка   

Заметки по этой теме