Часто на практике приходится решать задачу группирования и выравнивания контента средствами CSS. Сегодня мы рассмотрим основные способы размещения элементов в горизонтальный ряд.
Материал данной статьи призван помочь начинающим веб-дизайнерам в освоении приемов верстки web-страниц.
Из чего выбрать или методы
Существует несколько способов расположения структурных элементов в ряд в горизонтальной плоскости. Наиболее полезными, с точки зрения практического применения, являются:
- метод «Float»
- метод «Inline-block»
- метод «Table-cell»
Каждый из них имеет свои преимущества, области применения и недостатки. Рассмотрим их по порядку.
«Для рывка» или немного теории
Все структурные элементы HTML можно условно разделить на:
Инлайновые (встроенные) — типа img, span и им подобные. У нас нет возможности менять их фон и задавать им произвольные линейные размеры.
Блочные — занимающие всю ширину родительского блока, всегда начинаются с новой строки — p, h, div.
Наглядный пример встроенных и блочных структур приведен ниже:
Метод «Float»
Как уже известно (см. выше), блочный элемент размещается с новой строки вне зависимости от заданной ему ширины (width). По этому, уменьшая горизонтальный размер div-а, в рядок блочки не построить.
Наиболее популярный (особенно среди начинающих верстальщиков), метод решения это использование свойства float.
CSS свойство float обрело большую популярность и практическую ценность после перехода от табличного способа верстки к блочному.
Float: left (right) трансформирует блочный элемент в плавающий, выравнивает по левому (правому) краю родительского блока и устанавливает обтекание справа (слева) текстом и другими элементами.
Для примера, создадим четыре блока, которые нужно разместить в ряд:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" media="all" type="text/css" href="style.css" /> </head> <body> <div class="bblock">Строим</div> <div class="bblock">горизонтальный</div> <div class="bblock">ряд</div> <div class="bblock">из дивов</div> </body> </html>
И внешнюю таблицу стилей с следующим содержимым:
div { float: left; /*Задаем обтекание*/ line-height: 120px;/*Высота строки + верт. центрирования текста*/ font-size: 40px; background: dodgerblue; color: white; margin-top: 60px; width: 320px; /*Фиксируем ширину блока*/ margin-right: 10px; text-align: center; /*Центрируем текст по горизонтали*/ }
В результате получаем четыре блока, расположенные в горизонтальный ряд и выровненные по левому краю родительского блока:
Иногда на практике бывает необходимо выровнять блоки по правому краю родительского элемента. Изменим обтекание блоков в предыдущем примере:
float: right;
Обратите внимание на надписи, расположенные в блоках. На первый взгляд может показаться, что пример отработал криво. Но на самом деле, браузер обработал код правильно: прочитал блоки сверху вниз, и сделал то, что мы от него просили - выровнял по правому краю. Учтите этот момент при использовании свойства float: right.
Для того, чтобы прервать обтекание элементов с какого-то конкретного места, используйте строчку:
<div style="clear: both;"></div>
В рассмотренном выше примере расстояния между блоками мы задавали при помощи отступа margin-right. Но что делать, если у вас при верстке страницы возникла задача: разместить блоки в ряд, центрировать их, да и еще чтобы отступы были только между ними, но никак не снаружи?
Алгоритм действий следующий.
HTML:
<div class="wrap"> <!--Создаем дополнительную обертку-родительский элемент --> <div class="bblock">Строим</div> <div class="bblock">горизонтальный</div> <div class="bblock">ряд</div> <div class="bblock">из дивов</div> </div>
CSS:
.wrap { width: 1310px;/*фиксируем ширину обертки*/ margin: 0 auto;/*центрируем ее*/ background: darkgray; height: 120px;/*Задаем высоту обертки*/ } .bblock { float: left; /*Задаем обтекание*/ line-height: 120px;/*Высота строки + верт. центрирования текста*/ font-size: 40px; background: dodgerblue; color: white; width: 320px; /*Фиксируем ширину блока*/ margin-right: 10px; text-align: center; /*Центрируем текст по горизонтали*/ } .wrap :last-child { margin-right: 0px;/*Убираем поле последнего div-а*/ }
В результате получаем такую картину:
Ну что же, всех практических ситуаций не рассмотришь, по этому перейдем к общим особенностям.
Важно!!!
- Ширина блоков должна быть фиксированной. Иначе получите что-то такое:
- При уменьшении размера родительского блока или окна веб-браузера, не вмещающиеся блоки перемещаются вниз друг под дружку. Чтобы исключить такой косяк, примените свойство min-width.
- Не забывайте указывать !DOCTYPE вашего документа, иначе, при отображении страницы в IE, применив описанный выше метод горизонтального размещения блоков, у вас появится отступ справа порядка 17px (наверное разработчики под скролл разметили).
- Во избежание различий отображения страницы в разных браузерах, некоторые веб-мастера рекомендуют задавать точные значения свойств margin и padding для body.
- В отличии от метода «Inline-block» вы не столкнетесь с наличием зазора между блоками при отсутствии margin-ов.
- Для задания отступов и полей при размещении элементов воспользуйтесь свойствами margin и padding.
Метод «Inline-block»
Как строчные так и блочные элементы имеют свои преимущества и недостатки в контексте каждой конкретной решаемой задачи. А что если объединить их преимущества?
Встречайте, гвоздь программы — свойство display: inline-block.
display: inline-block генерирует блочно-строчный элемент, который по сути является строчным, но сохраняет блочные свойства — позволяет изменять линейные размеры, задавать поля, отступы и т.д.
Блочно-строчный элемент имеет следующие свойства:
- высота и ширина блока определяется автоматически по содержимому и значению отступов (padding)
- высота и ширина блока может быть задана фиксировано
- Отсутствует эффект схлопывания границ.
Рассмотрим пример создания простого навигационного меню, содержащего картинку и ссылку.
HTML:
<div class="nav"> <p><img src="./vaden-pro-logo.png" alt="" /></p> <p class="string"><a href="#">Ссылка меню 1 длиннее обычного</a></p> </div> <div class="nav"> <p><img src="./vaden-pro-logo.png" alt="" /></p> <p class="string"><a href="#">Ссылка меню 2</a></p> </div> <div class="nav"> <p><img src="./vaden-pro-logo.png" alt="" /></p> <p class="string"><a href="#">Ссылка меню 3</a></p> </div> <div class="nav"> <p><img src="./vaden-pro-logo.png" alt="" /></p> <p class="string"><a href="#">Ссылка меню 4</a></p> </div>
CSS:
.nav { display: inline-block; /*Задаем блочно-строчное отображение*/ width: 180px; /*задаем ширину блока*/ background: dodgerblue; } .string { text-align: center; /*Равняем текст по-горизонтали*/ }
В результате получаем такую менюшку:
Как видим, получилось кривовато… Но расстраиваться мы не намерены, по-этому применяем к нашим дивам CSS свойство vertical-align (подробнее см. ниже):
vertical-align: top;
Теперь наша навигационная панель выровнялась по верхней линии:
Конечно, приведенный пример является примитивным, но я уверен, что на его основе вы сможете создать настоящий шедевр!!!
Важно!!!
- При уменьшении ширины окна обозревателя невмещающийся элемент перемещаеться вниз (как в случае float: left)
- Элемент, отображаемый как inline-block чувствителен к пробелам. Это приводит к тому, что даже при нулевых значениях margin между блоками будет зазор. Зазор этот зависит от применяемого шрифта. Для примера рассмотрим список:
HTML:
<ul> <li>Зазор</li> <li>между</li> <li>блоками</li> </ul>
CSS:
li { display: inline-block; width: 180px; background: darkgrey; color: gold; line-height: 120px; font-size: 32px text-align: center; }
Результатом рендеринга такого кода будет следующая картина:
Есть несколько способов убрать зазоры:
- подобрать отрицательные значения margin:
margin-right: -4px;
- указать font-size: 0 для родительского блока и font-size ≠0 для инлайнового;
ul { font-size: 0px;} li {font-size: 32px;}
- не очень красиво, но все же… Написать код в одну строчку
<li>Зазор</li><li>между</li><li>блоками</li>
Результатом применения любого из выше перечисленных приемов будет следующая структура:
- подобрать отрицательные значения margin:
- Если у вас несколько блочно-строчных элементов подряд имеют разную высоту, то им необходимо задать свойство vertical-align: top. Напомню, что по умолчанию vertical-align присвоено значение baseline.
- Кросс-браузерность.
- Для древних версий Firefox добавляем строчку:
display: -moz-inline-stack;
и оборачиваем элемент в дополнительную div-обертку. - IE 7 и более ранние версии - добавляем строчки:
zoom: 1; /*задаем hasLayout*/ *display: inline; /*звездочка — хак для IE */ _height: 250px; /*в IE6 не работает min-height*/
- Замечу, что на указанные строчки избирательно реагируют конкретные браузеры (на первую — Firefox, на остальные - IE).
Метод «Table»
Табличный подход долгое время был стандартом верстки, что в первую очередь объяснялось простотой и интуитивной понятностью разметки. Скорее всего, именно это и послужило причиной появления табличного форматирования в CSS.
Свойства display: table (table-cell, inline-table), позволяют выполнять табличное форматирование элементов без применения HTML таблиц.
Для горизонтального размещения блоков нам понадобится родительский элемент, имеющий свойство display: table, и дочерние элементы (ячейки), имеющие свойство display: table-cell:
<div class="wrap"> <div class="bblock">Строим</div> <div class="bblock">табличный</div> <div class="bblock">ряд</div> <div class="bblock">из дивов</div> </div>
.bblock { display: table-cell; font-size: 32px; width: 200px; height: 200px; background: gold; text-align: center; vertical-align: middle; } .wrap { display: table; border-spacing: 20px 20px; background-color: darkgray; }
Важно!!!
- В отличии от методов «Inline-block» и «float», при уменьшении ширины окна веб-браузера, ячейки не перемещаются вниз.
- У вас нет возможности задавать свойство margin для ячеек псевдотаблицы.
- Кросс-браузерность. Свойства из семейства display: table* не поддерживаются IE6, IE7. Кроме того, в IE8 вы можете наблюдать динамическую ошибку рендеринга псевдотабличных элементов в виде рандомно пропадающих ячеек. Данная ошибка чаше всего проявляется при первичной прорисовке документа
.