- Отзывчивые блоки одинаковой высоты на основе Flexbox
- Проблема
- 4 способа как создать блоки одинаковой высоты
- Способ 1. Использование свойства display: table
- Преимущества:
- Недостатки:
- Способ 2: Использование JavaScript
- Преимущества:
- Недостатки:
- Способ 3: искусственные колонки
- Преимущества:
- Недостатки:
- Способ 4: Использование раздельных блоков с фоном
- Преимущества:
- Недостатки:
- Вывод
- Современные решения старых CSS-задач (2 часть): Элементы одинаковой высоты: Flexbox vs Grid
- Решение с помощью Flexbox
- Решение с помощью Grid
- Какой способ лучше?
Отзывчивые блоки одинаковой высоты на основе Flexbox
От автора: После публикации поста о том, как я создал отзывчивые блоки одинаковой высоты на сайте Readerrr, я получил несколько полезных отзывов от сообщества веб-разработчиков. Дэниел Стёрм (Daniel Sturm) предложил мне использовать модуль Flexbox из CSS3 вместо JavaScript, а Вирли Питерс (Veerle Pieters) оставил твит «… вы можете сделать это с помощью Flexbox, а JavaScript использовать для подстраховки». Точно! И почему я сам об этом не додумался?! Я читал до этого несколько статей про Flexbox, но сам никогда его не применял, поэтому он совершенно вылетел у меня из головы.
Почему Flexbox? Если вкратце, то модуль Flexbox Layout был создан для решения именно таких задач. Он является эффективным и гибким инструментом для управления, возможно, всеми разновидностями макетов. Благодаря ему практически не возникает задержки по времени между неправильной и правильной отрисовкой внешнего вида макета. При использовании решения на JavaScript тратится время на загрузку документа, затем на загрузку соответствующего JS-файла и, если таковые имеются, на загрузку изображений в блоках. Решение с Flexbox срабатывает мгновенно, а решению на JavaScript потребуются секунды. Но даже в этом случае, решение на JavaScript прекрасно подойдет для людей, использующих старые версии браузеров, которые не поддерживают Flexbox.
Проблема
Если вы не читали мой предыдущий пост, то вам это и не нужно делать. Вот собственно код и проблема (макет, который выглядит неисправным), которую нужно решить:
4 способа как создать блоки одинаковой высоты
Раньше, когда все верстали с использованием таблиц, создать колонки одинаковой высоты было очень просто. Достаточно создать таблицу, например, с 3мя колонками и все они автоматически будут иметь одинаковую высоту. Но в блочной верстке не все так просто.
В этой статье я расскажу вам о некоторых способах создания колонок равной высоты и о совместимости этих методов с браузерами (включая IE6). Все эти способы описывают создание 3х колоночного макета.
Способ 1. Использование свойства display: table
Для реализации макета используется список ( ul ) или блок div с вложенными в него блоками для строки и каждой из колонок. Обрамляющему блоку div присваивается значение display: table , а каждому вложенному блоку-колонке значение display: table-cell .
Рассмотрим пример со списком.
HTML код:
.base /*make it 100% width and a minimum of 1000px width*/
width: auto;
margin-left: 0px;
margin-right: 0px;
min-width: 1000px;
padding: 0px;
display:table;
>
.base-row Display: table-row;
>
.base li display: table-cell;
width: 33%;
>
.cell1 background-color: #f00;
>
.cell2 background-color: #0f0;
>
.cell3 background-color: #00f;
>
Преимущества:
Это наиболее простой и легкий способ создания колонок одинаковой высоты, в отличие от других методов.
Внешний отступ ( margin , как cellspacing для таблиц) равный для всех колонок создать не получится, однако, его можно заменить границей белого цвета (или цвета фона колонки) с соотвествующей шириной для иммитации отступа.
Недостатки:
Этот метод не работает в браузерах IE7 и ниже. Пройдет немало времени (когда IE7 станет новым IE6), прежде чем мы сможем без опаски использовать этот метод.
Способ 2: Использование JavaScript
Этот метод основан на использовании небольшого JS кода (JQuery), который “расставляет” нужную высоту каждой колонке на основе высоты наиболее длинной из них.
HTML код:
.container Width: 900px;
Margin-left: auto;
Margin-right: auto;
>
.leftsidebar Float: left;
Width: 33%;
>
.content Float: left;
Width: 33%;
>
.rightsidebar Float: left;
Width: 33%;
>
function setEqualHeight(columns)
var tallestcolumn = 0;
columns.each(
function()
currentHeight = $(this).height();
if(currentHeight > tallestcolumn)
tallestcolumn = currentHeight;
>
>
);
columns.height(tallestcolumn);
>
$(document).ready(function() setEqualHeight($(«.container > div»));
>);
Вы можете положить JS код в отдельный файл и вызвать его непосредственно в HTML коде. В этом случае, инициализация JQuery должна быть по коду расположена выше.
Код, который вам нужно изменить – это название класса блока, который создает колонки. В данном примере это класс container :
Вы можете изменить название класса блока с колонками или, даже, добавить класс к каждому блоку-колонке и использовать их раздельно, для удобства.
Преимущества:
Главное преимущество метода – он работает во всех браузерах и вам не нужно напрягаться с CSS кодом для выравнивания высоты.
Недостатки:
Если JavaScript будет отключен, соотвественно, колонки не будут равной высоты. Но, как правило, это очень редкий случай, т.к. большинство современных сайтов требуют включения JS.
Способ 3: искусственные колонки
Этот метод придуман одним из первых для реализации колонок одинаковой высоты. Суть его в том, что обрамляющему блоку присваивается фон, иммитирующий колонки (см. рис. ниже). Они просто накладываются на этот фон. Эффект равной высоты создается за счет повторяющегося фона.
.container background-image: tile.png;
background-repeat: repeat-y;
width: 900px;
margin-left: auto;
margin-right: auto;
.leftsidebar float: left;
width: 200px;
>
.content float: left;
width: 400px;
>
.right float:left;
width: 300px;
>
Преимущества:
Недостатки:
Этот метод можно использовать только для макетов/колонок фиксированной ширины.
Способ 4: Использование раздельных блоков с фоном
Этот способ основан на использовании раздельных блоков div, каждый из которых имеет свой фон и принимает значение высоты элемента, который он включает.
HTML код:
.rightback width: 100%;
float:left;
background-color: green;
overflow:hidden;
position:relative;
>
.contentback float:left;
background-color:blue;
width: 100%;
position:relative;
right: 300px; /* width of right sidebar */
>
.leftback width: 100%;
position:relative;
right: 400px; /* width of the content area */
float:left;
background-color: #f00;
>
.container width: 900px;
margin-left: auto;
margin-right:auto;
>
.leftsidebar float:left;
width: 200px;
overflow:hidden;
position:relative;
left: 700px;
>
.content float:left;
width: 400px;
overflow:hidden;
position:relative;
left: 700px;
>
.rightsidebar float:left;
overflow:hidden;
width: 300px;
background-color:#333;
position:relative;
left: 700px;
>
Выглядит не просто, не так ли? Главное уяснить 5 основных моментов:
- .rightback, .contentback, и.leftback содержат элементы .leftsidebar, .content and .rightsidebar, которые, в свою очередь, содержат текст.
- Каждый из вложенных блоков отвечает за цвет/фон колонки. В данном примере
.leftback соотвествует.leftsidebar,
.contentback – .content
и .rightback – .rightsidebar. - Кроме последнего (отвечающего за правую крайнюю колонку), каждому из блоков задан отступ справа, равный ширине элемента, прилегающего справа, который содержит фон. В данном примере .contentback (отвечающего за фон .content) сдвинут влево на 300px (что является шириной блока .rightsidebar). (см. рис. ниже)
- Колонки .leftsidebar, .content и .rightsidebar расположены друг за другом с определенной шириной.
- Они обеспечивают отступ слева равный сумме ширины каждой из колонок, кроме крайней правой. Т.е. они равны=ширина .rightsidebar (300px) и .content (400px) = 700px.( B+G)
На рисунке ниже изображено как располагаются блоки .rightback, .contentback и.leftback. Крайний слева – .rigthback, крайний справа — .leftback.
Пунктирная линия показывает видимую область колонок (блок .rightback обрезан с помощью overflow: hidden).
На картинке ниже черные линии, расположенные ниже красной – это контент элементов .leftsidebar, .content и .rightsidebar, если им задано свойство float:left и соотвествующая ширина.
Все 3 элемента имееют смещение слева от C, с помощью relative position.
C = B+G
Этот метод подробно описывается в этой статье.
Преимущества:
Метод работает во всех браузерах, включая Internet Explorer 6. Для реализации не требуется JavaScript, он полностью основан на CSS и HTML.
Недостатки:
Метод не так прост, как остальные, однако, он позволяет создать столько равных по высоте колонок, сколько требуется.
Вывод
Каждый из методов имеет свои преимущества и недостатки, но, наверняка, вы выберите для себя последний метод, который позволяет создать колонки равной высоты, работающие в любом браузере и без JS.
Современные решения старых CSS-задач (2 часть): Элементы одинаковой высоты: Flexbox vs Grid
Это вторая статья из серии, посвящённой ознакомлению с современными способами решения CSS-проблем, с которыми я сталкивалась на протяжении более 13 лет в роли фронтенд-разработчика.
Однажды (приблизительно 7 лет назад) я написала JQuery-плагин, который работал с тремя колонками, расположенными на одной строке. А именно, рассчитывал и задавал одинаковую высоту для элементов, независимо от количества содержимого в каждом из них. Метод вёрстки на float , который был тогда основным, не мог справиться с этой проблемой.
Решение с помощью Flexbox
С появлением Flexbox достижение такого поведения стало возможно благодаря добавлению всего одного свойства:
Удивительно! В этом случае прямые потомки по умолчанию выстраиваются в строку и имеют одинаковую высоту.
Но если содержимое будет храниться в дополнительном элементе, вложенном в .column , высота колонок с разным количеством контента снова будет отличаться.
Чтобы исправить это, вложенному элементу следует задать высоту 100%
.flexbox < display: flex; >/* Гарантия, что вложенные элементы с содержимым будут заполнять высоту колонок */ .element
Колонки снова станут равной высоты и будут расти вместе с содержимым вложенного элемента .element .
Решение с помощью Grid
Используя Grid, мы сталкиваемся с похожим поведением:
Подобно Flexbox, прямые потомки будут иметь одинаковую высоту, но их дети нуждаются в явном определении высоты, как и в способе с использованием Flexbox:
.flexbox < display: grid; grid-auto-flow: column; >/* Гарантия, что элементы с содержимым будут заполнять элементы колонок */ .element
Ниже представлена Codepen-демонстрация обоих решений для разного количества колонок в строке:
Какой способ лучше?
Для решения проблемы с равной высотой элементов, преимущество Flexbox в том, что ось по умолчанию позволяет сразу выстроить колонки рядом друг с другом, тогда как в Grid её нужно менять явно. Кроме того, элементы также не будут иметь одинаковую ширину (что может быть преимуществом для определённых типов содержимого, например, навигационных ссылок).
Преимуществом Grid в том, что столбцам можно задать равную ширину, если в этом есть необходимость. Также, в случае необходимости, можно указать желаемое максимальное количество столбцов на «строку». В этом случае Grid-макет с легкостью справляется с расчётами для автоматического распределения пространства между столбцами, в то время как Flexbox требует ручного задания расчётов для ограничения количества колонок.
Обновим наше решение с использованием Grid для 3 элементов .column на строке:
В то время, как для Flexbox самый простой вариант был бы таким:
Также, для каждого способа необходимо переопределять параметры с учётом адаптивности, но это выходит за рамки данной статьи