Кроссбраузерные инлайновые блоки

Ах, инлайновые блоки, такие ненадежные и такие заманчивые в использовании, обещающие много, но дающие мало :) Сколько раз я получал PSD файлы подобные такому:

Дизайн галлереи

и чуть не плакал...

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

Разорванный шаблон с float:left

Так как первый элемент галереи выше остальных, пятый элемент оплывает его слева, вместо того чтобы быть под ним. А мы хотим макет с гибкостью таблицы и семантичной разметкой данных.

Начнем с простого, ненумерованного списка и отобразим его элементы инлайновыми блоками.

  1. <ul>
  2. <li>
  3. <h4>Что-то</h4>
  4. <img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
  5. alt="lobster" width="75" height="75"/>
  6. </li>
  7. ...
  8. <ul>
  9. <style>
  10. li {
  11. width: 200px;
  12. min-height: 250px;
  13. border: 1px solid #000;
  14. display: inline-block;
  15. margin: 5px;
  16. }
  17. </style>

Это выглядит нормально в Firefox 3, Safari 3 и Opera:

Шаг 1

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

Что происходит с базовой линией каждого li и и где находится базовая линия ul? вам интересно где базовая линия? Одна картинка стоит тысячи слов:

Базовая линия

Базовая линия - это черная черта, идущая под текстом. По умолчанию инлайновые тэги и инлановый блочные тэги выравниваются по вертикали по базовой линии родительского элемента. Здесь видно как проходит базовая линия элементов:

Базовая линия

Как вы видите, базовая линия выровнена с базовой линией текста "This is the baseline". Этот текст не в li, а просто в ul, чтобы показать базовую линию списка.

Так или иначе, но исправить это просто: vertical-align:top и получим в результате:

Инлайновые блоки 2

Но это до сих пор не работает в Firefox 2, IE 6 и 7

Инлайновые блоки в Firefox 2

Начнем, пожалуй, с FF2.

Firefox 2 не поддерживает inline-block, но у него есть устаревший ныне параметра '-moz-inline-stack', который ведет себя почти как inline-block. И когда мы добавляем display:inline-block, FF2 игнорирует его и сохраняет -moz-inline-stack, так как не поддерживает inline-block. А браузеры которые поддерживают - проигнорируют предыдущее объявление display:-moz-inline-stack.

  1. <style>
  2. li {
  3. width: 200px;
  4. min-height: 250px;
  5. border: 1px solid #000;
  6. display: -moz-inline-stack;
  7. display: inline-block;
  8. vertical-align: top;
  9. margin: 5px;
  10. }
  11. </style>

Увы, получили не совсем то что надо:

Инлайновые блоки в Firefox 2

Тут есть простое решение. Добавить в li тэг div.

  1. <li>
  2. <div>
  3. <h4>Что-то</h4>
  4. <img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
  5. alt="lobster" width="75" height="75"/>
  6. </div>
  7. </li>

Он "сбрасывает" все внутри li и делает их нормально отображаемыми.

Инлайновые блоки шаг 2

Теперь, IE7. Он не поддерживает inline-block, но тут есть один трюк. Какой? Магическое свойство IE - hasLayout, которое много где помогает! Вообще говоря, такого свойства нет, то есть так сделать нельзя: hasLayout:true, но можно применить другими способами, например, zoom:1.

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

Когда мы добавили zoom:1 и *display:inline (* это хак для IE6 и 7) к li, IE7 начал отображать их как инлайновые:

  1. <style>
  2. li {
  3. width: 200px;
  4. min-height: 250px;
  5. border: 1px solid #000;
  6. display: -moz-inline-stack;
  7. display: inline-block;
  8. vertical-align: top;
  9. margin: 5px;
  10. zoom: 1;
  11. *display: inline;
  12. }
  13. </style>

Инлайновые блоки в IE7

Уф! Почти готово. Остался только IE6:

Инлайновые блоки в IE6

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

Итак, финальные CSS и HTML:

  1. <style>
  2. li {
  3. width: 200px;
  4. min-height: 250px;
  5. border: 1px solid #000;
  6. display: -moz-inline-stack;
  7. display: inline-block;
  8. vertical-align: top;
  9. margin: 5px;
  10. zoom: 1;
  11. *display: inline;
  12. _height: 250px;
  13. }
  14. </style>
  15. <li>
  16. <div>
  17. <h4>Что-то</h4>
  18. <img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
  19. alt="lobster" width="75" height="75"/>
  20. </div>
  21. </li>

Само собой что хаки IE лучше убрать в отдельные файлы и подключить их через условные коментарии.

Оригинал (en)

Rate It! (Average 0.00, 0 votes)

Related Posts

1 Responses to Кроссбраузерные инлайновые блоки

  1. gravatar

    Доступно, понятно. Спасибо.
    В избранное.
    Как только потребуется, испробую

Leave a Reply

Mail will not be published