CSS решения. Создание сетки, колонок и гридов.

Aleksandr Serenko
F.A.F.N.U.R
Published in
6 min readJun 6, 2020
CSS сетки. Создание колонок и гридов.

В данной статье поговорим о создании сеток в HTML. Разберём сетку в Twitter Bootstrap и приведём популярные решения для трёх случаев:

  • old way — старый стиль, работающий во всех популярных браузерах;
  • new way — современный стиль, работающий во всех современных браузерах (IE > 9) (twitter bootstrap 4);
  • feature way — божественный стиль (будущий), работающий в прогрессивных браузерах.

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

Классические колонки с использованием float (old way)

Bootstrap grid

Одна из самых популярных реализаций колонок была представлена в 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

Предыдущие статьи:

  1. Тестирование сервисов в Angular с помощью Jest. Тестирование реактивной/асинхронной логики.
  2. Тестирование Ngrx store в Angular. Методы и подходы для упрощения тестирование stat’ов Ngrx в Nx.
  3. Сборка Typescript приложения с помощью Webpack.
  4. Архитектура enterprise Angular приложений с использованием монорепозитория Nx.
  5. Angular тестирование component с помощью Jest.
  6. CSS решения. Фиксированный блок плюс адаптивный блок.

--

--

Aleksandr Serenko
F.A.F.N.U.R

Senior Front-end Developer, Angular evangelist, Nx apologist, NodeJS warlock