Just

Kitich

web-design

Колонки одинаковой высоты — возвращение

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

Вот тут я наткнулся на интересную статью Алекса Робинсона (Alex Robinson) и Джона Холли-на (Holly 'n John). Казалось бы, простое решение. Но почему я раньше так не делал?

Далее, собственно, мой вольный перевод:

???

Как работник ножа и топора HTML и CSS, Вы, скорее всего, сталкивались с проблемой создания колонок одинаковой высоты в блочной вёрстке. И, вероятно, использовали известное решение проблемы — фальш-колонки (faux columns), предложенные Деном Седерхольмом (Dan Cederholm). (Подробная статья на русском есть у Akella — прим. переводчика) Но вернёмся снова на место преступления :).

Кто?

Настоящим автором метода является Марк Келонер (Mark Challoner), а ваш покорный слуга всего лишь помог дошлифовать его идею.

Что?

Предположим, что мы верстаем страницу блоками и хотим сделать все столбцы одной высоты. Но (!) без использования фоновых изображений.

Вот где-то так это должно выглядеть

Почему?

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

  1. при изменении ширины колонки приходится менять фоновое изображение;
  2. при использовании «резиновой» вёрстки необходимы вообще немыслимые ухищрения;
  3. приходится играться с фоновым изображением, даже если нужен всего-навсего равномерный фон (или даже линия-разделитель между столбцами);
  4. для каждой такой колонки нужен дополнительный div-контейнер;
  5. а некоторые макеты вообще невозможно сверстать таким образом :)

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

Как?

Идея метода состоит в следующем:

  1. блоки-колонки должны быть завёрнуты в div-контейнер;
  2. внешний контейнер обладает свойством overflow: hidden;
  3. нижний внутренний отступ (padding) кононок устанавливается достаточно большим: padding-bottom: $big_value (больше любой допустимой высоты колонки);
  4. в тоже время нижний внешний отступ (margin) устанавливается равной аналогичному отрицательному значению: margin-bottom: -$big_value.

Таким образом, колонки становятся выше на $big_value, при этом всё, что следует за ними, с помощью отрицательного margin'а, «возвращается» вверх, к концу наполнения колонок. А overflow: hidden защищает колонки от переполнения. При этом, нашим колонкам спокойно можно задать любой фон.

Кстати, в IE всё будет работать и без overflow: hidden, но он и никак не помешает, так что убирать необязательно :).

Есть и маленькое «но»: браузеры не позволяют использовать в качестве $big_value бесконечно большое число. Наиболее консервативным в этом вопросе является Safari, диктуя нам максимум в 32767px. В принципе, этого достаточно для большинства случаев. Хотя не стесняйтесь использовать и меньшие значения.

Получается отличный код, не правда ли?

#block_1, #block_2, #block_3 {
  padding-bottom: 32767px;
  margin-bottom: -32767px;
}
#wrapper {
  overflow: hidden;
}

Если нам, например необходим отступ в 0.5em внизу колонки, можно сделать так:

#block_1, #block_2, #block_3 {
  padding-bottom: 1000em;
  margin-bottom: -999.5em;
}

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

Шлифовка

Да-да, не всё так просто, как хотелось бы думать :)

Safari

Не уверен, во всех ли версиях это происходит, но в Safari наблюдается «призрачный» эффект: колонки и фоны отрисовываются нормально, но ссылки и элементы формы, следующие за ними становятся некликабельными. (Исправлено по состоянию на 4 ноября 2005 года).

Проблема решается назначением position: relative нужным элементам, но возникают побочные эффекты в IE 5. Поэтому добавляем ещё и z-index: 1000.

Допустим, у нас есть элемент с id="affected_element", пишем следущее:

* > #affected_element {
  position: relative;
  z-index: 1000;
}

IE Mac 5
IE Mac 5 правильно считает высоту колонок, но прибавляет весь наш невидимый отступ к высоте страницы. Можете считать, что это Вас не касается, но ведь всё должно быть «в ажуре» ;). Нам понадобится простой хак — комментарий с обратным слешом:

/* Start Mac IE5 filter \*/
#block_1, #block_2, #block_3 {
  padding-bottom: 32767px;
  margin-bottom: -32767px;
}
/* End Mac IE5 filter */

Opera (1)

Opera 7.0-7.2 некорректно обрезает расширенные колонки. Добавление свойства display: inline-block контейнеру решает эту проблему, но создаёт новую. Поэтому используем ещё и clear:both для нашего футера.

Теперь всё в порядке везде кроме IE 5.01. Но добавляем float: left и — вуаля! — всё работает.

* html #wrapper {
  float: left;
}

Результат нашей работы.

Opera (2)

Opera 8 тоже не обошлась без сюрпризов, подарив нам некорректную обработку overflow: hidden. Следует отметить, что более ранние версии справлялись сами, безо всяких костылей.

К счастью, есть решение и на этот случай. Просто padding-bottom и margin-bottom необходимо прикручивать не к самим колонкам, а к элементам, в них находящимся.

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

Мы же будем использовать псевдо-элемент :after, поддерживаемый всеми современными браузерами. Но вместо нижнего отступа padding-bottom тогда придётся работать с верхним padding-top, так как мы больше не сможем полагаться на visibility: hidden для скрытия контента.

Конечно, если убрать padding-bottom, вёрстка поползёт в других браузерах, поэтому придётся снова использовать хаки:

/* Start Mac IE5 filter \*/
#block_1, #block_2, #block_3 {
  padding-bottom: 32767px;
  margin-bottom: -32767px;
}
/* End Mac IE5 filter */
@media all and (min-width: 0px) {
#block_1, *#block_2, #block_3 {
  padding-bottom: 0;
  margin-bottom: 0;
}
#block_1:after, #block_2:after, #block_3:after {
  content: '[DO NOT LEAVE IT IS NOT REAL]';
  display: block;
  background: inherit;
  padding-top: 32767px;
  margin-bottom: -32767px;
  height: 0;
}
}

Opera (3)

А теперь «хорошая» новость: предыдущий баг снова иправлен в Opera 9. Так что думайте сами, заморачиваться с ним или нет (думается, 8-я версия уже совсем неактуальна, так что можно было и мне не заморачиваться с этим вопросом — прим. переводчика).

Пример с фиксом для Opera 8.

Где?

Замечательно работает в IE Win 5.01-7, Opera 7-9, Firefox 1.0-2.0, Netscape 8, Safari 1.03 (и выше).

Работает странно в Netscape 6 и 7, IE Mac 5, Opera 5 и 6.

(в Firefox 2 тестировалось мной, в Firefox 3 и IE 8 не тестировалось – прим. переводчика)

Когда?

Всегда! Так как метод кажется достаточно надёжным. Основные найденные проблемы рассмотрены выше.

Альтернативными подходами остаются фальш-колонки и использование display:table, но приведенный здесь метод кажется всё же более гибким и надёжным.

Читать еще:
Подписаться: RSS
Поделиться: в Facebook в ЖЖ в Контакт в Twitter
Оценить: Бяка :(Няка :)
  1. Цікаво та корисно було почитати. Нетривіальний розв'язок проблеми «Як зробити колонки однакової висоти». Самому до такого важко прийти.

  2. 19.12.2008
    kitich #2 Ответить

    Не сказал бы — решение самое, как раз, тривиальное. Но я, например, в его направлении даже не копал бы — слишком все просто :)

  3. В тому той користь від «трюку», що до нього потрібно правильно підійти. Інколи легке рішення проблеми важче знайти і поки до нього докопаєшся, перепробуєш бозна-що, можливо й складнішого за виконанням. Для мене даний метод — нетривіальний, бо обходив його іншою дорогою :)

  4. 19.12.2008
    kitich #4 Ответить

    Кстати, сам пробовал — вылазит странный баг с «якорями» внутри страницы — прокручивается не вся страница в браузере, а контент внутри дива О_О — Расписал подробно возникающую ошибку: kitich.in.ua/blog/43

  5. 19.04.2011
    Григорий #5 Ответить

    Нашел перевод статьи указанной в статье, о «фальш-колонках» www.clearboth.ru/article/fauxcolumns.html

  6. 20.04.2011
    kitich #6 Ответить

    Сама идея, в общем-то, тривиальна. Но спасибо за дополнение темы

*

rss.)))

Что это?