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

24 Feb, 2007

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

Ситуация

Метод этот простой, и слово метод даже слишком сильное. Мелкий трюк возникший при верстке вот такого макета: колонки с разным кол-вом контента но разделителем до низу Где не было известно в какой из колонок будет больше текста, а разделитель должен был быть по высоте максимально длинной колонки.

Самым очевидным решением было бы обернуть эти колонки в какой то div, и для этого дива правильно спозиционировать фоновый однопиксельный рисунок ("повторить" рисунок по вертикали). Так сейчас решена идентичная проблема на сайте "A list apart". Решение было описано в статье Faux columnsя когда то писал об этом).

Однако, делать для этого картинку мне было лень.

border + margin

HTML был примерно такой:
  1. <div id="c1">
  2. тут контент
  3. </div>
  4. <div id="c2">
  5. тут контент
  6. </div>
Самый простой CSS, для того что бы колонки встали одна за другой:
  1. #c1, #c2{
  2. float:left;
  3. width:281px;/*не имеет значения =)*/
  4. }
В результате получались две колонки как на дизайне, но пока без разделителя. Этот разделитель не что иное как обычная однопиксельная граница. Ее можно было бы задать для самой длинной колонки, но только если знать какая из них.... Потому зададим пока для обеих:
  1. #c1{border-right:1px solid #ccc}
  2. #c2{border-left:1px solid #ccc}
В результате получилось то, что и ожидалось - сначала был двойной разделитель, а к низу оставалась только граница от большей колонки: двойной разделитель между колонками, и одинарный внизу Отсюда и пришло весьма простое решение:
  1. #c2{
  2. margin-left:-1px
  3. }
В результате, граница правой колонки накладывается поверх границы левой колонки, и мы получаем однопиксельный разделитель между ними. Вот пример того, что получилось (слегка приукрашенный для наглядности). А здесь я раскрасил обе границы в разный цвет.

Таким образом, теперь разделителем всегда будет служить граница большей колонки, поскольку она будет "выглядывать" из-за меньшей.

Можно сразу же развить этот метод и на три колонки, вот что получается:

  • Для трех колонок - интересно что разделители получаются - "умными", то есть они разделяют не до самого низу всю страницу, а разделяют только колонки. (можно поиграться с длиной колонок, что бы увидеть эффект)
  • background вместо border - просто заменяем border на background, и выставляем margin-left равный ширине фоновой картинки.

В конце

Метод, конечно, до боли простой, но избавил от лишнего открытия фотошопа, да и сервер от лишнего миллиона ХТТП запросов, а это немало. :). Вдобавок при изменении ширины колонок, нам больше не нужно изменять параллельно и позицию фоновой картинки как в универсальном методе. И я уверен кто-то уже давно бессознательно пользовался приемом. По использованию отрицательных полей, он напоминает мой недавний пост про "Разделители в меню". Надеюсь это кому-то упростит жизнь так же как и мне.

Буду рад услышать Ваши мысли, советы и рекомендации!

33 комментариев к “Колонки "одинаковой" высоты с разделителем”

1.set440 | 01 Mar, 2007
Ха! Люблю отрицательные маргины и перекрытия бордеров. Баловался даже как-то вкладки таким методом сделал.
2.Genn | 28 Feb, 2007
Для количества колонок больше двух, когда требуется, чтобы все разделители были одинаковой высоты (как на главной странице этого проекта, где они сейчас разной высоты ;)), можно использовать border'ы c двух сторон и инкрементировать margin'ы, не так ли?
3.akella | 27 Feb, 2007
@Gram: тогда проще использовать фоновый рисунок и вот этот прием http://alistapart.com/articles/fauxcolumns/ (или на русском)
4.Gram | 27 Feb, 2007
А что делать, когда задача та же самая -- сэмулировать колонки одинаковой высоты, но в случае, когда мы имеем дело не с разделителем, а с разным фоном у колонок
5.coder | 25 Feb, 2007
Просто гениально! Автору респект.
6.shvets | 25 Feb, 2007
"Новостной проект" (прим. акелла) кодишь?
7.akella | 25 Feb, 2007
@all ну вы прямо засмущали, наверняка ведь много кто уже использует ;), интересно было бы послушать трансформации этой идеи. @shvets: да, сорри, конспирация. =)
8.Neutrino | 25 Feb, 2007
ха, молодец :) все гениальное просто.
9.small-heap-of-sites | 25 Feb, 2007
круто!
10.Zigzag | 25 Feb, 2007
пасиб, примем к сведению. а почему вот здесь http://cssing.org.ua/examples/2equalcols/reallife/english.psd.html фотка нашей Октябрьской площади в день выборов в прошлом году? =)
11.Mkdir | 25 Feb, 2007
О, крутое решение! В мемориз. Юра, респект =)
12.GDie | 25 Feb, 2007
Супер! Пасиба.
13.pepelsbey | 25 Feb, 2007
Шамааан :) Не всегда хватает ума записать такие мини-открытия и иногда получается, что открываешь такие вещи по два-три раза )
14.akella | 25 Feb, 2007
@Zigzag: вот уж не знаю ) вопрос к дизайнеру, а я сразу и не приметил... @игорь: не совсем понял общую ситуацию, можно пример кода? если одну колонку флоатить влево а вторую вправо, то рассчеты становятся чуть труднее. Ведь нужно помнить что указание границы добавляется к ширине дива. И ширина будет 50%+1px. Не совсем понял зачем такой отрицательнй отступ?
15.Игорь | 25 Feb, 2007
я тебе в аську стукнул. или можешь в google talk если юзаешь. igor.morozov[sabaka]gmail.com
16.Игорь | 25 Feb, 2007
Я когда-то делал так, когда фотошопа под рукой не было, а надо было быстро. Потом как-то забыл об этом. Просто проблема в том. Что если #c1 и #c2 задать width:50%; убрать паддинги #c1 {margin-right:-50%} #c2 {float:right} то обе границы не стыкуются :(
17.Dimox | 25 Feb, 2007
Благодарен за отличный способ! Однажды обязательно пригодится.
18.bio | 25 Feb, 2007
отличное решение!
19.Genn | 27 Feb, 2007
Zigzag, когда рисовался первоначальный макет, эта тема была актуальной. С тех пор и кочевала картинка из одной итерации дизайна в другую ;) akella, замечательный прием.
20.nnn | 15 Mar, 2007
Добрый день вот уже второй день маюсь с похожей ситуацией, только одно маленькое но!, может кто подскажет надо сделать две колонки (одинаковой высоты это известно заранее) я их так и делал в принципе, еще до того как почитал статью, но вот с низу с отступом от этих 2х колонок в 5% надо разместить еще один блок, так вот если Firefox размещает его правильно, то iE ни в какую ... причем эксперимент показывает что ie берет 5% процентов от body а не от двух колонок, а мозилка от двух колонок как и задумывалось код следующий: (может кто подскажет решение) .d1{ background: url(Img/bg_1.jpg); height: 93px; width:35%; float:left; position: relative; margin: 0px 0; } .d3{ background:url(Img/bg_2.jpg); height: 93px; width: 65%; float: left; } #style4 { font-size: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; color: #717171; text-align: justify; margin-left:8%; margin-right:40%; padding-top:9%; } текст текст Служба маркетинга компании выбирает рекламный клаттер, это обозначено Ли Россом как осознавая социальную ответственность бизнеса.
21.nnn | 15 Mar, 2007
оо в предыдущем посте нет тэгов :-( div class='d1' - текст div class='d2' - текст div id='style4' - нижний блок
22.akella | 15 Mar, 2007
От чего вы берете 5% - от обертывающего дива? Так задайте для него #wrapper{padding-bottom:5%;} Вот и будет отступ вниз в 5 процентов.
23.nnn | 16 Mar, 2007
так в том то и дело что верхних два блока я не загоняю в общий див, дело в том что если загнать их в один див "шапка", и если float'aми после расставить один слева, другой справа, то они тогда выпадают из "шапки" :-( т.е. если я правильно понимаю флоат выталкивает дивы из потока
24.akella | 16 Mar, 2007
напишите для обертывающего дива #wrapper{width:100%;overflow:hidden}
25.tobto | 20 Mar, 2007
'И я уверен кто-то уже давно бессознательно пользовался приемом' - факт. Бордеры, как показывает практика, - очень сильный метод, который может избавить от болезненного фотошопинга 8)
26.viusha | 05 Apr, 2007
ОГРОМНОЕ человеческое СПАСИБО! А сколько миллионов нервных окончаний было загублено... Эх, знала бы раньше!
27.kost | 14 Apr, 2007
Отлично! Эх, вчера бы мне увидеть такой способ, когда я себя пытался час заставить открыть фотошоп и вырезать пиксел.
28.Oracle | 22 Apr, 2007
Хороший способ, сам недавно для одного сайта аналогичное сделал. Только не работает в Mozilla 1.7. Хрен бы с ней, только вот для того сайта, она все-таки еще актуальна, там посещаемость в день до 200 тыс. юзеров :-) Оставил пока так.
29.e1vin | 15 May, 2007
Недавно верстал макетик своего сайта и сам до такого додумался ;) Так что мысли сходятся иногда у совершенно разных людей.
30.Dimon | 23 Apr, 2008
в FF правая колонка сползает под левую DIV.command{ margin: 0 auto; width:100%; text-align:left; } DIV.leftColl, .rightColl{ float:left;width:50%;padding-left:15px; } DIV.leftColl{ border-right:1px solid #ccc; } DIV.leftColl{ border-right:1px solid #ccc; } DIV.rightColl{ border-left:1px solid #ccc; margin-left:-1px; } DIV.command DIV a{ display:block; margin:0 0 0.3em 0;} Австрия Азербайджан Албания Англия Андорра Армения Беларусь Бельгия Болгария Босния-Герцеговина Венгрия Германия Греция Грузия Дания Израиль Ирландия Исландия Испания Италия Казахстан Кипр Латвия Литва Лихтенштейн Люксембург Македония Мальта Молдова Нидерланды Норвегия Польша Португалия Россия Румыния Сан-Марино Северная Ирландия Сербия Словакия Словения Турция Украина Уэльс Фарерские острова Финляндия Франция Хорватия Чехия Швейцария Швеция Шотландия Эстония
31.akella | 23 Apr, 2008
Попробуйте убрать паддинги и бордеры
32.Dimon | 24 Apr, 2008
akella делал я это но в чем тогда смысл разделителя?
33.akella | 24 Apr, 2008
Там в том ошибка, что когда ты задаешь width:50% и padding:15px; То ширина блока будет 50%+15px а не 50%. Такова модель. И потому они естественно не поместятся, так как сумма их ширин просто больше 100%.