Как сделать колонки одинаковой высоты css. Блоки равной высоты в строке. Почему же так происходит

  • Перевод

Раньше, когда все верстали с использованием таблиц, создать колонки одинаковой высоты было очень просто. Достаточно создать таблицу, например, с 3мя колонками и все они автоматически будут иметь одинаковую высоту. Но в блочной верстке не все так просто.
В этой статье я расскажу вам о некоторых способах создания колонок равной высоты и о совместимости этих методов с браузерами (включая IE6). Все эти способы описывают создание 3х колоночного макета.

Способ 1. Использование свойства display: table

Для реализации макета используется список (ul) или блок div с вложенными в него блоками для строки и каждой из колонок. Обрамляющему блоку div присваивается значение display: table , а каждому вложенному блоку-колонке значение display: table-cell .
Рассмотрим пример со списком.
HTML код:


  • .....Lots of Content....

  • .....Lots of content....

  • .....Lots of content....



CSS:
.base {
/*make it 100% width and a minimum of 1000px width*/
width: auto;
margin-left: 0px;
margin-right: 0px;
min-width: 1000px;
padding: 0px;
display:table;
}
.base-row {
Display: table-row;
}
.base li {
display: table-cell;
width: 33%;
}
.cell1 {
background-color: #f00;
}
.cell2 {
background-color: #0f0;
}
.cell3 {
background-color: #00f;
}

Преимущества:

Это наиболее простой и легкий способ создания колонок одинаковой высоты, в отличие от других методов.
Внешний отступ (margin , как cellspacing для таблиц) равный для всех колонок создать не получится, однако, его можно заменить границей белого цвета (или цвета фона колонки) с соотвествующей шириной для иммитации отступа.

Недостатки:

Этот метод не работает в браузерах IE7 и ниже. Пройдет немало времени (когда IE7 станет новым IE6), прежде чем мы сможем без опаски использовать этот метод.

Способ 2: Использование JavaScript

Этот метод основан на использовании небольшого JS кода (JQuery), который “расставляет” нужную высоту каждой колонке на основе высоты наиболее длинной из них.
HTML код:

… Lots Of Content …

…. Lots Of Content …

… Lots Of Content …


CSS:
.container {
Width: 900px;
Margin-left: auto;
Margin-right: auto;
}
.leftsidebar {
Float: left;
Width: 33%;
}
.content {
Float: left;
Width: 33%;
}
.rightsidebar {
Float: left;
Width: 33%;
}

JavaScript (jQuery):
function setEqualHeight(columns)
{
var tallestcolumn = 0;
columns.each(
function()
{
currentHeight = $(this).height();
if(currentHeight > tallestcolumn)
{
tallestcolumn = currentHeight;
}
}
);
columns.height(tallestcolumn);
}
$(document).ready(function() {
setEqualHeight($(".container > div"));
});

Вы можете положить JS код в отдельный файл и вызвать его непосредственно в HTML коде. В этом случае, инициализация JQuery должна быть по коду расположена выше.
Код, который вам нужно изменить – это название класса блока, который создает колонки. В данном примере это класс container:

Вы можете изменить название класса блока с колонками или, даже, добавить класс к каждому блоку-колонке и использовать их раздельно, для удобства.

Преимущества:

Главное преимущество метода – он работает во всех браузерах и вам не нужно напрягаться с CSS кодом для выравнивания высоты.

Недостатки:

Если JavaScript будет отключен, соотвественно, колонки не будут равной высоты. Но, как правило, это очень редкий случай, т.к. большинство современных сайтов требуют включения JS.

Способ 3: искусственные колонки

Этот метод придуман одним из первых для реализации колонок одинаковой высоты. Суть его в том, что обрамляющему блоку присваивается фон, иммитирующий колонки (см. рис. ниже). Они просто накладываются на этот фон. Эффект равной высоты создается за счет повторяющегося фона.

HTML код:







CSS:
.container {
background-image: tile.png;
background-repeat: repeat-y;
width: 900px;
margin-left: auto;
margin-right: auto;

Leftsidebar {
float: left;
width: 200px;
}

Content {
float: left;
width: 400px;
}

Right {
float:left;
width: 300px;
}

Clearer {
clear: both;
}

Преимущества:

Очень простая реализация.

Недостатки:

Этот метод можно использовать только для макетов/колонок фиксированной ширины.

Способ 4: Использование раздельных блоков с фоном

Этот способ основан на использовании раздельных блоков div, каждый из которых имеет свой фон и принимает значение высоты элемента, который он включает.
HTML код:



…Lots Of Content…

…Lots Of Content…

…Lots Of Content…




CSS:
.rightback {
width: 100%;
float:left;
background-color: green;
overflow:hidden;
position:relative;
}
.contentback {
float:left;
background-color:blue;
width: 100%;
position:relative;
right: 300px; /* width of right sidebar */
}
.leftback {
width: 100%;
position:relative;
right: 400px; /* width of the content area */
float:left;
background-color: #f00;
}

Container {
width: 900px;
margin-left: auto;
margin-right:auto;
}

Leftsidebar {
float:left;
width: 200px;
overflow:hidden;
position:relative;
left: 700px;
}

Content {
float:left;
width: 400px;
overflow:hidden;
position:relative;
left: 700px;
}

Rightsidebar {
float:left;
overflow:hidden;
width: 300px;
background-color:#333;
position:relative;
left: 700px;
}


Выглядит не просто, не так ли? Главное уяснить 5 основных моментов:
  1. .rightback, .contentback, и.leftback содержат элементы.leftsidebar, .content and .rightsidebar, которые, в свою очередь, содержат текст.
  2. Каждый из вложенных блоков отвечает за цвет/фон колонки. В данном примере
    .leftback соотвествует.leftsidebar,
    .contentback – .content
    и.rightback – .rightsidebar.
  3. Кроме последнего (отвечающего за правую крайнюю колонку), каждому из блоков
    задан отступ справа, равный ширине элемента, прилегающего справа, который содержит фон. В данном примере.contentback (отвечающего за фон.content) сдвинут влево на 300px (что является шириной блока.rightsidebar). (см. рис. ниже)
  4. Колонки.leftsidebar, .content и.rightsidebar расположены друг за другом с определенной шириной.
  5. Они обеспечивают отступ слева равный сумме ширины каждой из колонок, кроме крайней правой. Т.е. они равны=ширина.rightsidebar (300px) и.content (400px) = 700px.(B+G)
На рисунке ниже изображено как располагаются блоки.rightback, .contentback и.leftback. Крайний слева – .rigthback, крайний справа - .leftback.

Пунктирная линия показывает видимую область колонок (блок.rightback обрезан с помощью overflow: hidden).
На картинке ниже черные линии, расположенные ниже красной – это контент элементов
.leftsidebar, .content и.rightsidebar, если им задано свойство float:left и соотвествующая ширина.
Все 3 элемента имееют смещение слева от C, с помощью relative position.
C = B+G

Этот метод подробно описывается в

Перевод: Влад Мержевич

Одна из немногих вещей, которую не так просто сделать с помощью CSS - это создание колонок одинаковой высоты. Существуют разные подходы, у каждого из них есть свои плюсы и минусы, здесь я хочу показать четыре метода.

Задумаемся над тем, что мы подразумеваем под колонками одинаковой высоты. Как правило, мы не хотим, чтобы контент внутри каждой колонки был одинаковой высоты. Если бы это было так, тогда нет никакой проблемы, поскольку высота колонок, естественно, будет такой же. На деле под колонками одинаковой высоты мы имеем в виду колонки, которые выглядят одинаковыми без контента внутри.

Мы можем достичь этого добавляя фон позади колонок, чтобы они казались равной высоты. В результате получим фиктивную одинаковую высоту.

Мне никогда не хотелось использовать фиктивные колонки. Не потому что это плохой метод, а потому что у меня есть пунктик - никогда не применять изображение для сплошной заливки цветом. Из-за этого я разработал собственный метод получения колонок одинаковой высоты, который за неимением лучшего термина буду называть псевдоколонки.

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

HTML

Мы используем тот же HTML, что и в методе фиктивных колонок выше.

Основной контент

CSS

CSS опять же весьма прост. Для разнообразия я выбрал резиновый макет , но вы можете легко всё настроить и для фиксированной ширины.

#container { background: #555; overflow: hidden } #content { float:left; width:75%; background:#eee; } #sidebar { float:left; width:25%; background:#555; }

Кроме использования % вместо px заметьте, что я задал цвет фона для #content и #sidebar . Вам остается только установить его для любой колонки, которая будет выше, но здесь я специально задал цвет для двух колонок.

Основное изменение по сравнению с фиктивными колонками - вместо фонового изображения мы устанавливаем цвет фона. В принципе, это то же самое, что показывать цвет фона контейнера сквозь короткую колонку.

Ограничение следующее - мы заранее должны знать, какая колонка будет короче и в идеале эта колонка должна быть такой на всех страницах сайта. Звучит, как довольно серьёзное ограничение, но на практике, я считаю, одна из двух колонок обычно короче на большинстве, если не на всех, страницах. На тех страницах, где это не так, для исправления достаточно просто добавить больше или меньше контента.

Плюсы

  • Просто настроить.
  • Легко обслуживать.

Минусы

  • Сложнее реализовать для трёх и более колонок.
  • Требуется заранее знать высоту колонок.
  • Не работает, когда колонки выше или короче на разных страницах.

Этот метод далёк от совершенства, но вы удивитесь, насколько часто он может применяться на практике.

На этот метод я наткнулся не так давно на Smashing Magazine в статье Тьерри Кобленца, хотя позже нашёл статью Алана Пирса на A List Apart , написанную несколько лет назад об этом же методе. Используются границы и отрицательные отступы, чтобы создать видимость колонок равной высоты.

HTML

Ничего нового в HTML нет по сравнению с тем, что мы видели выше. В своей статье Тьерри применяет в качестве контейнера body , но я буду придерживаться использования контейнера div как делаю это обычно.

Основной контент

CSS

В CSS начинается самое интересное. Контейнер просто используется для фиксации ширины и выравнивания макета по центру. Интересное происходит с #content и #sidebar .

#container { width:960px; margin: 0 auto; } #content { float:left; width:700px; border-left: 260px solid #555; } #sidebar { float: left; width:260px; margin-right: -260px; position: relative; }

Все фоновые цвета в этом методе устанавливаются для колонки #content . Мы задаём фон как обычно, а затем добавляем левую границу равную ширине боковой панели. Цвет границы совпадает с фоном боковой панели.

Если мы здесь остановимся, то вы увидите отображаемые колонки, однако наша левая граница выталкивает боковую панель прочь и мы должны вернуть её назад.

Вначале дадим боковой панели отрицательный правый margin равный её ширине (или ширине левой границы контента, они одинаковы). Это вернёт боковую панель туда, куда мы и хотим, но она по-прежнему не видна. Проблема в порядке наложения двух дивов. #content располагается поверх #sidebar , так что мы должны переместить #sidebar на передний план. Сделаем это путём добавления position: relative для боковой панели и теперь его содержание становится видно.

Плюсы

Минусы

  • Ширина боковой панели должна быть фиксирована, поскольку border-width понимает только абсолютные значения.
  • Отрицательные margin потенциально могут привести к ошибке в некоторых старых версиях IE.

Рекомендую прочесть обе статьи, ссылки на которые я привёл выше, поскольку они предлагают более детальную информацию, чем я здесь. Обе статьи содержат код для использования этого метода с третьей колонкой, а статья Тьерри рассказывает о создании границ между колонками.

Последний метод создал Мэтью Джеймс Тейлор . Из всех методов представленных здесь, на этот раз он будет работать в самых разных случаях использования.

Я оставил его на конец, так как метод немного сложный и вам, возможно, придётся прочитать несколько раз для понимания как он работает.

HTML

HTML похож на то, что мы видели выше, хотя вы заметите дополнительный контейнер div.

Основной контент

Как и в других методах, мы будем использовать эти контейнеры для установки фоновых цветов, которые появятся, словно они принадлежат нашим колонкам.

CSS

В CSS происходит несколько больше, чем мы видели до этого момента. Для #sidebar и #content задаётся float со значением left и устанавливается ширина, всё остальное помимо этого является новым.

Ключом этого метода выступает идея, что плавающий контейнер всегда имеет ту же высоту, что его содержимое. Размещая наши колонки внутри плавающих контейнеров, мы обеспечиваем, что контейнеры будут равны высоте самой длинной колонки.

#container-outer { float:left; overflow: hidden; background: #eee; } #container-inner { float:left; background: #555; position: relative; right:75%; } #sidebar { float: left; width: 25%; position: relative; left: 75%; } #content { float: left; width: 75%; position: relative; left: 75%; }

Первый шаг - добавить float к колонкам и контейнерам. Я применяю значение left , но направление в данном случае не важно. Используйте направление необходимое для вашего макета. Следующим шагом является установка фонов для двух контейнеров div . Я ставлю фон для #container-inner чтобы получить желаемое для боковой панели и фон для #container-outer чтобы получить желаемое для основного контента.

Если мы остановимся здесь, то увидим фон только для вложенного div , поскольку он по порядку наложения выше, чем внешний div .

Нам нужно немного позиционирования дабы сдвинуть внутренний div так, чтобы он показывался только там, где мы хотим отображать боковую панель. Это позволит фону у внешнего div проступать сквозь него там, где мы хотим показать колонку с контентом.

#container-inner { position: relative; right: 75%; }

Позиционируем внутреннюю колонку и устанавливаем значение right на 75%, оно такое же, как ширина колонки с контентом.

Фоны на месте, но содержимое обоих колонок также сдвигается на 75% влево. Нам нужно сдвинуть их на место.

#sidebar { position: relative; left:75%; } #content { position: relative; left:75%; }

Мы снова применяем относительное позиционирование и поскольку содержимое обоих колонок сместилось на 75% влево, нам надо сдвинуть это обратно на 75% вправо. Сделаем это установкой значения left в 75%. Теперь всё вернулось назад, где и должно быть.

Плюсы

  • Работает независимо от того, какая колонка выше или короче.
  • Работает с любым типом макета (фиксированным, резиновым, эластичным и др.).
  • Можно сделать сколько угодно колонок.

Минусы

  • Немного сложно для первого понимания.
  • Требуются дополнительные несемантичные дивы.

В целом это наиболее надёжный метод и он гарантированно работает в любой ситуации. Я призываю вас поиграть с этим для настоящего понимания и прочитать статью Мэтью несколько раз.

В статье Мэтью идёт макет из трёх колонок и у него также есть демонстрация для четырёх и пяти колонок. Я решил показать макет из двух колонок в надежде что это сделает идею проще для понимания.

Дополнительные ресурсы

Это ни в коем случае не единственные методы создания колонок одинаковой высоты. Крис Койер некоторое время назад поделился несколькими другими методами на CSS Tricks , которые вы можете предпочесть представленным здесь.

Есть также много других методов, которые можно найти немного поискав. Думаю, что данная статья и статья Криса охватывает большинство из наиболее распространённых методов.

Резюме

Колонки одинаковой высоты являются желательной чертой дизайна, но их не всегда легко сделать с помощью CSS-макетов . В идеале мы должны были бы использовать что-то вроде height: 100% и на этом всё, но сейчас мы можем применять любой из методов, упомянутых выше.

просты в настройке, но нужен дополнительный HTTP-запрос для изображения, а любое изменение макета требует новой картинки.

ещё проще, но имеют ограниченное применение для случаев, когда относительная высота обоих колонок известна и постоянна на страницах.

сравнительно просты в работе, не требуют предвидения о высоте колонок и прекрасно адаптируются к нескольким колонкам. Только нужно чтобы одна колонка была фиксированной ширины.

работает в большинстве случаев. Не нужно предварительно знать о высоте колонок и можно работать с любым желаемым числом колонок. Этот метод немного сложнее других.

Со временем я ожидаю более простого стандартного решения, но пока этих четырёх методов должно быть достаточно для вашего проекта.

Насколько часто вы делаете дизайн макета с колонками одинаковой высоты? Какой метод создания колонок вы при этом используете?

Сделать блоки одинаковой высоты, находящиеся в одной строке. Высота блоков зависит от содержимого.

Для решения этой задачи можно воспользоваться одним из . Но тут рассмотрим еще один вариант, который в некоторых случаях удобнее, чем остальные.

Решение

Каждая строка будет обернута контейнером. Этот контейнер по высоте будет равен высоте самого высокого блока в строке (используем особенность растягиваться по высоте с учетом содержимого.). Каждый блок в строке будет иметь дополнительный элемент для оформления своего родителя. Этот дополнительный элемент будет иметь ширину равную родителю, высоту 100% и абсолютное позиционирование. Чтобы высота была равна самому высокому блоку в строке, позиционируем декоративные элементы относительно блока-строки. Для более чистого и семантического кода, в качестве декоративных элементов использую псевдо элементы.

Если объяснения не очень понятны, то пример кода должен все прояснить:

содержимое
содержимое
содержимое
содержимое
содержимое
содержимое

Row { position: relative; /* родитель растягивается по высоте согласно самому высокому дочернему блоку. позиционировать рамки нужно относительно его */ width: 600px; margin-top: 20px; float: left; } .item { float: left; /* сделал флоатами чтобы меньше проблем было с позиционированием рамок */ width: 150px; padding: 5px; margin-left: 20px; } .item:after { content: ""; display: block; width: 160px; /* ширина рамки равна ширине блока-колонки */ height: 100%; /* высота = высоте родителя = высоте самого высокого блока-колонки */ border: 1px solid #0000FF; /* тут может быть любой декор для колонок */ -webkit-box-shadow: 0 0 5px #0000FF; -moz-box-shadow: 0 0 5px #0000FF; box-shadow: 0 0 5px #0000FF; position: absolute; top: 0; left: 20px; /* учитываем отступ слева элемента.item */ z-index: -1; /* чтобы был доступен контент элемента.item */ } /* позиционируем остальные рамки с учетом размеров колонок и отступов между ними */ .item+.item:after { left: 200px; } .item+.item+.item:after { left: 380px; }

Для IE7-8 подключаем дополнительные стили:

Item { z-index: expression(runtimeStyle.zIndex = 1, insertAdjacentHTML("afterBegin", "

")); } .itemDecor { width: 160px; height: 100%; border: 1px solid #0000FF; background: #fff; box-shadow: 0 0 5px #0000FF; behavior: url(pie.htc); position: absolute; top: 0; left: 20px; z-index: -1; } .item+.item .itemDecor { left: 200px; } .item+.item+.item .itemDecor { left: 380px; }

В статье решается проблема выравнивания по высоте контейнеров с текстом разного объема при использовании принципов блочной верстки.

При написании информационных ресурсов довольно часто прибегают к многоколоночной схеме. Другими словами содержимое страницы разбивается на несколько колонок. Такой принцип чаще используется для текстовой части контента. При этом объем текста в каждой колонке может быть разный. Возникает вопрос, каким образом сделать так, чтобы при разной величине текста выровнять по высоте колонки, причем изначально высота блока остается неизвестной. Ниже представлена схема двух разных случаев

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

Фоновый рисунок

Итак, идея вполне предсказуемая и заезженная (так как многие проблемы решаются заменой картинкой), она имеет ряд преимуществ, которые нельзя не отметить:

  • высокие показатели кроссбраузерности;
  • нет никаких проблем с валидацией;
  • используется минимальное количество вспомогательных блоков, что сокращает объем HTML-кода.

Как обычно, не бывает плюсов без минусов:

  • нагрузка на сервер за счет использования дополнительного количества картинок;
  • работает только в том случае, если известна точная ширина колонок.

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

Высоту этой линии рекомендуется использовать величиной 1 пиксель, для экономии размера изображения. Устанавливаем циклическое повторение этой картинки по оси ординат и получаем колонки одинаковой высоты (по крайней мере визуально). Ниже представлен код, с помощью которого реализуется данный метод

HTML

< div class = "background" > < div class = "left" > < div class = "center" > < div class = "right" >

Fon { width: 600px; background: url(fon. png) repeat- y; float: left; } . left { width: 200px; float: left; } . center { width: 200px; float: left; } . right { width: 200px; float: left; }

В итоге в браузере получаем такую картину:

margin + padding + overflow

Это решение я бы описал, как наглое но очень действенное. Принцип работы его заключается в том, что создается родительский элемент с очень большим значением высоты, которое достигается за счет значения свойства padding-bottom , но в тоже время компенсируется таким же отрицательным значением наружного отступа - margin-bottom . И плюс к этому добавляем свойство overflow родителю со значением hidden , что позволит обрезать высоту родителя по высоте самой большой колонки.

Для этого в код записываем

HTML

< div class = "background" > < div class = "left" > < div class = "center" > < div class = "right" >

Background { width: 600px; overflow: hidden; } . left { width: 200px; float: left; background: #fc7777; padding- bottom: 20000px; margin- bottom: - 20000px; } . center { width: 200px; float: left; background: #7780fc; padding- bottom: 20000px; margin- bottom: - 20000px; } . right { width: 200px; float: left; background: #fcaf77; padding- bottom: 20000px; margin- bottom: - 20000px; }

Результат в браузере будет аналогичен предыдущему способу.

Для этого метода будут характерны следующие положительные эффекты:

  • обеспечивает резиновую верстку блоков;
  • исключает нагрузку на сервер за счет наличия дополнительного количества фоновых изображений;
  • положительная реакция на проверку валидности кода;
  • минимизирует использование вспомогательных контейнеров, что сокращает код.

Недостатки:

  • в старых версиях браузера Opera не работает, так как этой программой неверно трактуется свойство overflow .

Метод дополнительных оберток

В этом случае надо создать для каждой колонки дополнительную обвертку с соответствующим цветом, а потом вывести каждый фон для определенной колонки относительным позиционированием. Принцип действия очень сложный для понимания, более подробно о работе этого способа можно узнать у автора идеи – Метью Тейлора. Однако, не вникая в подробности, можно использовать его шаблон, приведенный ниже

HTML

< div class = "background1" > < div class = "background2" > < div class = "background3" > < div class = "left" > < div class = "center" > < div class = "right" >

Background1 { width: 100 %; background: #fc7777; float: left; position: relative; right: 30 %; } . background2{ width: 100 %; background: #7780fc; float: left; position: relative; right: 40 %; } . background3 { width: 100 %; background: #fcaf77; float: left; } . left { width: 30 %; float: left; overflow: hidden; position: relative; left: 70 %; } . center { width: 30 %; float: left; overflow: hidden; position: relative; left: 70 %; } . right { width: 39 %; float: left; overflow: hidden; position: relative; left: 70 %; }

Результат в браузере будет полностью совпадать с предыдущими методами.

Для этого метода стоит отметить следующие положительные характеристики:

  • поддерживается всеми браузерами;
  • соответствует принципам так называемой «резиновой верстки»;
  • сохраняет показатель валидности кода.

Нежелательный эффект рассматриваемой верстки:

  • большое количество дополнительных контейнеров (их количество соответствует числу колонок – обязательное условие для работы метода).

В каких браузерах работает?

6.0+ 1.0+ 9.5+ 3.1+ 2.0+

Проблема создания колонок одинаковой высоты достаточно известна. Суть её в том, что при вёрстке float-блоки колонок имеют разные высоты, согласно своему содержимому.

В идеале же, нужно получить равные колонки

Существуют различные способы добиться этого эффекта. Все они без особого труда находятся в гугле, но в основном методика заключается в иммитации колонок («псевдоколонки»). Делается это за счёт различных смещений (margin и padding ), дополнительные контейнеры, которые «подставляются» под настоящие блоки, фоновые картинки и даже за счёт border .

Всё это конечно интересно, но при создании адаптивного дизайна ни один из этих методов не работает как следует.

Ситуация совсем оказалась печальной, когда я стал работать с «полурезиновой» адаптивной сеткой, где меняется значение float блоков (left и none ), а высота блоков должна меняться к auto при float:none .

Пробившись с этой задачей несколько дней, я пришёл к выводу, что легальных и достаточно простых способов её решить всего ничего:

  • использовать таблицы (table )
  • использовать display: table (и его производные)
  • использовать javascript

Верстку через тэги table рассматривать нет смысла. Вариант с display: table интересен, но только до момента, пока не сталкиваешься с «особенностью» браузеров отображать вложенные блоки вроде PRE на всю ширину браузера, а не table-cell-контейнера. В итоге этот вариант так же пришлось отмести, поскольку все эти мелкие «особенности»-баги перевесили все достоинства метода.

В итоге остался только один вариант - использование js-скрипта, который будет автоматически рассчитывать и выставлять высоты колонок с учетом их «адаптивности».

Нетерпеливые могут посмотреть рабочий .

HTML-разметка

Для демонстрации я буду использовать вот такой html-код:

Две колонки ... тут стили и js-скрипты...

content

sidebar1

Это достаточно типовая схема модульной сетки на две колонки:

  • общий контейнер main
  • два блока-колонки content и sidebar1
  • каждый блок сопровождается своим wrap-блоком

Строго говоря модульная сетка может быть любой, при этом не имеет значения ни её размеры, ни расположение блоков колонок. Это принципиальное отличие от других существующих js-скриптов, где требуется соблюсти определённую вложенность div-блоков. В моём варианте это не играет никакой роли.

Как сделать адаптивность

Существует несколько методик. Самый простой - это «резиновый» дизайн - когда все колонки задаются в процентах. Проблема такого дизайна в широких мониторах. При ширине более 1000-1200px абзацы превращаются в одиночные строчки, что ухудшает читабельность текста. Поэтому обычно ширину сайта ограничивают до 1000px (960, 980px), что позволяет без проблем разместить текст и боковую колонку.

При фиксированной ширине сайта адаптивность осуществляется путём отдельных @media-правил под каждый диапазон разрешений. Достаточно распространён следующий вариант:

@media (min-width: 1200px) { } @media (min-width: 768px) and (max-width: 959px) { } @media (max-width: 767px) { }

То есть сайт верстается с неким базовым разрешением, например 960px. Если разрешение экрана больше 1200px, то прописываются стили, где ширина контента и сайдбара становится больше. Иногда добавляют ещё одну колонку или какие-то блоки.

Если же разрешение ниже базового, то размеры колонок уменьшают. Как только экран становится совсем узким, чтобы колонки отображались в читабельном виде, их размещают уже одна под другой. Обычно для этого достаточно указать

Width: 100%; float: none;

То есть растягиваем на всю ширину и убираем «плавание».

«Полурезиновый» дизайн

Вариант с множеством @media хорош, но несколько трудозатратен. Если подумать, то колонки изначально должны быть резиновыми до какой-то определённой базовой ширины. Если размер экрана более 960px, то ширина сайта не меняется и составляет 960px. Но как только размер уменьшился, то размеры колонок меняются пропорционально друг другу. Как только достигается минимум (совсем узкая колонка), убираем «плавание» и растягиваем блоки на всю ширину.

На демо-примере используется именно такой вариант верстки. Покажу как это делается.

Вначале задаётся общая ширина контейнера:

Div.main { margin: 0 auto; width: 100%; max-width: 960px; }

Первое правило центрирует блок в браузере. Второе - выставляет ширину 100%. Третье ограничивает размеры максимальной шириной. Таким образом размер блока не превысит 960px.

Внутренние блоки позиционируются так:

Div.content { width: 75%; float: right; } div.sidebar1 { width: 25%; float: left; }

Суммарная ширина блоков должна быть равна 100%. Выравнивание float также произвольно. В этом примере контент располагается справа. Чтобы переместить его влево (то есть поменять колонки) достаточно у div.content указать float: left; .

Теперь зададим @media правило для узких экранов (менее 767px):

@media (max-width: 767px) { div.content { width: 100%; float: none; } div.sidebar1 { width: 100%; float: none; } }

// вся полезная ширина сайта (контент + сайдбар) @CONTENT_WIDTH: 960px; // ширина основного сайдбара @SIDEBAR_WIDTH: 250px; // расчет пропорций % для контента и сайдбара (в сумме 100%) @RATIO_CONTENT: 100% - (100% * @SIDEBAR_WIDTH / @CONTENT_WIDTH); @RATIO_SIDEBAR: 100% - @RATIO_CONTENT;

В css-less используем так:

Div.main { ... max-width: @CONTENT_WIDTH; ... } div.content { ... width: @RATIO_CONTENT; ... } div.sidebar1 { ... width: @RATIO_SIDEBAR; ... }

То есть можно указать произвольные размеры (@CONTENT_WIDTH и @SIDEBAR_WIDTH ), LESS сам пересчитает их в проценты.

Равная высота колонок

Алгоритм расчет высот достаточно простой: смотрятся два блока, после этого выбирается тот, который больше и второму блоку выставляется его высота. В моём варианте перед этим выставляется height:auto , с тем, чтобы браузер выставил «правильную» высоту исходных блоков. Если этого не сделать, то высота блоков будет только увеличиваться, но не уменьшаться.

Для того, чтобы отслеживать «адаптивность», я придумал использовать свойство float блоков. Если оно равно none , то ширина блоков должна быть auto и менять высоту уже не нужно.

Вот полный код скрипта:

Function column2height(e1, e2) { e1.css("height", "auto"); e2.css("height", "auto"); if (e1.css("float") != "none") { height_1 = e1.height(); height_2 = e2.height(); if (height_1 > height_2) { e2.height(height_1); } else { e1.height(height_2); } } } $(function() { e1 = $("div.sidebar1"); e2 = $("div.content"); column2height(e1, e2); $(window).resize(function() { column2height(e1, e2); }); });

То есть всё шаманство в функции column2height() , которая первый раз срабатывает при загрузке документа, а второй - при изменени размеров браузера.

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

Достоинства метода

  • Работает с любой html-структурой, где используются float-блоки.
  • Не требует переверстки.
  • Любая ширина колонок.
  • Прост для понимания и модификации.
  • «Полурезиновая»-адаптивность не требует множества @media-правил.
  • Автоматически распознаётся «адаптивность» для рассчёта высоты колонок.
  • Используется настоящая высота колонок, а не «псевдоколонки».
  • Блоки колонок могут быть произвольно оформлены, включая отступы, поля, границы, фоновые изображения, слошные фоны и т.п.

К минусам можно отнести только требование наличия включенного javascript у посетителя. По современным меркам это уже не критично.




Top