CSS решения. Создание сетки, колонок и гридов.
В данной статье поговорим о создании сеток в HTML. Разберём сетку в Twitter Bootstrap и приведём популярные решения для трёх случаев:
- old way — старый стиль, работающий во всех популярных браузерах;
- new way — современный стиль, работающий во всех современных браузерах (IE > 9) (twitter bootstrap 4);
- feature way — божественный стиль (будущий), работающий в прогрессивных браузерах.
Создание сеток одна из самых частых задач в CSS. Сначала их делали с помощью таблиц, но в дальнейшем появились более гибкие решения.
Классические колонки с использованием float (old way)
Одна из самых популярных реализаций колонок была представлена в Twitter Bootstrap 3.
Принцип работы в следующем:
- Создаём родителя (row), для которого задаём отрицательные отступы margin слева и справа. (Это необходимо, чтобы колонки располагались по центру без необходимости указывать дополнительные классы первому и последнему элементам, чтобы выровнять колонки);
- Так как колонки будут располагаться с помощью плавающего свойства float, к родителю применяется утилита clearfix, которая позволит нормализовать высоту родителя и устранит нежелательные сайд эффекты;
- Все дочерние элементы (.col) родителя получают положительные отступы слева и справа с помощью padding. Для позиционирования также устанавливается свойство
float: left
; - Считается, что в сетке не может быть более 12 колонок, поэтому базовая ширина колонки равна 1/12, в пересчёте на проценты ~8.33% . Соответственно, если колонка занимает размеры двух одинарных колонок, ширина будет 2/12, и так далее;
- Для того, чтобы колонки не проваливались друг в друга в случае, если одна колонка не имеет “видимого” содержимого, каждая колонка получает свойство
min-height: 1px
.
Создадим следующую HTML структуру со следующими стилями:
Сначала мы объявили константы:
- old-columns — количество колонок
- old-gutter — расстояние между колонками
Для родителя задали отступы слева и справа, а также добавили clearfix
:
.old-row {
@include clearfix();
margin-left: -$old-gutter-column;
margin-right: -$old-gutter-column;
}
Для колонок добавили отступы и базовые стили, общие для всех:
.old-column,
[class^='old-column-'] {
position: relative;
float: left;
min-height: 1px;
width: 100%;
padding-right: $old-gutter-column;
padding-left: $old-gutter-column;
}
Для примера, мы используем селекторы атрибутов ([class^=’old-column-’]), но в продакшене, старайтесь их изберать.
Саму сетку создали средствами SCSS:
@for $i from 1 through $old-columns {
.old-column-#{$i} {
width: percentage($i / $old-columns);
}
}
Которая в итоге сгенерирует набор классов с постфиксами от 1 до 12:
.old-column-1 {
width: 8.3333333333%;
}.old-column-2 {
width: 16.6666666667%;
}.old-column-3 {
width: 25%;
}.old-column-4 {
width: 33.3333333333%;
}.old-column-5 {
width: 41.6666666667%;
}.old-column-6 {
width: 50%;
}.old-column-7 {
width: 58.3333333333%;
}.old-column-8 {
width: 66.6666666667%;
}.old-column-9 {
width: 75%;
}.old-column-10 {
width: 83.3333333333%;
}.old-column-11 {
width: 91.6666666667%;
}.old-column-12 {
width: 100%;
}
Откроем в браузере:
Для добавления адаптивности, необходимо добавить точки остановок (breakpoints)для нужных размеров, а также задать соответствующие суффиксы классам колонок:
Как видно, для задания размеров мы использовали коллекции (map) в SCSS и с помощью цикла обошли все размеры и сгенерировали нужные классы с нужными суффиксами. Подробнее о работе map’ов в документации SASS.
В результате получим:
На gif’ке видно, как колонки изменяются в зависимости от ширины экрана.
Полную реализацию колонок, вы можете посмотреть в исходниках Twitter Bootstrap 3 в репозитории.
Преимущества:
- Работает во всех популярных браузерах.
Недостатки:
- Невозможность лаконичной реализации дополнительной возможности — одинаковая высота колонок.
Как и ранее (в предыдущей статье — CSS решения. Фиксированный блок плюс адаптивный блок) лучшим решением является использование микро скрипта, который следит за изменением ширины блоков и обновляет высоту блоков.
Колонки с использованием flex (new way)
Более прогрессивным способ для создания колонок является использование flex
.
Принцип работы заключается в следующем:
- Создаём родительский блок (.row) для которого указываем свойство
display: flex
. Так как колонки выстраиваются в линию и могут занимать больше 100%, для этого ставиться свойствоflex-wrap: wrap
; - Для создания корректных отступов задаём отрицательные
margin-left
иmargin-right
; - Для всех потомков первого уровня задаем свойства
position: relative
, которое гарантирует корректную обработку,width: 100%
что позволит нормализовать свойства всех потомков и уравнять их права на доступную им ширину, а также отступы слева и справа с помощьюpadding
; - Также создаются разные классы колонок (.col-1, .col-2, …), которые принимают соответствующие размеры в пропорции 1 к 12. В отличии от предыдущего решения, регулирование ширины колонок осуществляется с помощью свойств
flex
и max-width
.
Создадим следующую структуру HTML и классы, описанные выше:
Как можно увидеть из реализации, решение почти совпадает с old-way.
Откроем в браузере:
Так как решение уже учитывает адаптивность изменим ширину браузера и посмотрим на результат:
Ознакомиться с полным решением можно в репозитории Twitter Bootstrap.
Добавим немного контента в колонки, чтобы посмотреть, что будет с высотой колонок:
Как видно из скриншота, все колонки получили высоту самой большой колонки.
Преимущества:
- Работает во всех современных браузерах (IE > 9)
- Колонки одинаковой высоты из «коробки»
Недостатки:
- Не работает в старых браузерах.
Создание сеток с помощью grid (feature way)
Последним решением является создание сеток средствами W3C — использование display: grid
.
Принцип работы в следующем:
- Создаётся родительский блок, который будет сразу определять размеры и количество колонок. Блок получает свойство
display: grid
. - Для задание строк используется свойство
grid-template-rows
, которое принимает доступные размеры строк. Например:1fr
— создаст сетку с 1 строкой;1fr 2fr 1fr
— создаст сетку с 3 строками, где средняя строка будет занимать 50% всей доступной высоты - Для задания столбцов используется свойство
grid-template-columns
, которое принимает доступные размеры столбцов (аналогичноgrid-template-rows
).
Создадим сетку подобную тем, что приводились в примерах ранее:
Откроем в браузере:
На скриншоте видим, что отрицательных отступов нету и колонки занимают все доступное расстояние.
Так как мы использовали единицы гибкости (fr), колонки получаются одинаковой высоты.
Если изменим ширину:
Стоит отметить, что принципы создания сеток отличаются от модели сеток используемых в Twitter Bootstrap, которые приводились ранее. В данном случае блок, который объявляет сетку уже заранее знает все свои свойства, поэтому дополнительно указывать классы не нужно.
Преимущества:
- Позволяет создавать сетки любой сложности.
Недостатки:
- Не работает в старых браузерах;
- Требует перестройки мышления по построению и использованию сеток.
Дополнение
Небольшая демонстрация работы всех трёх решений:
Резюме
В данной статье рассмотрели основные решения, используемые для создания сеток.
Разобрали типовые решения, а также привели привели следующие реализации:
- старый стиль, который основан на решении Twitter Bootstrap 3;
- современный стиль, который основан на решении Twitter Bootstrap 4;
- будущий стиль, который основан на принципах построений сеток средствами CSS
display: grid
.
Спасибо за внимание!
Исходники
Все исходники находятся на github, в репозитории:
Для того, чтобы посмотреть состояние проекта на момент написания статьи, нужно выбрать соответствующий тег — css-grid.
git checkout css-grid
Код можно посмотреть в приложении frontend-css — https://github.com/Fafnur/medium-stories/tree/master/apps/frontend/css/src/app/grids
Ссылки
Подписывайтесь на блог, чтобы не пропустить новые статьи про Angular, веб-разработку и новости из мира фронтенда.
Medium: https://medium.com/fafnur
Добавляйтесь в группу ВК: https://vk.com/fafnur
Добавляйтесь в группу в Fb: https://www.facebook.com/groups/fafnur/
Телеграм канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1
Instagram: https://www.instagram.com/fafnur
LinkedIn: https://www.linkedin.com/in/fafnur
Предыдущие статьи:
- Тестирование сервисов в Angular с помощью Jest. Тестирование реактивной/асинхронной логики.
- Тестирование Ngrx store в Angular. Методы и подходы для упрощения тестирование stat’ов Ngrx в Nx.
- Сборка Typescript приложения с помощью Webpack.
- Архитектура enterprise Angular приложений с использованием монорепозитория Nx.
- Angular тестирование component с помощью Jest.
- CSS решения. Фиксированный блок плюс адаптивный блок.