Новая мажорная версия Сьюзи — Susy 3

Все, что нужно для начала работы с Susy 3 на русском. На 90% это вольный перевод следующих статей:
http://oddbird.net/susy/
http://oddbird.net/2017/06/28/susy3/
http://oddbird.net/2017/06/13/susy-spread/

Photo stolen from http://oddbird.net/susy/
Это незаконченная статья. В переводе могут быть неточности, я писал его всю ночь до 5 утра, и мог где-то жестоко затупить. Пишите, если что.

В начале месяца Июля года 2017-го зарелизилась новая мажорная версия 3.0 Susy. Это “сетка”, а вернее - калькулятор процентов, работающий на Sass. С ее помощью удобно строить margin-based сетки, которые будут давать чистый код на выходе, без затрагивания HTML разметки.

Они ведут себя предсказуемо, работают быстро и очень просто: все размеры в CSS в итоге будут заданы либо в процентах, либо через нативную CSS-функцию calc (тоже в общем-то, в процентах). 
Например, вот этот вот бред:

// Sass:
.main-nav
max-width: span(10 of 12 set-gutters 2em)

будет преобразован в этот ванильный CSS-бред:

// CSS:
.main-nav { 
max-width: calc(18em + ((100% - 22em) / 12 * 10))
}
Тут и дальше везде будет использован синтаксис Sass

Сьюзи была сделана, чтобы избежать сложных математических вычислений при верстке. Родная CSS-сетка (Grid layout) уже на подходе (примерно 70% поддержки браузерами), поэтому как бы еще и переходить рановато, и уже хочется что-то крутое. Susy 3.0 поможет сгладить этот переход от быдлокодерства на флоатах и всяких там Бутстрапах до Святых Нативных CSS-Гридов. Дальше расскажу почему.

Хоть евангелисты в лице Rachel Andrew и Вадима Макеева и говорят, что можно использовать Grid Layout для основной разметки, я решил заморочиться, и сделать разметку не чисто на гридах, а с фаллбеком до Сьюзи. Так, вроде как, делает сейчас сам Zell Liew (автор книги о Susy 2) правда, он не уточнил, до какой версии Susy он делает фалбек.

Это последняя предсмертная версия Susy. Дальше нет смысла выпускать какой-либо Бутстрап, Фаундейшин, или Сьюзи. Пора уже вернуть все это дерьмо в браузер .Все, что делают сейчас многочисленные “фреймворки” сеток будут делать CSS Grids.

Но под конец разработчики захотели не просто закрыть лавочку, а выпустить последнее мажорное обновление для оставшихся крайних случаев.

Они тупо урезали Susy до ядра — остался лишь модуль чистой арифметики, называемый `Su ` и синтаксический сахар в виде API. Остались только две главные API функции: span() и gutter() и всего-навсего 4 основных параметра в Sass map.

Да, в Susy 3.0 нету миксинов! Когда они писали Susy 1 и 2 флоаты были единственным вариантом как разместить элементы. Но это было давно и неправда. С хаками в верстке покончено! Тут они имеют ввиду конечно же flex box.

Ядром (и единственной фишкой) Susy всегда была арифметика и человекопонятные API. Использование только арифметики и функций позволит Susy навсегда стать независимой. Теперь ей не важно, что Вы используете: флоаты, инлайны, флексы, или даже гриды.

Если Вы можете себе позволить поддерживать только новые браузеры, где есть гриды, то Вы должны навсегда забыть про Susy. Она Вам не нужна. Если нет, то можно очень быстро сверстать все на Гридах, обернув этот код в директиву @supports:

@supports (display: grid) {
// Ваша ультра-крутая разметка на
Гридах
}

А потом сверстать какую-то говно-версию для устаревших браузеров на флоатах, инлайнах и клеарфиксах с оверфлов-хидденами — все как мы любим кароче. Говняность этой верстки нужно согласовывать с заказчиком, конечно. Заранее предупредив, что если делать ВЕСЬ сайт под старые браузеры, это будет в два раза дороже и дольше. А перспектив — никаких.

Susy-колонки и grid-template-columns от CSS grids

Синтаксис Susy максимально похож на синтаксис CSS Grids. Потому что они хотят двигать людей в этом направлении. И правильно.

Теперь чтобы создать колонки на Susy 3.0 нужно прописать то же, что и в гридовском grid-template-columns : список размеров колонок с функцией susy-repeat() которая соответстует repeat в Гридах:

// Симметричный макет
$grid-template-columns: repeat(12, 120px)
$columns: susy-repeat(12, 120px)

// Асимметричная сетка и микс с единицами измерения
$grid-template-columns: 120px repeat(4, 1fr) 30em
$columns: 120px susy-repeat(4) 30em

Где Гриды используют fr единицу измерения, Susy использует ничего. Просто цифра и все. 
То есть 2fr = 2 в Susy.

По дефолту Susy настроена на 4-колоночную сетку. Это записывается так:

susy-repeat(4)
// или так:
susy-repeat(1 1 1 1)
// т.е. ячейки сетки одинаковы по соотношению. Все равны, один к одному

Вот несколько примеров сетки с разным количеством колонок (столбцов):

// 12-колончатая em-based сетка… (эти две записи дают идентичный результат)
$columns: susy-repeat(12, 5em)
$columns: 5em 5em 5em 5em 5em 5em 5em 5em 5em 5em 5em 5em
// сетка "святого грааля" (погуглите что это)
$columns: 12em 1 200px
// добавим еще немного резиновых колонок в сетку "святого грааля"
// снова таки, эти две строчки дадут одинаковый результат:
$columns: 12em susy-repeat(4) 200px
$columns: 12em 1 1 1 1 200px
// три раза повторить сетку с двумя колонками размером 8em и 200px
// т.е. на выходе получится сетка из 3*2=6 колонок
// размером соответсвенно: 8em 200px 8em 200px 8em 200px:
$columns: susy-repeat(3, 8em 200px)
$columns: 8em 200px 8em 200px 8em 200px

Это разительное отличие от Susy 2, где можно было обычным номером (цифрой) 12 указать 12-колончатую резиновую сетку. Теперь нужно использовать именно приписку-функцию susy-repeat(12) . И сделано это чтобы больше соответствовать нативному CSS Grid Layout.

Покольку Susy не имеет доступа к DOM они сделали несравнимые и смешанные единицы через нативную для CSS функцию calc.

Susy-гаттеры (отступы между колонками) и grid-column-gap от CSS grids

Гаттеры в Susy не изменились с версии 2.0. Хотя, теперь их новый вывод в CSS посредством функции calc позволяет нам мешать разные единицы измерения новым способом. Это похоже на гридовское свойствоgrid-column-gap , принимающее любое значение гаттеров для разделения колонок. Безмерные гаттеры (просто число\цифра) будут вести себя как гридовская фракция. Так же, как и безмерные колонки. Гаттеры с указаными единицами измерения останутся статичными:

// unitless fluid gutters - безмерные резиновые гаттеры 
// (отступы между колонками)
$gutters: 0.25;

// static gutters - статичные отступы.
// Т.е. даже если колонкb будeт 2 пикселя, то отступы
// будут все равно 10 пикселей.
$gutters: 10px;

Сьюзи упростит нашу арифметику

Если мы не можем юзать CSS Grid, мы хотим чтобы Susy помогла нам с математическими вычислениями при построении сетки.

Для начала, сделаем нашу box-model по размеру блока (внимание, синтаксис Sass):

*
-moz-box-sizing: border-box
-webkit-box-sizing: border-box
box-sizing: border-box
&::before, &::after
-moz-box-sizing: border-box
-webkit-box-sizing: border-box
box-sizing: border-box

Используем паддинги для гаттеров

На самом деле, арифметика сеток сложна по-настоящему только тогда, когда мы добавляем марджины для наших гаттеров. Без этого у нас все четко, если мы указали элементуspan(3) , то он действительно займет 3 фракции. Или, например, мы хотим, чтобы элемент занимал 10 колонок из 64-х. Пишем:

.logo
width: span(10 of 64)

И это будет работать, даже если у вас везде 12-колончатая сетка. Оно само возьмет за 100% ваши 12 колонок, разобьет их на 64, и займет ровно 10 из них. Не нужно ничего никуда прописывать лишний раз!

Или же можно еще круче, задать в соотношениях:

// With Sass
.simple-grid
float: left
width: percentage(3/12)

/* Without Sass */
.simple-grid
float: left
width: calc(3/12 * 100%)

В данном выше случае элемент с классом .simple-grid займет четко 3 части из 12, и сделает это сам без ваших усилий в вычислении. Это же прекрасно — время экономится — теперь можно еще больше смотреть всяких смехуечек в ютубчике!

Там они еще говорят, что можно совсем упороться, и построить свою собственную сетку, используя нативные CSS кастомные свойства (Also Known As “Variables”). Но сейчас давайте не будем.

Если вы хотите использовать flexbox с Susy для построения более кроссбраузерных сеток, вам нужно всего лишь заменить flex-basis значения на Сьюзишные функции span() .

.flex
flex: 1 1 span(3 of 12)

Susy 3

Итак, если не получается упростить верстку с помощью гаттеров, основаных на паддингах с флексбоксами, начинаем разбираться с Susy 3.

Она помогает делать проще вычисления в марджин-гаттерах, асимметричных сетках, и в случае со смешанными единицами. Это действительно сложно сделать без Susy или CSS Grids да еще и без тибетского шамана.

В таких случаях, зацените что может Susy, она можете переварить этот кошмар:

$width: ($span + (($span - 1) * $gutter-width)) / ($columns + (($columns - 1) * $gutter-width))

…в нормальную тему!

$width: span(3)

Сетка по требованию

Один умник там у них повыпендривался, и спросил, вынуждает ли Сьюзи создавать сетку для всего документа. “Но, блин, зачем, Карл??”. Зачем писать целую систему миксинов или классов, если можно использовать всего лишь две функции span() и gutter() везде. Это две главные API Susy 3. Это более читабельно и гибко, нежели любая другая система сеток. Ничего не остается скрытым от взгляда — все максимально просто и наглядно:

// class names are for demonstration only…
.float
width: span(3)
margin-right: gutter()

.flexbox
flex: 1 1 span(3)
padding: 0 gutter() / 2

.push-3
margin-left: span(3 wide)

Ну, ладно, для постояльцев Cекты Cвидетелей Миксинов есть рекомендации:

// SCSS:
@mixin span(
$span,
$config: $susy
) {
width: span($span, $config);
@if index($span, 'last') {
float: right;
}
@else {
float: left;
margin-right: gutter();

Только юзеры-выпендрежники захотят сделать весь макет на сетке Susy 3. Большинство галерных гребцов будет довольна двумя Susy функциями.

Susy 3 конфигурация (или что писать в Sass map)

Писать придется очень мало. Всего 4 настройки есть у Susy3:

  1. Количество колонок
  2. Размеры гаттеров (отступы между колонками)
  3. Распространение spread (отдельно напишу потом про это)
  4. Распространение контейнера — container-spread (тоже отдельно напишу)

Код соответственно описанию:

// Синтаксис Sass (map в Sass пишется только в одну строку, 
// не пытайтесь переносить строки):
$susy: ('columns': susy-repeat(4), 'gutters': 0.25, 'spread': 'narrow', 'container-spread': 'narrow')
// Синтаксис SCSS:
$susy: (
'columns': susy-repeat(4),
'gutters': 0.25,
'spread': 'narrow',
'container-spread': 'narrow',
);

Выше мы уже разбирали что такое columns и gutters (это и ежу понятно в общем-то). И если честно, то со спредами тоже все предельно просто. 
Я не знаю зачем они там все так усложняют. Рокет саенс, блин, какой-то прям!

Spread (занимаемая область) в Susy 3

Понятие spread не ново для Susy 3. Оно было и в Susy 2 да и в любых других сетках. Но вся мощь этой фичи обычно скрыта за другими названиями или неочевидными параметрами (напримерgutter-position в Susy2).

Каждая сетка так или иначе решает вопрос места, которое занимает элемент (spread). Но нет еще ни одной сетки, которая бы указывала явно и недвусмысленно этот параметр. В этом плане Susy 3 — первопроходец.

Кстати, даже в новомодных Гридах нету такой гибкой настройки spread.

Есть два параметра распространения, что логично. Один для глобальной сетки — spread, это та сетка, которую умеет строить бутстрап, например. Это глобальная сетка, на весь документ. Она одна-единственная. Задается первым параметром в map:

$susy: (spread: narrow)

И второй параметр —container-spread описывает как сетка-родитель (контейнер) обрабатывает доступные гаттеры. Большинство сеток вставляют гаттеры между колонками. И это самый частый юзкейс, который мы будем наблюдать по жизни. Это значит, что в сетке гаттеров на 1 меньше, чем колонок. Это узки (narrow) режим. Он установлен по умолчанию.

По сути, этот параметр существует для задания распространения детей (потомков) внутри главной сетки. Т.е. все, что внутри body или внутри какого-то элемента — это уже по сути ребенок (потомок), а соответственно, на него уже будет действовать именно эта установка:

$susy: (container-spread: narrow)

Теперь дальше. Как распространяется глобальная сетка, и “вторичная”.

Есть три режима этого самого “распространения”:

Narrow (узкий) занимает место четко по колонкам. Не залазит на гаттеры. Различий, что spread, что container-spread — нету. Просто занимает столько колонок, сколько указано, не учитывая гаттеры.

Свойство глобальной сетки spread: narrow
Свойство для “потомков” container-spread: narrow

Wide (широкий) — если мы укажем этот параметр, то в сетке у нас появится еще один гаттер. т.е. обычно у нас в сетке гаттеров на один меньше, чем колонок. А тут их будет равное количество. Правда, это с математической точки зрения. Так-то визуально гаттеров будет на 2 больше, чем колонок. Но крайние гаттеры будут не полноразмерными.

И тут фишка: для глобальной сетки (т.е. для spread:wide) сетка захватит полностью весь гаттер справа (см. рисунок).
А для дочернего контейнера container-spread: wideэтот лишний гаттер делится на две равные части, ставит их по краям сетки и занимает оба края (см. рисунок).

Свойство глобальной сетки spread: wide
Свойство для “потомков” container-spread: wide
Корявым фломастером я выделил области, на которых нужно акцентировать внимание. Это специально, чтобы сформировать порцию информации в нашем с сами мозгу. Прочитал данный прием в книге “Думай как математик”.

Wider (широчайший) занимает самый большой кусок пространства — саму колонку и гаттеры вокруг нее. Тут все просто и без нюансов. Полноразмерных гаттеров в случае с wider будет уже действительно на один больше, чем колонок:

Свойство глобальной сетки spread: wider
Свойство для “потомков” container-spread: wider

Важный нюанс: в Susy 3 нету понятия контейнера, как допустим, в bootstrap 3. Теперь в Сьюзи каждый элемент сетки ведет себя так, будто в нем есть своя сетка, по которой можно выровнять контент, хранящийся в этом “контейнере” (потомки). Т.е. все элементы-родители выступают контейнерами для своих прямых потомков (очень похоже на Flexbox и на CSS grids пока еще нету саб гридов).

Вот и все ньюансы со спредом (spread).

Документация Susy 3.


Непереведенная важная часть: Pushing, Pulling, & Padding элементов


Далее будет перевод кусков 
“Susy3 Shorthand Syntax”
“Primary API Functions”
“Installation & Other Options”
отсюда: http://oddbird.net/2017/06/28/susy3/