Любому верстальщику, перед которым встала очередная задача по вёрстке адаптивного макета, нужны сетки. В большинстве случаев берётся старый добрый bootstrap, и в html-ке начинают появляться div-ы с классами вида col-xs-6 col-sm-4 col-md-3
. И вроде бы всё хорошо и быстро, но в данном подходе часто возникает множество подводных камней. В данной статье мы рассмотрим эти подводные камни, и закидаем тухлыми помидорами рассмотрим мою поделку для беспроблемных сеток.
Проблемы
Нестандартные сетки
Итак, у нашего верстальщика очень мало времени, макет горит, всё надо сделать вчера. Поэтому, он берёт для основы популярный css-фреймворк bootstrap, и начинает свою работу. И тут, в середине работы, он вдруг натыкается на блок баннеров "5 в ряд". Все, кто работал с bootstrap знает, что его сетка по умолчанию 12-кратная, поэтому 5 колонок в ряд стандартной бутстраповской сеткой ну никак не сделаешь. Да, конечно, в бутстрапе можно собрать произвольную сетку, но это время терять, качать зависимости, собирать less-ки (а мы, допустим, пишем на sass).
Может подключить какую-нибудь библиотеку для настраиваемых сеток? В целом это хороший выход, единственный минус данного подхода, что практически все из них рассчитаны либо на долгое и нудное написание @media(min-width:){}
, либо генерируют свой набор классов, с кучей, наверняка не нужных col15-xs-offset-3
, которые попадут в итоговую css-ку.
Поэтому, с большой вероятностью, верстальщик просто пропишет все стили вручную (там, в принципе, не так много писать).
Необходимость своего набора breakpoint-ов
Очень часто в стандартной бутстраповской сетке не хватает дополнительных брейкпоинтов, т. е. есть xs, sm, md, lg — все они до ширины 1200px. А как же большие мониторы? Какой-нибудь брейкпоинт xl на 1600px так и просится в стандартный набор. Но его опять же нет, и возникают те же варианты решения, что и в предыдущем пункте. А ведь контрольных точек может быть очень много — 320, 360, 640, 768, 992, 1200, 1600, 1900..
Избыточность и многословность
И тут мы плавно подходим к следующей проблеме. Представьте, что вам нужно прописать для каждой сетки свои размеры блока, тогда у вас получится что-то типа этого:
<div class="col-xxs-12 col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1"></div>
Не слишком ли много? Добавьте сюда возможные pull/push и visible/hidden и тогда можно смело начинать сходить с ума. А ведь все эти классы прописаны в css, представьте сколько нужно прописать классов в css для всех комбинаций 60-кратной сетки!
Отделение стилей от разметки
Любой верстальщик знает, что inline-стили — это плохо. Так зачем мы пишем в классы разметки то, что касается стилей? col-xs-6
, visible-sm
и не дай бог text-right
— это всё стили, и, если надо будет вносить правки в уже натянутую на вёрстку, обязательно возникнет проблема, что верстальщику придётся просить backend-щика поменять col-sm-6 на col-sm-4.
Перекрытие ненужных стилей
Часто css-фреймворк подключают весь только ради сеток и пары мелких функций, что вытекает впоследствии в избыточном сбросе стилей и двойном размере итогового css. Например, подключается весь bootstrap.min.css, а потом весело и задорно убираются тенюшки и закруглённые уголки у .btn, .form-control
и тому подобного, включая :hover, :focus, :first-child
. В итоге, вместо помощи, фреймворк начинает мешать. Не говоря уже о часто не нужных фичах, по типу .glyphicon
. Конечно, опять же можно собрать bootstrap из того, что нужно, но это опять время.
Чужие стандарты и code-style
Допустим, верстальщик изучил БЭМ и начал его применять. Но необходимость использовать bootstrap диктует свои исключения — в нём все классы пишутся через дефис, не следуя принципам БЭМ. И тут возникает проблема выбора — либо смириться с мешаниной в названиях классов (btn-block disabled component__btn component__btn_disabled
), либо всё-таки выкинуть bootstrap.
Устаревшие методы
Как известно, сетки в bootstrap 3 основаны на float-ах. Что часто вызывает проблемы, одна из наиболее частых — различная высота блоков, в результате которой красивая сетка "ломается". Хватит использовать float-ы не по назначению, уже практически вымерли все браузеры, которые не умеют flexbox!
Susy! — это выход?
В поиске решения всех перечисленных выше проблем, я наткнулся на замечательный сеточный фреймворк Susy!, в целом очень хороший. Но мне не хватало скорости, т. к. susy! предлагал описывать колонки для каждого брейкпоинта отдельно:
.col {
@media (min-width: 768px) {
@include gallery(4 of 12);
}
@media (min-width: 1200px) {
@include gallery(3 of 12);
}
}
То есть susy! предполагает, что брейкпоинтами вы будете заниматься самостоятельно. Кроме того, susy! сам не пишет за вас display: flex
для, строк, вам нужно их не забывать прописывать самостоятельно. Отступы между колонками в нём задаются только относительные (сделать фиксированные в пикселях не получится). Также, он совсем недавно научился flex, а до этого он строил сетки на float
и :nth-child()
. В общем, susy! это хорошо, но хотелось бы скорости и лёгкости описания сеток для всех брейкпоинтов, как это было с bootstrap.
Поиск других сеточных систем также не давал особо результата — все либо идут по пути susy!, забывая про breakpoints, либо идут по пути bootstrap, предоставляя набор сгенерированных классов для руления сетками в html.
Велосипедостроение
Итак, решено было написать что-то своё, в результате родился fast-grid. Он также, как и susy, построен на sass. Какие же главные преимущества он предоставляет по сравнению с другими решениями, в частности, с susy!? В первую очередь скоростью за счёт меньшего количества кода, возьмем стандартный bootstrap пример:
<div class="row">
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">1</div>
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">2</div>
</div>
С помощью fast-grid такую сетку очень легко описать:
@import "~fast-grid/fast-grid";
.row {
@include grid-row();
}
.col {
@include grid-col(6 4 3 2);
}
https://codepen.io/PaulZi/pen/EvPbWK
Давайте теперь пройдёмся по нашим недостаткам, и увидим как fast-grid решает все эти проблемы.
Нестандартные сетки
Легко:
@import "~fast-grid/fast-grid";
.cols {
$grid: (
gap: 5px
);
@include grid-row($grid);
&__item {
@include grid-col(12 6 null (1 of 5), $grid);
}
}
https://codepen.io/PaulZi/pen/gxPXJq
Необходимость своего набора breakpoint-ов
@import "~fast-grid/fast-grid";
.cols {
$grid: (
breakpoints: (
xxs: 0px,
xs: 360px,
sm: 640px,
md: 960px,
lg: 1200px,
xl: 1600px
),
columns: 60
);
@include grid-row($grid);
&__item {
@include grid-col((xxs: 60, xs: 30, sm: 20, md: 15, lg: 12), $grid);
}
}
https://codepen.io/PaulZi/pen/XaXVmg
Избыточность и многословность / Отделение стилей от разметки
fast-grid это сеточный фреймворк для использования в css, а не в html на основе сгенериронных наборов классов. Благодаря этому разметка становится отделена от стилей, что благотворно отражается на дальнейшей поддержке. Также благодаря этому нет необходимости генерировать кучу вспомогательных классов (.col-xs-push-4
и т. п.), которые по большей части не используются.
Перекрытие ненужных стилей
Так как fast-grid — это набор mixin-ов, сам он не генерирует ни одного правила в css. Поэтому тут вы не столкнётесь с тем, что фреймворк стилизует элементы так как вам не надо. Да и вообще, это только сетки, и ничего больше.
Чужие стандарты и code-style
fast-grid — это mixin-ы, которые вы должны использовать внутри ваших классов, с такими наименованиями, которые вы сами предпочитаете. Любите БЭМ? Не вопрос!
Устаревшие методы
По умолчанию используется flexbox, что открывает множество возможностей и решает проблемы классических float. Например, можно легко менять порядок колонок.
В примере ниже, мы выводим сайдбар ниже основного содержимого для мобильной версии, и делаем его первым блоком на больших экранах:
https://codepen.io/PaulZi/pen/yoepbg
Можно было бы конечно этого добиться с помощью pull/push для float, но это очень костыльно.
Заключение
В целом, поставленная для меня задача была выполнена — теперь сетки для меня больше не вызывают никаких проблем, и вёрстка идёт быстро и легко. Больше о возможностях fast-grid вы можете почитать в репозитарии и рассмотреть на примерах:
GitHub: https://github.com/paulzi/fast-grid
Примеры: https://paulzi.github.io/fast-grid/
Вы всё ещё используете bootstrap? Тогда мы идём к вам!
Автор: Павел