Для современной верстки использование сетки не новость. Практически все html-фреймвоки используют ту или иную сетку. Я встречала 3 вида сетки:
- сетка на float;
- сетка на inline-block;
- сетка на flexbox.
Сетка на inline-block имеет свои особенности, плюсы и минусы, которые следует рассмотреть.
Введение
Сетка, в которой для расположения элементов в ряд используется свойство float: left или float: right используется в большинстве html-фреймвоках (Foundation, Bootstrap и пр). У нее есть свои плюсы и минусы. Думаю, она популярна потому, что была первым достойным решением после табличной верстки, а также поддерживается старыми браузерами. Однако работая с ней я встретила в ней по крайней мере 2 существенных недостатка.
- У элемента с заданным свойством float отсутствует высота и поэтому тяжело выровнять дочерние элементы по вертикали.
- Если несколько элементов с свойством float расположены по горизонтали в один ряд и предыдущий элемент (пусть это элемент А) имеет большую высоту, чем последующие (элементы В), то при переходе на следующую сточку один из элементов В может «зацепится» за элемент А и не попасть в начало строки. В фреймвоках эта проблема решается наличием элемента-строки (в Bootstrap — это класс row), но тогда нужно четко знать, сколько элементов будет в ряду. А если товары на странице категории выводятся в цикле и на десктопе они должны располагаться по 5 в ряд, а на мобильном — по 3?
Эти недостатки привели меня к поиску других решений. Естественно, хорошим решением есть сетка с использованием flexbox, которая позволяет гибко настроить расположение элементов внутри контейнера. Ее главным недостатком есть поддержка только современными браузерами. Но хотелось попробовать и другие решения. Прочитав несколько статей об использовании элементов со свойством display: inline-block для выравнивания элементов и расположении в ряд, я принялась искать сетку на inline-block. Однако ничего готового для использования в проектах я не нашла. Только отдельные заготовки. Поэтому, я решила сама создать такую сетку. Для именования классов я использовала методологию БЭМ (Блок-Элемент-Модификатор). Итак, давайте рассмотрим что получилось.
Брейкпоинты и нормализация тегов
В сетке используются следующие брейкпоинты (контрольные ширины браузера, при которых меняется расположение блоков) и префиксы для них:
- xs: 480рх,
- sm: 768рх,
- ms: 1024рх,
- md: 1280рх,
- lg: 1440рх,
- mg: 1680рх.
Для сетки используется минимальная нормализация элементов, необходимых для корректного отображения контента:
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
}
html {
font-size: 10px;
}
Однако можно использовать ее вместе с другими библиотеками (Reset.css, Normalize.css и пр). В сетке также все размеры указаны в единицах rem, которые относительны шрифту элемента html. Поэтому для масштабирования шрифт html на разных брейкпоинтах меняется:
@media (max-width: 1680px) {
html {
font-size: 9.5px;
}
}
@media (max-width: 1440px) {
html {
font-size: 9px;
}
}
@media (max-width: 1280px) {
html {
font-size: 8.5px;
}
}
@media (max-width: 1024px) {
html {
font-size: 8px;
}
}
@media (max-width: 768px) {
html {
font-size: 8.5px;
}
}
@media (max-width: 480px) {
html {
font-size: 7px;
}
}
В сетке по умолчанию используется 24 колонки и следующие отступы между блоками: 1, 2, 3, 4, 5, 10, 15, 20, 25, 30, 40, 50. По поводу отступов следует объяснить. Отступ, скажем, 15 — это не 15рх! Это означает, что на ширине браузера 1920рх (которую я принимаю как отправную точку, поскольку для этой ширины чаще всего создается дизайн сайта) отступ блока с одной стороны будет 15рх. А учитывая, что шрифт html на этой ширине равен 10рх, то отступ в сетке задается как 1.5rem. На меньшей ширине шрифт html будет меньше и отступы тоже уменьшатся.
Брейкпоинты, количество колонок, отступы и стартовый шрифт html можно изменить в SASS-версии сетки и сгенерировать нужную для проекта сетку.
Основные блоки сетки
В сетке я использую 3 основных блока:
- класс grid — для обозначения внешнего блока;
- класс box — для обозначения дополнительного блока внутри grid;
- класс cell — для обозначения внутренних блоков внутри grid или box.
Итого, сетка имеет такую структуру:
<div class="grid">
<div class="box">
<div class="cell">Элемент 1</div>
<div class="cell">Элемент 2</div>
<div class="cell">Элемент 3</div>
</div>
</div>
Или такую:
<div class="grid">
<div class="cell">Элемент 1</div>
<div class="cell">Элемент 2</div>
<div class="cell">Элемент 3</div>
</div>
Если так, то сразу напрашивается вопрос: А зачем тогда дополнительный блок box? Блок box может быть только одним внутри grid и необходим, если нужны отступы между внутренними блоками или выравнивание внутренних блоков.
Модификаторы блока grid
Блок grid имеет следующие модификаторы:
- grid--size применяется в случае, если ширина блока фиксирована и на каждом брейкпоинте она равна ширине предыдущего брейкпоинте. Например, если ширина браузера 1366рх, и в блоке grid указать модификатор grid--size, то блок будет иметь ширину 1280рх и будет располагаться по средине.
- grid--st, grid--sm, grid--ms, grid--md, grid--md, grid--mg — применяется если нужно, что бы ширина, начиная с какого-то брейкпоинта, была фиксирована, а до этого блок будет распространяться по всей ширине. Например, если использовать модификатор grid--md, то на ширинах меньше 1280рх блок будет иметь ширину 100%, а начиная с ширины 1280рх будет равен этой ширине.
- grid--col24 применяется, если нужно использовать колонки указанной ширины. Поскольку можно сгенерировать несколько-колоночную сетку (например, 24 колонки и 35 колонок), то можно использовать модификаторы grid--col24 и grid--col35. Первый даст возможность располагать элементы по 2, 3, 4, 6, 12 в ряд, а второй — по 5 и 7 в ряд. Это бывает нужно, если в дизайне используется различное число колонок.
- grid--g10, grid--v10, grid--gv10 задают отступы между внутренними блоками (cell) соответственно только по горизонтали, только по вертикале и в обоих направлениях. Цифра в конце (в данном случае 10) указывает на ширину отступа с одной стороны. Например, если мы хотим отступы между внутренними блоками в 3rem только по горизонтали, то внешнему блоку нужно задать модификатор grid--g15. Однако тут есть 2 тонкости:
- По горизонтали блок может иметь одинаковые отступы и справа, и слева, в то время, как по вертикале делается двойной отступ снизу. Это сделано для удобства, поскольку в основном первый блок начинается сверху без отступа, а блоки, идущие снизу должны отделяться от него отступом;
- Отступы делаются только внутри между внутренними блоками, а снаружи они плотно прилегают к внешнему блоку.
Модификаторы блока box
Блок box имеет следующие модификаторы:
- box--left, box--right, box--center, box--justify используется, если нужно выровнять колонки по горизонтали соответственно слева, справа, по центру и по всей ширине.
- box--top, box--bottom, box--middle используется, если нужно выровнять колонки по вертикале, соответственно сверху, снизу и по центру.
Модификаторы блока cell
Блок cell имеет следующие модификаторы:
- cell--none, cell--auto, cell--full задают как будет отображается внутренний блок по умолчанию: будет скрыт, иметь собственную ширину или распространяться на всю ширину родителя;
- cell--col1, cell--col2, cell--col3 и т. д. задают конкретную начальную ширину внутреннего блока. Например, модификатор cell--col2 означает, что блок будет занимать 2 колонки;
- cell--st5, cell--xs10, cell--md15 и т. д. ширину внутреннего блока на определенном брейкпоинте. Например, модификатор cell--md15 означает, что ширина блока будет составлять 15 колонок при ширине экрана < 1280px (md).
- cell--left, cell--right, cell--center, cell--justify задают выравнивание элементов нутри блока по горизонтали соответственно слева, справа, по центру и по всей ширине;
- cell--top, cell--bottom, cell--middle задают выравнивание по вертикале, соответственно сверху, снизу и по центру. Однако следует учесть, что поскольку внутренние блоки имеют свойство display: inline-block, то по вертикале они выравниваются относительно друг друга, а не родителя! Поэтому, чтобы выровнять в блоке по вертикали, например, по центру, нужно обоим блокам поставить модификатор cell--middle.
Пример применения модификаторов
Следующий участок кода показывает, как могут применяться различные модификаторы вместе:
<div class="grid grid--col24 grid--size grid--gv15">
<div class="box box--middle">
<div class="cell cell--none cell--md8 cell--sm24">
Элемент 1
</div>
<div class="cell cell--none cell--md8 cell--sm24 cell--center">
Элемент 2
</div>
<div class="cell cell--none cell--md8 cell--sm24 cell--right">
Элемент 3
</div>
</div>
</div>
Заключение
Исходные файлы сетки и пример ее использования можно смотреть тут. Обратите внимание, что в репозитории есть файл grid-inline-block.css с скомпилированной сеткой с указанными выше параметрами. Но также имеется и файл grid-inline-block.scss, используя который можно скомпилировать свой вариант сетки.
Созданная сетка имеет свои плюсы:
- Решает проблемы с сеткой на float и делает по сути то же самое.
- В отличии от сетки на float может выравнивать элементы по вертикале, а также задавать разное количество колонок или разные отступы.
- В отличии от сетки на flexbox поддерживается и более старыми браузерами, например, ИЕ9 и старыми версиями Android.
- Позволяет внутренние блоки скрывать или показывать на нужной ширине экрана.
- Имеет интересную способность выравнивать элементы по вертикале относительно друг друга. Это бывает полезным для пунктов меню.
- Большое количество внутренних блоков с разными модификаторами могут находится в пределах одного внешнего блока и они друг другу мешать не будут
- Позволяет создавать бесконечную вложенность внешних блоков.
Однако сетка и не лишена недостатков. Вот некоторые из них:
- При задании последнему внешнему блоку (например, подвалу сайта) модификаторов grid--v10 или grid--gv10 (10 — это для примера), то есть которые задают вертикальный внутренний отступ, то этот последний блок не будет прижат к низу страницы. Это связано с тем, что отрицательный margin-bottom, который тут используется не работает в сочетании с нижней границей body. Решить эту проблему можно просто не задавая указанный модификаторы последнему блоку.
- Хоть сетка и имеет некоторую гибкость в выравнивании внутренних блоков, но ей не сравнится в этом с flexbox.
- Если по каким-то причинам внутренний блок стал больше по ширине, чем то место, что ему было отведено (такое может произойти, если не задавать конкретную ширину внутренним блокам, а ограничится только классом cell), то этот блок перескочит на новую строчку, что часто не желательно. Поэтому такие моменты нужно продумывать сразу.
Не могу сказать, что эта сетка лучше всех и что все ее должны использовать. Но думаю, она имеет право на существование наряду с другими.
Автор: babenkoma