4 метода создания колонок одинаковой высоты
Оригинал: http://www.vanseodesign.com/css/equal-height-columns/
Перевод: Влад Мержевич
Одна из немногих вещей, которую не так просто сделать с помощью CSS — это создание колонок одинаковой высоты. Существуют разные подходы, у каждого из них есть свои плюсы и минусы, здесь я хочу показать четыре метода.
Задумаемся над тем, что мы подразумеваем под колонками одинаковой высоты. Как правило, мы не хотим, чтобы контент внутри каждой колонки был одинаковой высоты. Если бы это было так, тогда нет никакой проблемы, поскольку высота колонок, естественно, будет такой же. На деле под колонками одинаковой высоты мы имеем в виду колонки, которые выглядят одинаковыми без контента внутри.
Мы можем достичь этого добавляя фон позади колонок, чтобы они казались равной высоты. В результате получим фиктивную одинаковую высоту.
Желающие сразу смотреть демонстрацию и код могут щёлкнуть на любом изображении идущим перед каждым разделом ниже или обратиться к соответствующему демо.
Фиктивные колонки
Фиктивные колонки существуют уже долгое время. С 2004 года, если быть точным. За это время они были и, возможно, всё ещё остаются методом де-факто для создания колонок одинаковой высоты.
Этот простой трюк использует фоновое изображение которое повторяется по вертикали. Пример такого изображения показан ниже. Я увеличил высоту для наглядности.
Изображение обычно делается высотой в один пиксел, а его ширина совпадает с шириной макета. В том месте, где одна колонка переходит в другую, изображение для фиктивных колонок также должно меняться.
HTML
В этом примере мы будем использовать HTML, похожий на то, с чем мы уже работали, хотя я пропущу шапку и подвал, чтобы сосредоточиться на столбцах.
<div>
<div>
<p>Боковая панель</p>
</div>
<div>
<p>Основной контент</p>
</div>
</div>
Вы можете использовать в качестве контейнера body, но я предпочитаю применять контейнер div. Так вы сможете увидеть, что эта техника работает для создания колонок внутри общего макета, а не только самостоятельно.
CSS
#container {
width:960px;
margin:0 auto;
background: url("faux-columns.png") repeat-y;
overflow: hidden;
}
#sidebar {
float:left;
width:340px;
}
#content {
float:left;
width:620px;
}
CSS довольно прост. Настройка width и float для #sidebar и #content уже должны быть вам знакомы, также как настройка width и margin для #container. Новым здесь является добавление фонового изображения и применение overflow: hidden для контейнера. Нам нужно установить свойство overflow, чтобы контейнер div не схлопнулся и раскрыть обратно всё внутри плавающих элементов.
Контейнер будет той же высоты, что и самая высокая из колонок, а фоновое изображение создаёт эффект, словно короткая колонка имеет аналогичную высоту.
Данный метод лучше всего работает для макетов фиксированной ширины, но также подходит и для большинства резиновых макетов.
Вы также не ограничены простым изменением цвета фона. Границы, тени, узоры и др. могут быть добавлены в соответствующем месте фонового изображения. Для выбранных узоров следует создать изображение высотой больше одного пиксела.
Плюсы
- Легко настраивать.
- Работает независимо от того, какой столбец выше или ниже.
Минусы
- Необходима картинка которая создаёт дополнительный HTTP-запрос.
- Любое изменение макета требует переделки изображения.
- Нужно заранее знать, как будет выглядеть макет для создания изображения.
Псевдоколонки
Мне никогда не хотелось использовать фиктивные колонки. Не потому что это плохой метод, а потому что у меня есть пунктик — никогда не применять изображение для сплошной заливки цветом. Из-за этого я разработал собственный метод получения колонок одинаковой высоты, который за неимением лучшего термина буду называть псевдоколонки.
Он работает аналогично методу фиктивных колонок, который предполагает добавление фона к контейнеру. Это не общий подход к колонкам одинаковой высоты, поэтому он имеет ограниченную область применения, но если вы сталкиваетесь с таким случаем, всё это работает легко и просто.
HTML
Мы используем тот же HTML, что и в методе фиктивных колонок выше.
<div>
<div>
<p>Боковая панель</p>
</div>
<div>
<p>Основной контент</p>
</div>
</div>
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 как делаю это обычно.
<div>
<div>
<p>Боковая панель</p>
</div>
<div>
<p>Основной контент</p>
</div>
</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.
<div>
<div>
<div>
<p>Боковая панель</p>
</div>
<div>
<p>Основной контент</p>
</div>
</div>
</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-запрос для изображения, а любое изменение макета требует новой картинки.
Псевдоколонки ещё проще, но имеют ограниченное применение для случаев, когда относительная высота обоих колонок известна и постоянна на страницах.
Границы и отрицательные отступы сравнительно просты в работе, не требуют предвидения о высоте колонок и прекрасно адаптируются к нескольким колонкам. Только нужно чтобы одна колонка была фиксированной ширины.
Смещение колонок и контейнера работает в большинстве случаев. Не нужно предварительно знать о высоте колонок и можно работать с любым желаемым числом колонок. Этот метод немного сложнее других.
Со временем я ожидаю более простого стандартного решения, но пока этих четырёх методов должно быть достаточно для вашего проекта.
Насколько часто вы делаете дизайн макета с колонками одинаковой высоты? Какой метод создания колонок вы при этом используете?
Одинаковая высота колонок DIV
Время чтения: 3 мин.В сегодняшней статье я хочу рассказать о новом способе создания колонок одинаковой высоты с помощью CSS. Не нужно больше использовать Javascript, чтобы высота колонок стала одинаковой для всех. Суть данного метода заключается в использовании нового свойства CSS3, которое дает нам намного больше возможностей, чем просто создание колонок одинаковой высоты. Но в этом уроке мы рассмотрим как легко можно решить эту наболевшую проблему.
Рекомендую также:
Живая демонстрация:
Посмотреть примерСкачать
А вот скриншот:
Речь в данной статьей пойдет о свойстве flex. О нём я уже писал в данной статье — Вторая часть секретных свойств CSS3.
Разметка страницы
HTML часть
Определим две колонки, которые в дальнейшем будем делать одинаковой высоты с помощью CSS:
HTML КОД
1 2 3 4 5 6 7 8 | <section> <div> <!-- Часть с контентом --> </div> <aside> <!-- Сайдбар --> </aside> </section> |
То есть нам необходимо сделать так, чтобы блок <div> с идентификатором main и блок <aside> имели одинаковую высоту, независимо от содержания внутри любого. Но это еще не всё что нужно сделать. На маленьких экранах боковая сторона должна размещаться под блоком с основным содержимым. Это сделаем для удобства просмотра на мобильных устройствах.
Колонки одинаковой высоты
CSS часть
Определим flexbox для основного контейнера, в котором находятся два блока:
CSS КОД
1 2 3 | #page { display:flex; } |
Сейчас мы преобразовали блок с идентификатором page во flex-контейнер. На данный момент он занимает всю ширину страницы.
Но давайте сделаем для него максимальную ширину 1200px и выровняем по центру:
CSS КОД
1 2 3 4 5 6 7 | #page { display:flex; /* Выравнивание по центру */ max-width:1200px; margin:0 auto; } |
Отлично! Сейчас осталось задать ширину для центрального блока с основным контентом и для сайдбара:
CSS КОД
1 2 3 4 5 6 7 8 9 10 | #main { /* Это свойство позволяет данному блоку растягиваться и занимать всё доступное пространство, не затрагивая сайдбар */ flex-grow:1; } aside { /* Здесь задаем ширину сайдбара по умолчанию и не даем ему сужаться*/ flex-shrink:0; width:280px; } |
Пояснения:
- flex-grow — на сколько один отдельный блок может быть больше соседних элементов.
- flex-shrink — определяет возможность сжиматься при необходимости.
Наша страница близка к завершению. Но когда блок с основным контентом сужается, то страница становится очень длинной. Поэтому при определенной ширине экрана мы можем сделать так, чтобы сайдбар уходил под блок с основным контентом и удобно просматривался на мобильных устройствах:
CSS КОД
1 2 3 4 5 6 7 8 9 10 | @media all and (max-width: 800px) { #page { flex-flow:column; } /* Делаем сайдбар на всю ширину экрана */ aside { width:auto; } } |
Здесь приведен код без префиксов для того, чтобы он не занимал много места и не смотрелся громоздко. Вы можете полностью рабочий пример с помощью кнопки в начале статьи.
Также нужно сказать о том, где работает данный метод. Так как это свойство достаточно новое, то и работает оно в современных браузерах Firefox, Chrome, Safari, Opera и IE 11.
Вывод
Из данной статьи вы узнали как сделать колонки одинаковой высоты на CSS. Но это далеко не все возможности этого CSS свойства. Свойство flex позволяет делать блоки резиновыми, выстраивать элементы автоматически в несколько столбцов или строк, занимая всю свободную область, а также многое другое.
Но самое основное, и, главное, часто используемое решение при верстке страниц, мы рассмотрели в данной статье.
Успехов!
Источник: Оригинал
С Уважением, Юрий Немец
DIV-ные колонки одинаковой высоты на CSS
По роду занятий, сталкиваясь с потребностями начинающих вебмастеров сверстать каркас страницы интернет магазина строго по прихотям заказчика, приходится время от времени подсказывать какие-то мелочи и помогать в нахождении лёгких решений нетипичных задач.
Одна из таких — используя только обожаемую заказчиком DIV-ную вёрстку и вообще не привлекая JavaScript, дать колонкам сайта автоматическое выравнивание высоты по наиболее заполненной колонке, подобно тому как это происходило бы в нелюбимой табличной вёрстке.
Ниже предлагаю элементарное решение на основе всего двух объявлений в стилях сайта и одного обёрточного контейнера в теле страницы. Решение валидно для множества браузеров, кроме IE6-IE7, и при удалении одного свойства из стилей, привнесённых этим решением, может быть преобразовано под браузеры без поддержки CSS3.
Предположим, есть следующая разметка: шапка, три колонки (левая, центральная, правая) и подвал страницы.
<!DOCTYPE HTML> <html> <head> <title> Пример колонок одинаковой высоты на CSS </title> </head> <body> <div> шапка </div> <div> левая колонка </div> <div> центральная колонка </div> <div> правая колонка </div> <div> подвал </div> </body> </html>
Шаг 1 Первым делом оборачиваем будущие колонки в DIV-контейнер. Например, назначим ему класс columns.
<!DOCTYPE HTML> <html> <head> <title> Пример колонок одинаковой высоты на CSS </title> </head> <body> <div> шапка </div> <div> <div> левая колонка </div> <div> центральная колонка </div> <div> правая колонка </div> </div> <div> подвал </div> </body> </html>
Шаг 2 Осталось прописать в стили сайта следующее:
.columns { display: table; width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; 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; -moz-box-sizing: border-box; box-sizing: border-box; }
Здесь мы указали браузеру, что требуем обёрточный контейнер показывать как блочную таблицу на всю ширину родителя, причём для исключения непредвиденных искажений размеры таблицы просим рассматривать по её границам (плюс неучитываемые 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.ru/examples/css-div-cells/index.html — эта демонстрационная страница сделана на основе фрагментов изложенного выше кода. Только всё (html-код и css-правила) объединено в один HTML-файл. В дополнение колонки раскрашены разными цветами и в них добавлен много строчный контент, чтобы сразу был понятен эффект.
DIV-ные колонки одинаковой высоты на CSS
По роду занятий, сталкиваясь с потребностями начинающих вебмастеров сверстать каркас страницы интернет магазина строго по прихотям заказчика, приходится время от времени подсказывать какие-то мелочи и помогать в нахождении лёгких решений нетипичных задач.
Одна из таких — используя только обожаемую заказчиком DIV-ную вёрстку и вообще не привлекая JavaScript, дать колонкам сайта автоматическое выравнивание высоты по наиболее заполненной колонке, подобно тому как это происходило бы в нелюбимой табличной вёрстке.
Ниже предлагаю элементарное решение на основе всего двух объявлений в стилях сайта и одного обёрточного контейнера в теле страницы. Решение валидно для множества браузеров, кроме IE6-IE7, и при удалении одного свойства из стилей, привнесённых этим решением, может быть преобразовано под браузеры без поддержки CSS3.
Объяснение решения
Предположим, есть следующая разметка: шапка, три колонки (левая, центральная, правая) и подвал страницы.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Колонки</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>
Первым делом оборачиваем будущие колонки в DIV-контейнер. Например, назначим ему идентификатор columns.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Колонки</title>
</head>
<body>
<div></div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div></div>
</body>
</html>
Осталось прописать в стили сайта следующее:
#columns {
display: table;
width: 100%;
box-sizing: border-box; /* не поддерживается в CSS2 */
margin-left: 0;
margin-right: 0;
}
#columns > div,
#columns > noindex > div {
display: table-cell;
vertical-align: top;
width: auto;
box-sizing: border-box; /* не поддерживается в CSS2 */
}
Здесь мы указали браузеру, что требуем обёрточный контейнер показывать как блочную таблицу на всю ширину родителя, причём для исключения непредвиденных искажений размеры таблицы просим рассматривать по её границам (плюс неучитываемые margin-отступы с боков погашаем намеренно, иначе размер исказится). А вложенные в эту обёртку первородные DIV-ы призываем показывать как ячейки таблицы с подстраиваемой шириной (подстройку высоты браузер делает сам) и таким же рассмотрением размеров ячеек по их границам, а не по границам содержащегося в них контента.
В CSS2 не поддерживается свойство box-sizing, поэтому для старых браузеров, в случае необходимости указать размеры ячеек, делать это нужно за вычетом значений border- и padding-отступов.
Теперь если бы мы, например, захотели боковые колонки сделать фиксированного размера, то в стилях просто нужно прописать желаемые ограничительные размеры колонок. Допустим, желаем левую колонку — 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 служит цели отработать ситуацию, когда СЕОшник сайта решил отдельную колонку закрыть от индексирования поисковыми серверами (нынче в строении интернет-магазинов это бывает принципиальной деталью).
Явные достоинства
- простая реализация;
- гарантированная одинаковая высота колонок;
- колонки легко переставляются местами при необходимости;
- легко добавить дополнительные колонки или изъять лишние;
- колонки запросто скрываются от индексирования оборачиванием в тег noindex;
- это не float-решение, поэтому отсутствует дефект «соскакивание колонки на новую строку».
Недостатки
- не работает в браузерах 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 размером.
два блока одинаковой высоты / Habr
Задача
Заданы два блочных элемента – один с текстом статьи (ширина 75% от ширины документа), другой с перечнем ссылок для навигации по первому элементу (ширина 25%, расположен слева от первого блока). Высота элемента содержащего статью задается динамически, в зависимости от наполнения блока текстом. Необходимо сделать так, что бы второй блок с навигацией обладал таким же значением параметра высоты как и первый содержащий основной текст статьи.
Техническое уточнение
Ранее подобные задачи решались с помощью TABLE-TR-TD семейства табличных тэгов, но такой подход нарушал принцип отделения структуры данных в разметке (markup — HTML) от способа их стилизации (styling — CSS), поскольки сами данные по характеру представленной информации вовсе не были табличными, а только использовали сходный табличному метод отображения на странице:
<table>
<tr>
<td id=”navigation”>
...перечень a-href ссылок...
</td>
<td id=”content”>
..содержимое статьи...
</td>
</tr>
</table>
Позже стандарт СSS был расширен дополнительными значениями table, table-cell для параметра display, что позволило использовать привычные DIV, SPAN элементы в html-структуре разметки страницы и задавать для них соответствующие css-правила для отображения в виде таблицы с колонками сообщающимися в процентном соотношении как по ширине так и по высоте:
<div id=”wrapper”>
<div id=”navigation”>
...перечень a-href ссылок...
</div>
<div id=”content”>
...содержимое статьи...
</div>
</div>
#wrapper {
display: table;
}
#navigation, #content {
display: table-cell
}
Казалось бы задача была решена, но к сожалению, такой подход не работал в старших версиях браузеров (IE 6, IE 7) заставляя верстальщиков искать другие подходы. Довольно распространенным стало решение с помощью вложенных элементов-оберток смещение которых относительно друг-друга позволяет добиться визуального эффекта равных по высоте колонок:
<div>
<div>
<div>
...перечень a-href ссылок...
</div>
<div>
...содержание...
</div>
</div>
</div>
#navigation, #content {
position: relative;
float: left;
left: -50%;
}
#navigation {
width: 50%;
}
#bg-one, #bg-two {
position:relative;
float: left;
width: 100%;
background-color: #9988ff;
}
#bg-one {
overflow: hidden;
}
#bg-two {
left: 50%;
background-color: #99ff99;
}
Роль колонок здесь выполняют обертывающие тэги (#bg-one, #bg-two) количество которых дублирует вложенные в них тэги с контентом (#content, #navigation). Такая техника работает даже в IE 6, но ее ощутимым недостатком является необходимость добавления большого количества дополнительных элементов (#bg-one, #bg-two) обертывающих тэги с текстом колонок (#content, #navigation). Количество таких элементов оберток (#bg-N) равно количеству фактических блочных-тэгов с колоноками текста. В приведенном выше примере для добавления еще одной колонки (скажем #advertisement) на одном уровне с #navigation и #content придется добавить еще один общий обертывающий элемент bg-three:
<div>
<div>
<div>
<div>
..перечень ссылок a href...
</div>
<div>
..содержание статьи....
</div>
<div>
...рекламные объявления...
</div>
</div>
</div>
</div>
#navigation, #content, #advertisement {
position: relative;
float: left;
left: -64%;
}
#navigation,#content {
width: 32%;
}
#bg-one, #bg-two, #bg-three {
position: relative;
float: left;
width: 100%;
background-color: #9988ff;
}
#bg-one {
overflow: hidden;
}
#bg-two {
left: 32%;
background-color: #99ff99;
}
#bg-three {
left: 32%;
background-color: #a0a0a0;
}
В таком случае html-разметка заметно усложняется – причина наличия обертывающих тэгов неочевидна. Таким образом отказываясь от html-таблиц из-за плохой читабельности разметки мы приходим к еще менее читабельному коду. Ситуацию можно улучшить если перенести обертывающие тэги на один уровень с колонками:
<div>
<div></div>
<div>
..перечень ссылок с a href..
</div>
<div></div>
<div>
...содержание статьи...
</div>
</div>
#wrapper{
position: relative;
float: left;
width: 100%;
}
#navigation, #content {
position: relative;
float: left;
width: 50%;
}
#navigation-bg {
position: absolute;
left: 0;
width: 50%;
height: 100%;
background-color: #ffaaaa;
}
#content-bg {
position: absolute;
left: 50%;
width: 50%;
height: 100%;
background-color: #aaffaa;
}
В таком случае элементы c фоном (#navigation-bg, #content-bg) расположены перед тэгами содержащими текст колонок, что заметно улучшает понимание разметки. Но к сожалению IE 6 не понимает процентных значений заданных в параметре высоты для блочных элементов с абсолютным позиционированием, а для более свежие версии браузеров поддерживают display: table правило, которое позволяет избежать добавочных div-элементов содержащих фон колонок (в примере выше #content-bg, #navigation-bg).
Решение
Читая задание становится заметным что разметка текста с прицелом на последующие применение css-правила display: table, также содержит один лишний тэг:
<div id=”wrapper”>
<nav class=”shakespeare”>
...перечень ссылок...
</nav>
<article class=”shakespeare”>
...содержание статьи...
</article>
</div>
#wrapper {
display: table;
}
.shakespeare {
display: table-cell;
background-color: #f0f0f0;
}
Ведь в таком варианте зависимость высоты колонок двунаправлена, то есть высота блока заданного тэгом nav зависит от высоты блока заданного тэгом article и наоборот — блок article зависит от высоты блока nav. Хотя в данном случае только высота блока nav должна подстраиваться под высоту более длинного тэга article обратная зависимость является лишней:
<article>
<aside>
...перечень ссылок...
</aside>
..содержание статьи
</article>
article {
position: relative;
display: block;
width: 75%;
left: 25%;
background-color: #8888FF;
}
aside {
position: absolute;
display: block;
width: 33%;
left: -33%;
height: 100%;
background-color: #F88888;
}
Процентное значения для аболютных элементов также как и display: table работают в браузере IE начиная только с восьмой версии. Значения ширины и длины блока aside берутся из пересчета относительно размеров блока article, так как в CSS координаты и размеры элемента с абсолютным отсчитывается начиная с первого родительского элемента с нестатичным (relative, absolute, fixed) значеним параметра position. То есть ширина блока article (которая составляет 75% от ширины документа) для aside контейнера равна 100%, составляя пропорцию:
75% - 100%
25% - ?
получаем
25% * 100% / 75% = 33.33%
То есть 25% свободного экрана в процентном соотношении блока article.
Таким образом мы можем избавиться от лишнего wrapper элемента, отобразить зависимость одной колонки от другой в коде и не прибегать к методу табличного позиционирования для нетабличных данных.
Колонки одинаковой высоты через border
Особенностью табличной верстки является то, что колонки, получаемые с помощью ячеек таблицы, имеют одну высоту. Это неудивительно, поскольку ячейки взаимосвязаны и при повышении высоты одной ячейки, соответственно увеличивается высота рядом расположенных ячеек. Многие разработчики пытаются произвести подобный эффект и с помощью слоев, т.е. сделать их взаимосвязанными и одной высоты, независимо от объема содержимого.
На самом деле применение слоев для создания одинаковых по высоте колонок неверно по своей сути, поскольку противоречит идеологии слоев. А именно: высота слоя ограничена его содержимым и формируется автоматически. При этом высота колонок различается, что хорошо видно на рис. 1, где представленный макет построен именно на базе слоев.
Рис. 1. Колонки, созданные с помощью слоев
Аналогичный документ, но сверстанный с помощью таблицы, будет иметь несколько другой вид, как показано на рис. 2.
Рис. 2. Колонки, созданные с помощью таблицы
Таким образом, видно четкое разделение подходов к верстке:
- если используются слои, то колонки должны иметь высоту, которая определяется содержимым слоя;
- колонки одинаковой высоты строятся с помощью таблицы.
Игнорирование этих принципов приводит к усложнению кода и появлению ошибок в отображении документа браузерами, как следствие, повышается время на разработку сайта и его отладку. Поэтому приведенный далее материал должен восприниматься не как руководство к действию, а предназначен для лучшего понимания основ работы со слоями и стилями.
Сразу определимся, что создать макет с колонками одинаковой высоты слоями напрямую не получится. Любые методы лишь имитируют желаемый результат за счет использования фонового цвета, добавления границ или другими способами. Далее рассмотрим создание колонок с помощью границ.
Границы в качестве колонок
Суть метода в следующем — добавляем слева или справа от элемента границу, ширина которой совпадает с шириной одной из колонок. Понятно, что границы предназначены совсем для других целей, но в данном случае такое их использование позволяет получить желаемый результат. Для этого создаем слой с именем container и для него устанавливаем стиль, как показано в примере 1.
Пример 1. Создание колонок
#container {
border-left: 200px solid maroon; /* Цвет левой колонки */
background: #f0f0f0; /* Цвет фона правой колонки */
}
Поскольку элемент у нас всего один, то колонки, имитированные с помощью широкой вертикальной линии и фона, всегда имеют одну высоту. Остается расположить информацию точно поверх этого контейнера. Для левой колонки, назовем ее col1, следует задать ее ширину и с помощью стилевого свойства float указать, что это плавающий элемент. Поскольку граница не является частью текстового блока, то требуется сместить слой col1 влево за счет добавления свойства margin-left с отрицательным значением, равным ширине границы (пример 2).
Пример 2. Формирование левой колонки
#col1 {
width: 200px; /* Ширина левой колонки */
float: left; /* Превращаем в плавающий элемент */
margin-left: -200px; /* Сдвигаем все влево на ширину границы */
color: #fff; /* Цвет текста в колонке */
}
В данном примере сочетание свойств float: left и margin-left с отрицательным значением позволяет расположить содержимое слоя прямо поверх границы. Для правой колонки col2 никаких дополнительных условий указывать не надо, текст будет располагаться как нам требуется.
Из-за того, что плавающий элемент располагается поверх линии границы, может получиться, что текст в левой колонке выходит за пределы цветного прямоугольника. Чтобы этого не произошло, следует отменить действие свойства float за счет использования clear. Окончательный код показан в примере 3.
Пример 3. Колонки одной высоты
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Две колонки одной высоты</title>
<style type="text/css">
#container {
border-left: 200px solid maroon; /* Цвет и ширина левой колонки */
background: #f0f0f0; /* Цвет фона правой колонки */
}
#col1 {
width: 200px; /* Ширина левой колонки */
float: left; /* Превращаем в плавающий элемент */
margin-left: -200px; /* Сдвигаем все влево на ширину границы */
color: #fff; /* Цвет текста в колонке */
}
#col1 p {
padding: 5px; /* Поля вокруг абзаца текста */
margin: 0; /* Обнуляем отступы */
}
#col2 {
padding: 5px;
}
div.clear {
clear: both; /* Убираем все плавающие элементы */
}
</style>
</head>
<body>
<div>
<div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem
nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat
volutpat.</p>
</div>
<div>
Ut wisi enim ad minim veniam, quis nostrud exerci taion ullamcorper
suscipit lobortis nisl ut aliquip ex en commodo consequat. Duis
te feugifacilisi per suscipit lobortis nisl ut aliquip ex en commodo
consequat.Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna
aliguam erat volutpat.
</div>
<div> </div>
</div>
</body>
</html>
Данный пример работает в браузерах Firefox и Opera и некорректно отображается браузером Internet Explorer 6 (IE6). Это связано с ошибкой интерпретации границ этим браузером. Для создания универсального кода придется «подкладывать» для IE6 индивидуальный стиль, в частности, текущее значение margin-left для слоя col1 надо разделить пополам. В примере 4 показано, как сделать стиль, который будет пониматься только в IE.
Пример 4. Отступ для Internet Explorer
* HTML #col1 {
margin-left: -100px; /* Сдвигаем все влево на половину ширины границы */
}
Конструкция * HTML работает только в IE6, остальные браузеры ее пропустят. Универсальный код с учетом особенностей браузеров показан в примере 5.
Пример 5. Использование границ
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Две колонки одной высоты</title>
<style type="text/css">
#container {
border-left: 200px solid maroon;
background: #f0f0f0;
}
#col1 {
width: 200px; float: left; margin-left: -200px; color: #fff;
}
* HTML #col1 {
margin-left: -100px;
}
#col2 {
padding: 5px;
}
div.clear {
clear: both;
}
</style>
</head>
<body>
<div>
<div>Колонка 1</div>
<div>Колонка 2</div>
<div> </div>
</div>
</body>
</html>
В данном примере показано создание левой колонки фиксированной ширины, а правая колонка занимает все доступное пространство. Для случая, когда колонки надо поменять местами, используйте border-right вместо border-left; float: right вместо float: left и margin-right вместо margin-left. Остальные параметры останутся неизменными.
«Див» блоки одинаковой высоты / Habr
На днях столкнулся с задачей:
Сделать две одинаковые по высоте
-колонки, не зависимо от количества текста в какой либо из них.Условия:
- Никаких таблиц;
- Поддержка IE6+ и т.д;
- Резиновая верстка;
- Никакого JavaScript, чистый HTML и CSS.
Дизайн:
В дизайне изображены две колонки с отступом друг от друга. Каждый из них имеет свой фон и border с округленными уголками. На вид все просто.Поиск решений:
Искал и естественно нашел очень полезный пост, где описаны все самые действенные способы решения данной задачи: http://habrahabr.ru/post/64173/.
Собственно 4-е решение из этого поста было наиболее приемлемым, но с помощью него мне так и не удалось вывести два разных фона для своих колонок.Решение
В отчаянии найти решение в интернете, я решил взять за основу структуру 4-го решения из вышеописанного поста и переделать/упростить под свои нужды.Вышла та же структура но уже не на основе позиционирования (position:relative
), а на основе отрицательных отступов (margin-left:-100%;
) и более логичной структуры (сначала левая колонка/текст, потом правая).HTML
тут текст длиннее
или тут, неважно
CSS "резиновый".text_container_l {
width: 50%;
float:left;
}
.text_container_r {
width: 100%;
float:left;
margin:0 0 0 100%;
}
.text_l {
float:left;
width:100%;
margin:0 0 0 -100%;
}
.text_r {
float:left;
}
CSS "фиксированной ширины".text_container_l {
width: 400px;
float:left;
}
.text_container_r {
width: 200px;
float:left;
margin:0 0 0 400px;
}
.text_l {
float:left;
width:400px;
margin:0 0 0 -400px;
}
.text_r {
float:left;
}
Описание
Как видите код гораздо проще и понятнее.
В моем случае "резиновой" верстки везде используются проценты и это немного все усложняет, но решение так же подходит и для фиксированной ширины.В "резиновом" примере предоставлен макет из двух колонок шириной по 50% от ширины контейнера. Обратите внимание, что колонки обернуты двумя -ами, которые будут наследовать высоту вложенных колонок и каждый будет выводить свое фоновое изображение.
Внешним двум контейнерам просто задаем нужные нам широты для колонок, а второму также добавляем компенсацию отступом, равным размеру первой колонки.
Далее задаем ширину первой колонки и также компенсируем отрицательным отступом, равным ширине первой колонки.
Вторая колонка просто "плывет по течению".
Советы
Растягивающийся фон, который будет всегда одной высоты, необходимо прописывать в контейнеры а не в колонки. Также следует избегать всяческие верхние и нижние отступы для контейнеров, например: padding, margin, border
. Поскольку все контейнеры вложены друг в друга, то такие отступы у родителя сдвинут всех детей. Если для колонки нужен border, можно использовать вместо него outline
или box-shadow:0 0 0 4px #ccc;
. Свойство padding
также не рекомендуется применять на саму колонку, так как это может увеличить ее ширину и тогда придется рассчитывать «компенсации» и ширину колонки с его учетом. Проще поместить в колонку еще div
и с ним уже творить, что угодно.Основная сложность с процентами, это рассчитать ширину второй колонки относительно первой. То есть если ширина первой колонки 30%, а вторая должна быть в 2 раза больше, то это будет 200% от ширины первой колонки, если в 2 раза меньше, то это будет 50% — такую ширину и нужно на нее ставить.
Если нужно 3+ столбика то соответственно их нужно обернуть в 3 контейнера, которым задать широты и соответственно скомпенсировать отступами.