Печатает... Список заметок

Дневники дизайн-системы. Выпуск 2. Цвета и типографика

Предыдущие выпуски:

Выпуск 1. Вступление


Типографика

Начал с выбора гарнитуры, определил следующие требования:

  • гротеск;
  • бесплатный для всех вариантов использования;
  • качественная кириллица.

Всем трём критериям соответствует IBM Plex Sans, доступная в гугл-фонтс. Подробнее о ней можно почитать в замечательной статье на «Тайп тудэй», которая и обратила моё внимание на это семейство шрифтов.

Следом определил список стилей.

Минимально достаточным набором посчитал такой:

  • page name — это h1, самый крупный и самый важный заголовок, обычно он один и чаще всего это название страницы, например заглавие статьи.
  • heading — это h2, название секции или главы.
  • subheading — h3, подзаголовок, именует подразделы.
  • headline — h4, вспомогательный низкоуровневый заголовок для именования незначительных элементов.
  • large text — текстовый стиль для расстановки акцентов, например, такой можно использовать для выделения тезисов в статье или оформления важных цитат.
  • text — стандартный стиль для простого текста.
  • caption — уменьшенный текст: подписи, вспомогательные элементы интерфейса.
  • code — моноширинный текст для фрагментов кода.

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

В своих проектах я использую базовую сетку размером в 4px, поэтому производя расчёт кеглей и интерлиньяжа я ориентировался на этот размер.

Тут важно помнить, что задать явно межстрочный интервал, вписав базовые линии в вертикальный ритм сетки не так просто. Всё потому что в классической типографике интерлиньяж — расстояние между базовыми линиями строк, а в вебе свойство line-height задаёт высоту контейнера строки. Если line-height больше font-size — сверху и снизу появятся отступы, которые будут выбивать элементы из вертикального ритма.

Некоторые ребята конкретно заморачиваются, дотошно вгоняя всё в сетку, я же, ради экономии времени, в этом проекте постараюсь не страдать чрезмерным перфикционизмом и буду стараться соблюдать общий порядок без лишнего пиксель-перфекта.

Расчёт кеглей начал с самого маленького десктопного стиля — caption, задав ему font-size в 15 пикселей.

Добавил 2 пикселя, получил 17 для основного текста и следом продолжил прибавлять каждое следующее число фибонначи: 15+2+3+5+8+13.

Получил ряд: 15, 17, 20, 25, 33, 46 пикселей. Подобрал к нему максимально гармонично выглядящие line-height, которые при этом кратны четырём. Проверил как это всё будет выглядеть вживую и немного скорректировал линейку кеглей на глаз.

Для мобильных устройств уменьшил размеры заголовков h1 – h3, оставив прочие стили неизменными.

Получилась такая таблица стилей:

Стиль font-size, px (desk) line-height, px (desk) интерлиньяж (desk) font-size, px (mob) line-height, px (mob) интерлиньяж (mob)
page name44521,1835401,14
heading34401,1728321,14
subheading26321,2323281,21
headline20241,220241,2
large text20281,420281,4
text17241,4117241,41
caption15201,3315201,33

Обращаю внимание на межстрочный интервал заголовков, уменьшенный относительно простого стиля. Это хорошо заметно в сравнении large text и headline, имеющих одинаковые кегли. Сделано это потому что в меру разреженные текстовые блоки легко читаются, при этом если задать тот же интерлиньяж заголовку, то он визуально «развалится».

После осталось создать стили в фигме.

И написать миксины для вёрстки.

@mixin text-style__page-name {
 font-size: 44px;
 font-weight: 700;
 line-height: 52px;
}
@mixin text-style__page-name_mobile {
 font-size: 35px;
 font-weight: 700;
 line-height: 40px;
}
@mixin text-style__heading {
 font-size: 34px;
 font-weight: 700;
 line-height: 40px;
}
@mixin text-style__heading_mobile {
 font-size: 28px;
 font-weight: 700;
 line-height: 32px;
}
@mixin text-style__subheading {
 font-size: 26px;
 font-weight: 600;
 line-height: 32px;
}
@mixin text-style__subheading_mobile {
 font-size: 23px;
 font-weight: 600;
 line-height: 28px;
}
@mixin text-style__headline {
 font-size: 20px;
 font-weight: 500;
 line-height: 24px;
}
@mixin text-style__large-text {
 font-size: 20px;
 font-weight: 400;
 line-height: 28px;
}
@mixin text-style__text {
 font-size: 17px;
 font-weight: 400;
 line-height: 24px;
}
@mixin text-style__caption {
 font-size: 15px;
 font-weight: 400;
 line-height: 20px;
}

При этом единый для всех стилей font-family и font-style я вынес за скобки, не забыв добавить исключение для фрагментов кода:

html, body {
 font-family: "IBM Plex Sans", sans-serif;
 font-style: normal;
}
pre, code {
 font-family: "IBM Plex Mono", monospace;
}

Палитра

Палитру поделил на три секции:

  • градации серого;
  • основные цвета;
  • сигнальные цвета.

Начну с серой палитры, она состоит из 13 оттенков серого цвета. Замечу, что в моей системе, как и в природе, нет чистого белого и чистого чёрного: $color__white и $color__text, который служит одновременно цветом стандартного текста и чёрным, по сути являются очень светлым и тёмным серым.

Также, мои оттенки серого не нейтральны. Светлые тона имеют едва уловимую примесь жёлтого, тёмные — синего, ведь при естественном освещении светлые области обычно более тёплые, тени — холодные.

Основных цветов у меня два: $color__first и $color__second. Первый и второй — абстракция, позволяющая передавать смысл, без привязки к конкретным названиям. Синий и оранжевый сегодня завтра могут стать зелёным и жёлтым, при этом мне не придётся переписывать названия переменных.

Каждый из цветов имеет по пять градаций: стандарт, два светлых варианта и два тёмных.

Сигнальные цвета — вспомогательная часть палитры. Алармы пригодятся для предупреждений (снова абстракция: сегодня я предупреждаю красным, а завтра оранжевым). Ок-цвета для одобрений и сообщений об успехе.

Итого на момент написания поста моя палитра выглядит так.

А переменные, в соответствующем файле так:

$color__white: rgb(254,253,251);
$color__gray_0: rgba(249,248,246,1);
$color__gray_1: rgba(241,241,238,1);
$color__gray_2: rgba(235,236,234,1);
$color__gray_3: rgba(229,232,230,1);
$color__gray_4: rgba(225,229,229,1);
$color__gray_5: rgba(217,219,221,1);
$color__gray_6: rgba(197,200,204,1);
$color__gray_7: rgba(169,172,176,1);
$color__gray_8: rgba(126,128,132,1);
$color__gray_9: rgba(84,85,88,1);
$color__gray_10: rgba(56,56,61,1);
$color__text: rgba(25,27,40,1);
​
$color__first_ultralight: rgb(159,226,255);
$color__first_light: rgb(83,196,244);
$color__first_standard: rgb(33,160,215);
$color__first_medium: rgb(25,143,207);
$color__first_dark: rgb(11,123,184);
​
$color__second_light: rgb(253,149,94);
$color__second_ultralight: rgb(255,195,157);
$color__second_standard: rgb(243,109,47);
$color__second_medium: rgb(243,85,22);
$color__second_dark: rgb(214,61,0);
​
$color__alarm_dark: rgb(209,13,0);
$color__alarm_standard: rgb(244,32,18);
$color__alarm_light: rgb(253,89,79);
​
$color__ok_dark: rgb(29,156,34);
$color__ok_standard: rgb(98,205,103);
$color__ok_light: rgb(147,231,140);

Эта серия постов — описание процесса, который подразумевает эволюцию продукта. Поэтому если вы читаете пост спустя некоторое время после публикации, имейте ввиду, что это не документация, некоторые вещи в актуальной версии работы могут отличаться от описанного.Актуальную версию можно посмотреть:

Полный список записей серии смотрите по тегу #raw-alfa