Pull to refresh

Создаем сетку с помощью Susy

Reading time 7 min
Views 48K


Susy — тулкит для создания сеток, с помощью которого можно решать множество разнообразных задач по расположению контента. В отличии от фреймворков, таких как Bootstrap или Foundation, Susy не предоставляет предопределенных классов для использования, а только лишь набор функций и миксин, после знакомства с которыми можно сделать много большее.

В этой публикации будут рассмотрены основные возможности Susy на примерах, а так же будет добавлен вывод с использованием flexbox.

Варианты установки


Susy может использоваться как дополнение к Compass, но это не является основным требованием. Поэтому можно обойтись одним SASS, при этом сделав импорт исходников. А здесь все примеры будут на CodePen, который уже месяца как два имеет встроенную поддержку.

Область применения


Может оказаться, что все те возможности, которые предоставляет этот инструмент, окажутся лишними и надуманными для решения задачи.
Пример:

<div class="grid">
  <div class="col-2-3">
     Main Content
  </div>
  <div class="col-1-3">
     Sidebar
  </div>
</div>

Использование Susy тут явно неоправданно. Don’t Overthink It Grids.

Более подходящий пример




Хочу обратить внимание на то, что не буду дублировать сюда фрагменты SASS кода, где задействуется тулкит. Поэтому смотрите пример, там я всю основную часть вынес наверх.

Здесь использовался следующий функционал Susy:
  • $susy [map]
    Глобальная переменная настройки сетки. В дальнейшем, все заданные здесь значения можно изменять просто добавляя альтернативные настройки в миксины и функции как параметр. Может быть полезна для задания значений по умолчанию, чтобы избежать дублирования.
  • container [mixin]
    Главным образом используется для горизонтального расположения контейнера. Так же задает максимальную ширину, следуя принципу “fluid on the inside and elastic on the outside”. Тут обеспечивается второе — elastic.
  • span [mixin]
    Основной миксин при использовании данного тулкита. Задает ширину элемента, применяет необходимые свойства для избавления от вертикальной направленности блочных элементов. Еще может добавлять отступы от других элементов (gutters).
  • gallery [mixin]
    Используется при множестве элементов, которые располагаются в несколько строк. Необходимо задать количество элементов в строке, все остальное делается автоматически: расчет ширины, отступы от других элементов, перенос на новую строку.

В этом описании я старался показать основное назначение средств тулкита, избегая подробностей о различных настройках и особенностях реализации. Первое всегда можно посмотреть в документации, а второе в репозитории на GitHub.

Этого для “достаточно полного” обзора будет явно мало, поэтому рассмотрим некоторые части более подробно. Но хотелось бы чтобы это все не обратилось в перевод документации.

Конфигурация сетки


В зависимости от конфигурации мы получаем различный вывод от миксинов и функций. И так получается, что чуть ли не весь результат может контролироваться через эти настройки, при этом даже не затрагивая параметры. Поэтому понимание конфигурации — понимание работы тулкита и его возможностей.

Есть два основных способа задания конфигурации:
  1. Глобальная переменная
    Это та самая $susy, которая является ассоциативным массивом (map) и имеет следующие значения по умолчанию:
    Скрытый текст
     $susy: (
      flow: ltr,
      math: fluid,
      output: float,
      gutter-position: after,
      container: auto,
      container-position: center,
      columns: 4,
      gutters: .25,
      column-width: false,
      global-box-sizing: content-box,
      last-flow: to,
      debug: (
        image: hide,
        color: rgba(#66f, .25),
        output: background,
        toggle: top right,
      ),
      use-custom: (
        background-image: true,
        background-options: false,
        box-sizing: true,
        clearfix: false,
        rem: true,
      )
    );
    


  2. Использование shorthand синтаксиса
    В этом случае все настройки передаются как параметр, который является списком (list). Особенность такого способа заключается в том, что мы можем указывать значения в совершенно произвольном порядке и при этом не указывать свойства, которым будут присвоены данные значения.

    Есть два типа данного синтаксиса: layout и span.
    Пример:

    12 столбцов, коэффициент отступа 0.25, ширина в процентах, фоновое изображение для отладки
    $layout: 12 .25 fluid show
    2 колонки начиная с 4-ой позиции асимметричной сетки, без отступов
    $span: 2 at 4 of (1 2 3 2 1) no-gutters
    можно и так, чтобы в list был map
    $span: 2 at 4 (columns: (1 2 3 2 1), gutters: no-gutters)
    

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

Теперь давайте пробежимся по основным свойствам, которые есть в конфигурации:
  • math
    Тип сетки: static или fluid. В первом случае все размеры статичны и задаются в пикселях (как в 960.gs), во втором же все указывается в процентах. Использование static сейчас неактуально, поэтому таких примеров не будет.
  • columns
    Количество колонок, которые мы можем выделять для наших элементов. В Bootstrap, например, это значение равно 12.
  • gutters
    Размер отступов между колонками. При fluid является коэффициентом для размера колонки (размер отступа = размер колонки * коэффициент).
    Хотелось бы показать момент, который немного сбивал с толку:

    span(1 of 2)
    span(6 of 12)
    

    Здесь можно ожидать одинакового результата, но это не так. И дело как раз в отступах, в том что их размер зависит от размера колонок и коэффициента (коэффициент в этих случаях одинаков).
    Тут действует следующая закономерность:
    Чем больше колонок задано, тем каждая колонка меньше по ширине. А чем меньше колонка — тем меньше отступ.
    Получится что в первом случае отступ будет больше, чем во втором. И значит ширина элемента в первом случае будет меньше, чем во втором. Это будет показано дальше на примере.
  • gutter-position
    Отступы можно делать как с помощью margin, так и с помощью padding. Так же можно задать отступ с определенной стороны, либо с двух сторон одновременно.
  • output
    Обычно, для избавления от вертикальной направленности блочные элементы “флоатятся”, либо используется inline-block (у которого хаков не меньше будет). Тут же есть выбор либо float, либо isolate. Второе для меня было неизвестным, поэтому давайте распишу тут подробнее.
    Скрытый текст
    Давно-давно писали про проблему с округлением процентов при задании ширины у элементов (sub-pixel rounding). Так получалось, что все сотые доли процентов могли стать целыми, где-то в большую сторону, а где-то и в меньшую. Поэтому в некоторых браузерах элемент, которому следовало касаться контейнера с края, находился на расстоянии нескольких процентов. Что еще не так плохо, так как при округлении в большую сторону элемент мог вполне перейти на другую строку, потому что общая ширина получалась более 100%.
    Решение данной проблемы было найдено. В данном случае элементы позиционируются абсолютно, но только по горизонтали (благодаря margin в -100%). А по вертикали поток не теряется и можно сделать обычный clear. То есть элемент не сможет перейти на другую строку, а погрешность получается в 1% из-за независимости от размеров других элементов. Кстати, именно этот метод использует gallery.
    Посмотреть примеры можно здесь. Сейчас такой проблемы не наблюдается, но в предыдущем Safari все же было.

  • debug
    Есть два способа для отладки:
    1. background
      В данном случае фоновое изображение является градиентом, который представляет из себя колонки с отступами.
    2. inspect
      В документации почему-то не написано, но такая опция все же есть. Добавляет к выводу миксинов “описательные” свойства и значения. В Firefox этого не увидеть (он их игнорирует и не выводит) в отличии от Chrome. Может быть полезно при адаптивной верстке.


Примеры


Isolate вывод




В примере хочется обратить внимание на независимое от других элементов позиционирование, при котором теряется горизонтальный поток. Поэтому необходимо указывать позицию для вывода (location) после at:

span(2 of 4 at 1 isolate)

И получается, что мы можем задавать порядок расположения прямо в CSS. Справа вверху есть кнопка backward, которая показывает данную возможность. Но order в flexbox конечно же будет лучше, потому что он был сделан специально для этого, да и с isolate мы можем менять порядок только у элементов одной строки.

Асимметричная сетка


В отличии от привычного случая, когда все колонки равны, асимметричная сетка позволяет задавать колонки разного размера. Сетка задается коэффициентами, и отношение ширины колонок равно отношению коэффициентов. Здесь тоже нужно указывать позицию для вывода (location) после at, для того чтобы можно было расcчитать ширину элемента.

элемент занимает 2 колонки, начиная с первой позиции (3 2)
span(2 at 1 of (3 2 3))
элемент занимает 1 колонку, начиная с третьей позиции (3)
span(1 at 3 of (3 2 3))

А теперь пример. В статье о сетках конечно же следовало упомянуть о золотом сечении. Можно было бы сделать две колонки с асимметрией как (1 1.618), но это неинтересно. Нужно больше прямоугольников! Поэтому есть пример использования асимметричной сетки с биномиальными коэффициентами, которые как раз сюда подходят. Треугольник Паскаля:



В скрипте и стилях в самом начале есть переменная timeout. Ее можно сбросить в false, тем самым увеличив количество строк. Последнее время мне выдавался timeout на препроцессинг стилей, поэтому уменьшил количество.

Различный span




В этом примере глобально включен debug inspect, вывод которого можно увидеть в инспекторе.

Пример по порядку:
  1. Включена отладка в виде фонового изображения с градиентом. Отображается при наведении на переключатель, который располагается справа вверху.
    Может получиться так, что элементы будут немного несоответствовать фоновому изображению. Это проблема процентного округления размера градиента.
    Первый элемент “проталкивается” вперед на 2 колонки. Последний направлен вправо из-за указания last.
  2. Отступы у колонок идут с двух сторон. Это позволяет не указывать крайние элементы.
  3. Отступы задаются как padding и размещаются с двух сторон.
  4. Bleed представляет из себя “вылезающий” за отступы контейнера элемент.
  5. И последним является пример с разным количеством колонок. Как уже писал выше, можно было бы ожидать одинаковый результат, но получается не так.

Flexbox




Flexbox предоставляет много интересных возможностей для расположения контента, но основной проблемой здесь был выбор общих и очевидных вариантов использования. И скажу, что получилось найти таких вариантов не так много, и они вполне могут быть сделаны старыми способами.

Вариант применения justify-content в Susy сразу не имеет смысла, потому что тулкит основывается на использовании всего пространства. Так же из списка исключаем flex-grow и flex-shrink.
Возможность переноса элементов на другие строки не подходит для работы с системой сеток. Минус flex-wrap. И align-content тоже.
Как использовать column и column-reverse тоже неизвестно.

Остальное остается. Вот как это можно применить:
  • order
    С помощью этого свойства мы можем менять порядок отображения элементов, независимо от их расположения в DOM.
    Такое можно было сделать с помощью isolate, пример был выше. Конечно же, применение order выглядит лучше.
  • align-items и align-self
    С помощью этих свойств можно получить колонки одинаковой высоты используя stretch. А так же различные вертикальные выравнивания (flex-start, center, flex-end, baseline).
    До этого выручали таблички.
  • flex-direction
    В Susy есть возможность указывать направление контента: LTR и RTL. При float выводе это регулируется заданием left или right.
    Здесь решением будет использование row-reverse.

Теперь в $susy-keywords изменился output и был добавлен align:
Скрытый текст
$susy-keywords: (
  container: auto,
  math: static fluid,
  output: isolate float flexbox,
  align: stretch start center end baseline,
  container-position: left center right,
  flow: ltr rtl,
  gutter-position: before after split inside inside-static,
  box-sizing: border-box content-box,
  span: full,
  edge: first alpha last omega full,
  spread: narrow wide wider,
  gutter-override: no-gutters no-gutter,
  role: nest,
  clear: break nobreak,
  debug image: show hide show-columns show-baseline,
  debug output: background overlay,
);


На этом все. Make grids, not war.
Tags:
Hubs:
+17
Comments 5
Comments Comments 5

Articles