Для комментариев зарегистрироваться или войти
Либо используйте ваш Open_ID, например аккаунт гугл, яндекс или ЖЖ
 

24 февраля 2010 :Плавающие блоки с фиксированной шириной

Итак, долгожданная статья. Вопреки заголовку свойства display:float здесь не используется, что не отменяет результата.

Неделю назад мне потребовался эффект для создания плавающих блоков фиксированной ширины, примерно как на картинке:

Gallery Design

Если вы пробовали верстать что-то похожее, то знаете в чём подвох.

В общем случае, сверстать этот макет было бы плёвым делом. Фиксированная ширина, фиксированная высота, float:left и готово. Но! Дизайн требует чтобы количество контента могло варьироваться, что означает — если в одном из блоков будет больше контента, то вёрстка поедет:

Broken Layout with float:left

Так как первый блок выше чем другие, пятый блок, обтекает его слева, вместо того чтобы быть ниже. Я потратила немало времени в поисках нужной реализации, и в конце концов вспомнила про свойство display:inline-block, кроссбраузерную реализацию которого, как оказывается, я ровно год назад утянула себе в закладочки. Далее — перевод этой статьи.

Начнём с простой страницы, с не сортированным списком, и установим свойство отображения display:inline-block. Желательно использовать изначально блоковый элемент, такой как <li> для этих целей, т.к. в некоторых браузерах перевод из inline в 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 и Опере:

Step
1

Легко заметить, что что-то не так с вертикальным выравниванием (статью о котором я написала недавно, см. ссылку). Точнее не совсем не так, потому что это правильное отображение, но не то что мы хотели.

Выравнивание здесь проходит по базовой линии каждого элемента <li> относительно родителя <ul>. Что такое базовая линия можно увидеть на картинке:

Baseline

Говоря проще значением по умолчанию для vertical-align в режиме inline или inline-block элемента, является базовая линия, что означает что базовая линия элемента будет расположена также как у родительского. Базовая линия в нашем случае показана на следующем изображении:

Baseline
illustration

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

Inline block 2

За исключением конечно любимых всеми IE 6 и 7, и Firefox 2.

inline-block-ff2

Начнём с Firefox 2.

Firefox 2 не поддерживает inline-block, но он поддерживает браузеро-специфичное свойство ‘-moz-inline-stack’, которое даёт результат как раз как inline-block. И когда мы добавим после него свойство display:inline-block, FF2 проигнорирует неизвестное свойство и оставит -moz-inline-stack, потому что он не поддерживает inline-block. Браузеры которые поддерживают 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;
    }
</style>

(Не путайте также свойство ‘-moz-inline-stack’ с ‘-moz-inline-box’ обсуждаемым в тематическом топике на хабре, это разные вещи).

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

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>

Это поправит всё внутри <li> и заставит их отображаться нормально.

Inline block 2

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

Технически, наличие hasLayout у элемента означает что он отвечает за своё собственное отображение и отображение дочерних элементов. (В комбинации с min-height и width, вы можете получить что-то похожее на display:block). Это похоже на волшебную пыль, которой вы можете посыпать глюки отображения и они изчезнут.

Когда мы добавим zoom:1 и *display:inline (хак со звёздочкой для IE6 и 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

Поскольку в данном примере мы хотели использовать min-height, которое не поддерживается IE 6, но благодаря его неверному отображению свойства height, мы можем использовать его. Установим значение _height (IE6 хак с подчёркиванием) в 250px, это сделает высоту всех <li> как минимум 250px, и если их контент не влезет, они растянутся до нужной высоты. Все остальные браузеры проигнорируют _height.

Итак, после всех усилий, вот финальные стили 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>


я буду очень признательна если вы прокоментируете эту статью

Комментарии:


Чтобы оставить комментарий нужно зарегистрироваться или войти.
Либо волшебно используйте ваш логин в Google, Яндекс, рамблер или ЖЖ чтобы войти через Open_ID
Оставить комментарий как:
Гость:
Сообщение:
Подпишитесь на статьи через RSS

15 самых популярных статей: