DIV-ные колонки одинаковой высоты на CSS

DIV-ные колонки одинаковой высоты на CSS

Описание простейшего способа сделать на тегах DIV колонки гарантированно одинаковой высоты с помощью только лишь CSS.

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

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

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

Предположим, есть следующая разметка: шапка, три колонки (левая, центральная, правая) и подвал страницы.

«!DOCTYPE HTML»
«html»
    «head»
        «title» Пример колонок одинаковой высоты на CSS «/title»
    «/head»

    «body»
        «div class="header"» шапка «/div»

        «div class="left"»   левая колонка       «/div»
        «div class="center"» центральная колонка «/div»
        «div class="right"»  правая колонка      «/div»

        «div class="footer"» подвал «/div»
    «/body»
«/html»

Шаг 1 Первым делом оборачиваем будущие колонки в DIV-контейнер. Например, назначим ему класс columns.

«!DOCTYPE HTML»
«html»
    «head»
        «title» Пример колонок одинаковой высоты на CSS «/title»
    «/head»

    «body»
        «div class="header"» шапка «/div»

        «div class="columns"»
            «div class="left"»   левая колонка       «/div»
            «div class="center"» центральная колонка «/div»
            «div class="right"»  правая колонка      «/div»
        «/div»

        «div class="footer"» подвал «/div»
    «/body»
«/html»

Шаг 2 Осталось прописать в стили сайта следующее:

/* обёртка колонок */
.columns {
    display: table;
    width: 100%;
    -webkit-box-sizing: border-box;  /* фикс для старых Chrome и Safari */
       -moz-box-sizing: border-box;  /* фикс проблемы для Firefox       */
            box-sizing: border-box;  /* не поддерживается в CSS2        */
    margin-left: 0;
    margin-right: 0;
}

/* сами колонки */
.columns » div,
.columns » noindex » div {
    display: table-cell;
    vertical-align: top;
    width: auto;
    position: relative;
    -webkit-box-sizing: border-box;  /* фикс для старых Chrome и Safari */
       -moz-box-sizing: border-box;  /* фикс проблемы для Firefox       */
            box-sizing: border-box;  /* не поддерживается в CSS2        */
}

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

Заметка В CSS2 не поддерживается свойство box-sizing, поэтому для старых браузеров, в случае необходимости указать размеры ячеек, делать это нужно за вычетом значений border- и padding-отступов.

Шаг 3 (опциональный). Теперь если бы мы, например, захотели боковые колонки сделать фиксированного размера, то в стилях просто нужно прописать желаемые ограничительные размеры колонок. Допустим, желаем левую колонку - 300 пикселей, а правую - 200 пикселей и вдобавок с отсечением невольно выступивших за край частей её содержимого.

/* левая колонка */
.columns » .left,
.columns » noindex » .left {
    max-width: 300px;
    min-width: 300px;
    width: 300px;
}

/* правая колонка */
.columns » .right,
.columns » noindex » .right {
    max-width: 200px;
    min-width: 200px;
    width: 200px;
    overflow: hidden;
}

Заметка Такое указание родства объектов, как использовано в продемонстрированном примере, необходимо для гарантии срабатывания стилевых правил лишь на конкретные колонки, принадлежащие непосредственно обёртке. А добавочное причисление случая с тегом noindex служит цели отработать ситуацию, когда SEO-шник сайта решил отдельную колонку закрыть от индексирования поисковыми серверами (нынче в строении интернет магазинов это бывает принципиальной деталью).

Явные достоинства

  • простая реализация;
  • гарантированная одинаковая высота колонок;
  • колонки легко переставляются местами при необходимости;
  • легко добавить дополнительные колонки или изъять лишние;
  • колонки запросто скрываются от индексирования оборачиванием в тег noindex;
  • это не float-решение, поэтому отсутствует дефект "соскакивание колонки на новую строку".

Важная SEO-деталь такого решения состоит в том, что стилизация DIV-колонок под ячейки таблицы не наносит урон поисковому продвижению страницы. Ведь согласно спецификации, стилевые правила описывают, как элементы разметки будут выглядеть на экране браузера, и ни в коем случае не переопределяют тип содержимого элемента. То есть в примере выше стиль лишь предписывал браузеру показывать DIV-колонки ПОДОБНО ячейкам таблицы. Не считать их ячейками, а именно показывать как ячейки. Как же браузер и поисковый робот должны интерпретировать элемент, это задано тегом элемента. В данном примере разметкой было указано, что колонку требуют интерпретировать как DIV (division, раздел), но никак не TD (table division, раздел таблицы) лишь на основании, что элемент станет внешне похожим на ячейку.

Недостатки

  • не работает в браузерах IE6, IE7 - они изначально не поддерживают свойство display: table в стилях;
  • в браузере Safari 3.1 требуется удвоенная обёртка DIV-ами - здесь свойство display: table-cell дочернего объекта первого родства работает при наличии пары родительских контейнеров, вложенных один в другой со свойствами display: table и display: table-row;
  • нельзя использовать боковые margin-отступы у обёрточного DIV-а, если одновременно задаём ему ширину не в форме width: auto, потому что при рассмотрении размеров объекта браузер не принимает во внимание размеры margin-отступов, следовательно правый край объекта "уедет" дальше положенного на величину неучтённого отступа;
  • у колонок не получится задать margin-отступы, потому что браузер игнорирует всяческую манипуляцию такими отступами в объектах со свойством display: table-cell;
  • строго неподвижная фиксация ширины колонок вне зависимости от ширины их содержимого (то есть когда край колонки не сместится, даже если неразрывные части контента вылезут за край) сохраняется только при указании трех ограничительных размеров (свойства width, min-width, max-width) в абсолютных единицах, в то время как использование относительного размера, скажем 20%, не гарантирует удержание ширины на неразрывной части контента, так как неявно позволяет браузеру автоподстройку ширины колонки в заём избыточного пространства соседних колонок с относительным или width: auto размером.

Живое демо

imperacms.com/examples/css-div-cells/index.html - эта демонстрационная страница сделана на основе фрагментов изложенного выше кода. Только всё (html-код и css-правила) объединено в один HTML-файл. В дополнение колонки раскрашены разными цветами и в них добавлен много строчный контент, чтобы сразу был понятен эффект.

Обсуждение

Андрей Sibirtelecom WebStream Улан-Удэ
Адаптивный дизайн уже нормой стал. Неужели живы ещё динозавры, ровняющие колонки?
Тимош SunLine-Net Кривой Рог
Инфузория, мозги прикупи. Адаптивный дизайн и высота колонок не одно и то же.
BoniiR1
И тем не менее. Я до сих пор встречаю в шаблонах equalheight плагин. Наверно решение на основе js выравнивает блоки лучше.
Сергей Baltcom Jelgava Латвия
EqualHeight ни лучше ни хуже. Он создан для bootstrap шаблонов. Выравнивание с помощью css там выполнить проблематично.
Антон
Этот плагин на карточки товаров вобще отлично выравнивает. А больше не знаю куда еще мог быть применится.

Написать комментарийОтветить на выделенный комментарий

Начнём?

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

Допустимые теги

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

  • опционально парные:
    • [shot=image-url] ALT text [/shot]
    • [link=page-url] anchor text [/link]
  • всегда парные:
    • [quote] comment fragment [/quote]
    • [code] source code fragment [/code]
  • одинарные:
    • [youtube=video-url]
  • и "теговые" символы:
    • « и »

Обратите внимание

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