Простой прием или колонки «одинаковой высоты»

10 Sep, 2004

После недавних статей Liquid Bleach и Sliding Faux Columns захотелось это как то обобщить что ли, вобщем говоря изложить на русском. Разумеется ни в коей мере не предендуя на оригинальную идею. К тому же я не нашел перевода статьи Faux Columns (Dan Cederholm) (может плохо искал?). Вот об этой простой технике и о её не менее простом продолжении и пойдет речь.
Сначала понятно как всегда встала проблема.

Проблема

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

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

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

"Фиксированное" решение

Первое решение изложил Dan Cederholm в своей статье на A List Apart называвшейся Faux Columns. Можете подробнее почитать там, а я изложу основной прием.

Пускай эти две колонки содержатся в div'e. И у этого div'а фиксированная ширина (как и у двух колонок, что в нем). Тогда можно использовать вот такую картинку:
почти мой фон
(картинка немного уменьшена, на самом деле её ширина должна совпадать с шириной внешнего div'а). И вместе с тем такой CSS:

#внешнийДИВ{
background: #fff url(bg.gif) repeat-y 0 0;
}

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

"Резиновое" решение

Второе решение всплыло недавно. Наверно правильно будет отнести авторство к двум людям: Douglas Bowman и Eric Meyer. Вот они и изобрели простое решение все той же проблемы, но уже для резиновых страничек. Вот здесь их оригинальные статьи на stopdesign.com и meyerweb.com

Основная идея использованная в этом приёме очень похожа на идею использованную все тем же Бауманом в своей статье Sliding Doors of CSS (на русском+ вторая часть). Прием заключается в создании очень большого изображения (или двух, если дизайн из трех колонок). Картинка должна быть отчасти полностью прозрачной, а в другой части должен содержаться рисунок. Эту картинку нужно, так же как и в первом приеме, повторять вертикально (repeat-y).

Однако сама картинка теперь уже зависит от пропорций вашей странички. Например Мейер использовал в примерах трехколоночный дизайн. Для этого понадобились такие изображения 1000-2000.gif 2000-3000.gif. Эти картинки говорят своими названиями о том, где они непрозрачны. И использовал он разумеется дизайн, где все три колонки имеют ширину 33% от внешнего блока. Тогда нужен такой CSS:

.one {background: url(1000-3000.gif) 33% 0 repeat-y;}
.two {background: url(2000-3000.gif) 67% 0 repeat-y;}

Примеры Мейера слегка усложнены. Я например не сразу понял в чем ключ (секунд десять потерял :))(хотя то вобщем-то не примеры, а тестовый набор) Вот мой пример, он годится лишь для двухколоночного дизайна(66%/33%). Но я думаю его простота поможет кому-то лучше разобраться. Попробуйте посжимать страничку с примером. Вы должны увидеть как меняется ширина правой колонки, но пропорции их остаются прежними.

Вот это собственно и все об этой технике. Как говорит гуру (Мейер) этот трюк поддерживается хорошо. Есть какие-то мелкие глюки на Mac, но нам ли о них горевать.

Ссылки по теме

22 комментариев к “Простой прием или колонки «одинаковой высоты»”

1.Vanav | 10 Sep, 2004
Да, если нужен другой фон для колонки, то это, похоже, единственное решение для такой вёрстки. Хочу сразу предостеречь о небольших недостатках такого подхода (float:left), это не относится к фону колонок, скорее, к верстке с float-колонками вообще: - если внутри контента встречается clear:both (а это реально, если там не просто сплошной текст), то в этом месте порвутся колонки; - колонка с контентом (центральная) всегда будет последней в исходном тексте, если применять метод "в лоб"; - всплывают некоторые баги IE (3px jog etc.), если float контактирует с не-float. Просто всегда радовало, когда гуру описывают новый метод, умалчивая о граблях, поставляющихся в комплекте :)
2.akella | 11 Sep, 2004
Да конечно не без граблей, но ведь главное фон резиновый, а там уже наши проблемы. Тем более, что сейчас наверно на каждый глюк по три хака и по 10 workaround'ов. :)
3.Yukki Pospel | 12 Sep, 2004
Ко всем этим багам есть "фиксы" :) которые можно найти здесь: http://www.positioniseverything.net/
4.Александр | 12 Jan, 2010
с использованием JavaScript без всяких там jQuery страница в три плавающих колонки одинаковой высоты пишется быстрее и красивей, а JS в наше время помоему во всех браузерах работает.
5.Александр | 12 Jan, 2010
кстати насчет кроссбраузерности типа "не существует решения" БРЭД. сам проверял во всех браузерах отлично работает!
6.sonika | 06 May, 2007
Мне понравился Пример Мейера с тремя резиновыми колонками, то, что было нужно в данный момент, спасибо за ссылку! А что сделать в случае, если высота колонок (и всего контейнера div class="container" соответственно) заранее неизвестна? (в примере http://meyerweb.com/eric/css/edge/sliding-faux/demo.html высота .container задана в 300px) Если убрать высоту, IE кушает, а вот Опера и FF картинки 2000-3000.gif и 1000-3000.gif перестают отображать. В %% (вместо пикселей) высота не помогает что-то…
7.akella | 06 May, 2007
Видимо имеется ввиду что колонки сделаны через float, тогда надо что бы эти элементы растянулись до содержащих флоатов А это например можно либо с помощью div class="clr" сразу после колонок и потом .clr{clear:both}. Либо для окаймляющего элемента задавать .parent{ width:100%;/*IE*/ overflow:hidden;/*all others*/ } Если я не так понял, дай ссылку на пример...
8.sonika | 06 May, 2007
Собственно говоря, вот что у меня на данный момент: http://sonika.ru/trash/Sliding-Faux-Columns/demo-my.html (колонки я сделала 22%, 56% и 22% шириной). В IE картинки в background 660-3000.gif и 2340-3000.gif «размножаются» до конца div class="container", а в Опере и FF — только до высоты div class="outer" 300px Если убираю height: 300px; у .outer картинки вообще пропадают.
9.akella | 06 May, 2007
Попробуй заменить вопросительное: height: 300px; /* ??? */ На восклицательное: overflow:hidden; /* !!! */ =)
10.sonika | 06 May, 2007
Юра, спасибо, восклицательные знаки помогли! :)
11.cssing :: Архив :: Блок внизу одной из колонок | 14 Aug, 2008
[...] считать, что кунг-фу колонок одинаковой высоты все уже умеют делать. Тогда после нехитрого CSS, у нас [...]
12.Lost_Sense | 14 Aug, 2008
akella, в твоем примере прописана высота для блоков. если ее убрать то фон исчезает. а фишка же в том и есть, чтоб высота была динамическая и фон растягивался на всю высоту контента. или я что-то не так понимаю?
13.akella | 14 Aug, 2008
Высоту я там забил только чтобы показать фон блоков, почему-то я не догадался просто вбить туда тучу текста =) Это было 4 года назад!! Огого! Все поправил! http://cssing.org.ua/examples/liquidfaux.html, спасибо за указание!
14.Bohdan | 26 Sep, 2008
Друзі, в мене питання по темі але не зовсім.. Є проблема з float:left. Скажімо є перелік блоків thumbnails. У кожному є сталої висоти малюнок, а під ним текст.. Текст різний, відповідно, в результаті одного блоку висота більша ніж в іншого. min-height не панацея, бо лишає велику пустоту внизу (у мене гумовий дизайн, і текст при маленькій роздільній здатності внизу малюнка, а при великій перелазить вправо, бо текст розтягується до ширини блоку). Ось приклад http://domivka.net.ua/temp/eag/pmm2/ . звузьте екран до 800 на 600 і побачите що один із div'ів випадає. Треба щоби при збільшенні розміру блоку з найбільшим текстом, не випадали інші.. В таблицях це легко.. там всі чарунки (ячейки) однакової висоти.. Блоки це не дозволяють робити.. Можна позбочуватися шляхом створення ще одного горизонтального блоку для двох div'ів, але це перебор. Дякую..
15.akella | 26 Sep, 2008
В данном конкретном случае мне кажется лучше запретить тексту сползать под картинку, пусть лучше блоки сползают чуть раньше, зато высота будет определяться картинкой. А?
16.Bohdan | 26 Sep, 2008
тут проблема шо якраз сповзанням тексту під малюнок я вирішую проблему нестачі горизонтального місця для розміщення всіх елементів сайту при 1024 і нижче
17.akella | 27 Sep, 2008
Возможно вам окажется полезной одна из техник http://cssing.org.ua/2008/09/17/adaptive-boxes/ Мне кажется лучше оставлять один блок, при сильном сжатии. ну, либо добавить div style="clear:both" после двух блоков.
18.Bohdan | 27 Sep, 2008
ще є варіант - display:table-row; для двох блоків.. Дякую за консультації. Класний і корисний сайт!
19.Роман | 06 Oct, 2008
Наверное стоит *одинаковой высоты* в заголовке поместить в кавычки. Потому как приведён пример "псевдо-одинаковых" колонок. Кроссбраузерного решения действительно одинаковых по высоте колонок не существует.
20.akella | 07 Oct, 2008
Вы в хорошем смысле педантичны, Роман. Добавил кавычки, хотя кроссброузерное решение вроде ж было? Просто извращенное всякими ИЕ-штучками и display:table. Ну разве трудно парой экспрешнов заставить все отображаться нормально =)
21.Vasser | 29 Dec, 2008
А если просто задать для body фон такого цвета, каким должен быть фон второй колонки? Нормально работает. Для других див"ов просто ставим свой фон. Вот так посто решаем проблему
22.akella | 30 Dec, 2008
Да, можно и так, но это только при условии что мы знаем какая из колонок будет выше-короче.