Open belozer opened 5 years ago
Ответ из Telegram от @koloskof
Фундаментально Тематизация отвечает тому подходу, которого мы с дизайнерами придерживаемся: «При проработке визуала человек описывает смысл блока (смысловые модификаторы), ничего не зная про Тему, а при проработке Темы человек может ничего не знать про блоки, которые будут в ней отрисовываться»
Для каждого Мерча/Лейбла/Компании есть три Темы:
Внутри каждой Темы, цветовые переменные разделены на группы.
Базовые переменные, которые формируют основную палитру (они не используются в интерфейсе, нужны только для образования интерфейсных пременных (наследования)). Они имеют префикс color-base-*. Пример:
$color-base-base $color-base-system
имя base переменной | что наследуется |
---|---|
$color-base-base | типографика |
$color-base-essential | фоны |
$color-base-project | акцентные цвета |
$color-base-phantom | бордеры, оверлеи, тени |
$color-base-path | ссылки |
Цвета фонов, которые формируются с учётом состояний блоков. Значения наследуются от цвета переменной $color-base-essential. Они имеют префикс color-bg-*. Пример:
$color-bg-brand, $color-control-bg-default-affect
Цвета типографики, которые формируются с учётом визуальной иерархии и так же наследуются от цвета переменной $color-base-base. Они имеют префикс color-typo-*. Пример:
$color-typo-primary, $color-typo-warning
Каждый цвет темы вычисляется на основе изменения параметров hue(h) — тон, saturation(s) — насыщенность, lightness(l) — яркость и alpha(a) — полупрозрачность у base переменных.
Например цвет для основного текста вычисляется на основе цвета переменной $color-base-base с уменьшением альфы (полупрозрачности) до 95%:
$color-typo-primary: color($color-base-base a(95%))
Другой пример, для бордеров: $color-bg-border: color($color-base-phantom l(100%) a(20%));
Стоит помнить, что параметры переменных можно не менять. Если с точки зрения визуала цвет подходит, то base переменную допускается использовать as is. В этом случае color(...) не указывается, т.к. идет прямое наследование(?)присвоение:
$color-typo-alert: $color-base-alert;
Альфа-канал задается всегда в %: $color-typo-primary: color($color-base-base a(95%));
Как сказано выше, для формирования нового цвета переменной, необходимо изменить один из параметров h, s, l, a. Допускается два вида записи:
h(50%) ↔️ h(50)
новыйПараметр = 0.5(текущийПараметр).
При HUE = 20, новый HUE = 0.5(20) = 10
h(+50%) (работает для + и -)
новыйПараметр = текущийПараметр + 0.5(текущийПараметр).
При HUE = 30, новый HUE = 30 + 0.5(30) = 45
Если параметр указан h(-X) и [текущийПараметр - X(текущийПараметр)]<0, то результирующее значение будет рассчитано как 0.
Пример: h(-125%), при HUE = 30, новый HUE = 30 - 1.25(30) = 30 - 37.5 = -7.5 → 0
Тема всегда должна быть примиксована как минимум на один самый верхний узел. Она задается правила как будут отрисовываться все сущности внутри одного интерфейса/экрана.
Но также всегда есть возможность делать разнотематические вставки в рамках одного интерфейса. Так же Темы могут прилетать динамически, примиксовываясь по какому-либо событию на тот или иной узел.
Контролы реагируют на уровень общей Темы так же как и все остальные интерфейсные сущности.
При этом их цветовые переменные наследуются от тех же основных переменных, что и цвета состояний блоков и типографики, вычисляются через математику (путем изменения HSL).
Благодаря Custom Properties, контролы подстраиваются под цветовую схему блока в который они помещаются (в зависимости от того, какая модификация themecolor* у ближайшего родителя). Это позволило органично вписывать Лего контролы в любые интерфейсные сущности и распространять на них единую Тему.
(тут кусок в котором взяли выборку брендов. Классифицировали их по цветам. По каждому цвету взяли самый недосвеченный и пересвеченный пример и на каждый из них попробовали написать Темы в дефолтном, инвёрсном и брендовом вариантах. Для того чтобы когда нужно описываться тему для очередного бренда можно было скопировать макисмально близкую по цвету пачку тем и немного подкрутить математику)
В чате https://t.me/whitepapertools, можно Илью более подробно про это поспрашивать
Любопытно, почему для тем (skins) нельзя использовать разные пути к css-файлам? Или вам обе темы нужны одновременно?
@viT-1 Использовать одновременно.
Решили использовать подход @whitepapertools. Дополнительно, в некоторых модификаторах использовать подход описанный https://github.com/bem-site/bem-forum-content-ru/issues/1572#issue-430090239, работающий по принципу props/state
Блоки и темы оформления.
Уже давно пытаюсь избавиться от боли модификатора
_theme
у блоков. У нас 2 темы блокаbutton
- публичная и админка, около 2K строк стилей в сумме.Имхо, блок должен быть максимально реиспользуемым и не тянуть ненужный код. Сейчас под тему запихиваются ВСЕ комбинации модификаторов блока, даже если они не нужны на странице. Это боль в поддержке.
Очень близки идеи http://whitepaper.tools/. В целом работаю тоже в этом направлении.
На данный момент пришёл к использованию 2-х видов переменных.
1. Глобальные/Контекстные (что реализовано в whitepaper)
Задаются через блок
theme
и модификаторыtheme_color_*
theme_size_*
и т.д. Провайдят контекст переменных вниз по дереву.2. Локальные (Уровень блока)
Задаются с указанием префикса имени блока. Такой способ явно ограничивает пространство имён переменных, чтобы случайно не сломать что-то внутри дерева. И позволяет легко изменять их через модификаторы.
Блок получает переменные из контекста и преобразует их в локальные для дальнейшего использования в своих стилях.
3. Модификаторы
Дальше через модификаторы жонглируем уже локальными переменными блока.
Данный подход позволяет избавиться от длинных селекторов в css.
Например если мы не хотим использовать локальные переменные, то нужно писать классы таким образом
И это только 2 состояние, а там ещё N состояний, включая вложенные элементы...
4. Именование цветов
После долгих ресёрчей толком не нашёл способа лаконично и предсказуемо описывать переменные. Наиболее лаконичным стилем нашёл подход из Material Design https://material.io/design/color/
В кратце, есть какой-то цвет и для него создаётся рекомендуемый контрастный цвет.
В качестве дополнительного задания контраста есть идеи использовать доп. параметр
-low
,-hight
В целом такое именование позволяет добиться предсказуемых результатов при создании темы.
Правда это тоже не является серебренной пулей, т.к. где-то могут не использоваться рекомендуемые переменные.
И не известно на сколько в новой теме
surface
иerror
будут контрастны друг к другу.upd Пересмотрел ещё раз whitepapper https://github.com/whitepapertools/whitepaper-portal/tree/a6bb170522b470560e3572856cf11b1929e1469a/common.blocks/theme
Идёт разбитие цветовой темы на 2 вида. 1 базовые цвета страницы, 2 контролы (кнопки, чекбоксы, инпуты и т.д.).
Данный подход позволяет наиболее однозначно разрабатывать цвета для темы и тестировать их в "вакуме", что очень удобно. Тема не рассчитывается на все цвета радуги. Если нужно много вариаций, то стоит сделать несколько тем, что и плюс и минус.
Плюсы:
Минусы:
5. Старые браузеры
Любимый IE... Хоть поддержка по caniuse уже > 90% https://caniuse.com/#search=css-variables он ещё живёт...
Как один из подходов решения этого вопроса есть компромиссный вариант - делать версию с одной темой. Все переменные темы дублировать в
:root
и через postcss ставить статичные значения.Этот сегмент получит сильно урезанный вариант оформления... Если это сильно критично то от локальных переменных придётся отказаться и делать стилизацию через каскады.
Либо использовать подходы с css-in-js... Но они не лишены недостатков.
6. Дизайнеры, разработчики и система
Тут конечно есть конфликт интересов... Но имхо, у дизайнера должна быть система, по которой он работает и она должна быть логичной (например http://whitepaper.tools/)
П.Н. Небольшая демка "на коленке" Буду благодарен, если поделитесь своей системой стилизации блоков и именованием переменных.