# Темы

Расположение тем в проекте: source/scss/project/themes/.

Тема - это вынесенная (отделённая от общих css правил) часть css правил, которая содержит css свойства связанные с цветом (исключением являются пользовательские правила предназначенные для конкретной темы). Процесс сортировки правил происходит с помощью пост-обработки в postcss плагине и не требует пользовательского вмешательства. Для работы с темой используется ungic.theme модуль.

Тема состоит из:

  • основных цветов,
  • конфигурации,
  • палитр

Возможности при использовании тем:

  • генерация тем для любых компонентов или набора компонентов,
  • генерация любых цветовых схем (тем), без необходимости в дополнительных манипуляциях,
  • автоматическая, "умная" инверсия тем.
  • написание CSS стилей относительно тем и их инверсий с помощью методов ungic.theme модуля.
  • использование переменных new

TIP

При генерации css стилей, темы могут быть включены как в общий css файл, так и в отдельный, включая инверсию темы!

TIP

Все css правила тем, изолированы друг от друга с помощью css селектора. Можно подключить любое кол-во тем к HTML документу и переключаться между ними с помощью класса типа un-theme-{theme-name} у корневого элемента страницы:

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Общие стили с темой по умолчанию -->
  <link rel="stylesheet" href="css/app.css">
  <!-- Инверсия темы по умолчанию -->
  <link rel="stylesheet" href="css/app-inverse.css">

  <!-- Доп. тема viola -->
  <link rel="stylesheet" href="css/app.theme-viola.css">
  <!-- Инверсия темы viola -->
  <link rel="stylesheet" href="css/app.theme-viola-inverse.css">

  <!-- Доп. тема darkela -->
  <link rel="stylesheet" href="css/app.theme-darkela.css">
  <!-- Инверсия темы darkela -->
  <link rel="stylesheet" href="css/app.theme-darkela-inverse.css">
</head>
<body>
    <!-- Тема по умолчанию -->
</body>
</html>
<!-- Инверсировали тему по умолчанию, с помощью класса un-inverse -->
<html dir class="un-inverse" data-ungic-root>
<!-- Переключили на тему viola -->
<html dir class="un-theme-viola" data-ungic-root>
<!-- Переключили на тему viola + инверсия -->
<html dir class="un-theme-viola un-inverse" data-ungic-root>

# Структура

Тема состоит из одного конфигурационного .scss файла расположенного в themes директории проекта. Тем в проекте может быть любое количество, однако, в режиме разработки используется только одна тема указанная в конфиг. файле проекта которая может быть переключена с помощью dev команды в scss cli меню, а при генерации релиза можно сгенерировать любое количество тем проекта.

Обратите внимание!

В режиме разработки используется только одна тема проекта указанная в конфиг. файле проекта, для переключения между темами и другими параметрами в режиме разработки используется dev команда из scss CLI меню!

TIP

Конфигурационный файл темы является частью системного ungic.theme модуля.

Пример default.scss файла темы:

$colors: (
    primary: #9cef0a,
    secondary: #3d3931,
    success: #cce678,
    danger: #e6787d,
    info: #4bafee,
    warning: #eee84b,
    system: (#cf7e16, #e8a900),
    text-color: (#3a3b39, #fff9ea),
    background-color: (#FFF, #202120)
);

$config: (
    brightness: (
        offset-brighten: 20,
        offset-dim: 20,
        saturation-brighten: (0, 0),
        saturation-dim: (0, 0)
    ),
    relative-light-limit : true,
    gray: (
        saturation: 5%,
        hue: blue
    )
);

$palettes: (
    primary: (
        lighten: #e8f2c7,
        darken: #4c5d15
    ),
    secondary: (
        lighten: #f5f3e6,
        darken: #2a2925
    )
);

# $colors - Цвета темы

Обязательный* параметр темы.

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

# Значением цвета может быть:

TIP

Относительное значение - термин который используется при конфигурации темы и обозначает то, что значение для данной переменной, может быть задано в виде SASS списка из двух значений, где первое значение применяется для темы по умолчанию, а второе в режиме инверсии темы!

TIP

Для того, чтобы контролировать цвет инверсионной темы, значение цвета указывается с помощью относительного значения, кроме того, назначение цвета в подобном формате для text-color и background-color является обязательным требованием!

$colors: (
    text-color: (#000, #FFF),
    background-color: (#FFF, #000)
    ...
)

Подробнее об инверсии тем.

Валидация допустимых цветов контролируется с помощью фреймворка (основные цвета) и переменной $available-theme-colors (доп. цвета) из конфигурационного файла самого проекта:

// из un-meta модуля, функция проверки цветов тем
@function get-all-available-сolors() {
    $available-colors: config.$available-theme-colors;
    $required-colors: (primary, secondary, system, info, danger, success, warning, text-color, background-color);
    @each $color-name in $required-colors {
        @if not list.index($available-colors, $color-name) {
            $available-colors: list.append($available-colors, $color-name, $separator: comma);
        }
    }
    @return $available-colors;
}

// source/project/config.scss

// Допустимые имена цвета для тем
$available-theme-colors: (
	secondary,
	extra
);

Обязательные цвета должны быть определены для следующих имен:

  • primary
  • secondary
  • system
  • info
  • danger
  • success
  • warning
  • text-color
  • background-color

Опциональные:

  • extra

TIP

Если extra цвет указан в конфигурации проекта как доступный цвет, но отсутствует в самой теме, при этом присутствуют primary и secondary, то extra назначается автоматически методом смешивания цветов: color.mix($primary, $secondary)

TIP

Для упрощенного понимания и написания данного руководства, будем называть цвета в соответствии с их именами (цвет primary или цвет danger).

Обратите внимание!

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

# $config - Конфигурация темы

Обязательный* параметр темы.

Конфигурация для ungic.theme модуля.

$config: (
    // Конфигурация для методов работы с цветом.
    brightness: (
        // Используются theme.brighten / theme.dim методами
        // отступ в оттенка цвета (hue) в цветовой модели hsl, от процента
        // осветления или затемнения цвета.
        // Может быть числом положительным или отрицательным.
        // ! поддерживается относительное значение*
        offset-brighten: 20,
        offset-dim: 20,

        // Используются theme.brighten / theme.dim методами
        // сдвиг saturation цвета с помощью sass color.scale метода.
        // ! поддерживается относительное значение*
        saturation-brighten: (0, 0),
        saturation-dim: (0, 0)
    ),

    // Сохранение баланса света при манипулировании цветом.
    // Свет цвета не выходит за рамки самого светлого
    // или самого темного цвета темы.
    relative-light-limit : true,

    // Конфигурация серого цвета
    gray: (
        // Оттенок цвета
        // Значение должно быть цветом,
        // ! поддерживается относительное значение*
        hue: blue,

        // Сила насыщенности оттенка цвета от 0 до 100%
        // ! поддерживается относительное значение*
        saturation: 5%
    )
);

Ссылки по теме:

# $palettes - Палитры

Опциональный параметр темы.

Палитра оттенков для цветов темы.

Модуль ungic.theme имеет такие методы как color и gray, с помощью которых можно получить ни только цвет темы, но и их оттенки:

@use "ungic.theme" as *;
@debug color(primary); // Вернет цвет primary
@debug gray(); // Вернет серый вычисленный между цветом текста и фона темы.

// Оттенки

// Осветлить или затемнить на 10% относительно
// самого светлого / темного цвета темы с hue отступом
// в HSL цветовой модели
// в случае светлой темы - осветляет, в случае темной - затемняет
@debug color(primary, .1);

// Сдвигает серый цвет на 90%
// в светлую или темную сторону (зависит от типа темы)
@debug gray(.9);

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

Обратите внимание

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

Палитра задается исключительно для доступных цветов тем:

$colors: (
    primary: #722fcd,
    text-color: (#212121, #f4f4f4),
    ...
);

$palettes: (
    primary: (
        lighten: #dac5f7,
        darken: #1e093b
    ),
    gray: (
        lighten: #fafafa
    )
);

Использование палитры выглядит следующим образом:

@use "ungic.theme" as *;

// Вместо числа передаем имя оттенка палитры
@debug color(primary, lighten);

// Действует и для серого
@debug color(gray, lighten);
// или
@debug gray(lighten);

# Использование палитры со значением по умолчанию.

Для использования палитры со значением по умолчанию, оттенок передается в виде SASS списка:

@use "ungic.theme" as *;

// В случае если нет оттенка в палитре
// будет применен оттенок путем вычисления света
@debug color(gray, (darken, -.9));

# Палитра относительно типа темы

Палитры не поддерживают относительное значение*, управление оттенком цвета относительно типа темы осуществляется вручную с помощью методов таких как:

@use "ungic.theme" as theme;

@debug theme.color(gray, theme.subs(lighten, darken));

// Со значением по умолчанию
@debug theme.color(gray, (theme.subs(lighten, darken), .9));

// или
@include theme.is-type(light) {
    // любые правила для светлой темы
}

@include theme.is-type(dark) {
    // любые правила для темной темы
}

// или
@include theme.is-light {
    // любые правила для светлой темы
}

@include theme.is-dark {
    // любые правила для темной темы
}

// или
$theme-type: theme.get(theme-type);

@if $theme-type == light {
    //...
}
@if $theme-type == dark {
    //...
}

Также, могут быть полезны следующие методы при работе с темами:

Ссылки по теме:

# Ограничения

Назначать цвет с помощью методов ungic-theme модуля, можно только для тех правил, которые содержат селектор, а значит имеются ограничения для использования в следующих случаях:

  • При создании анимации в keyframes
  • В css переменных
@use "ungic.theme" as *;

@keyframes test {
    to {
        // Цвет не будет меняться для каждой темы или для инверсии
        color: color(primary);
    }
}
.test {
     // Будет работать должным образом, 
     // будет меняться цвет текста относительно темы и инверсии.
    color: color(text-color);
    animation: test 2s infinite alternate; 
}

Для того, чтобы обойти данное ограничение следует воспользоваться специальными методами, которые будут возвращать цвет в виде css переменных:

@use "ungic.theme" as *;

@keyframes test {
    to {
        // color-var метод вернет значение цвета в виде CSS переменной и это будет работать должным образом.
        color: color-var(primary);
    }
}
.test {
     // Будет работать должным образом, 
     // будет меняться цвет текста относительно темы и инверсии.
    color: color(text-color);
    animation: test 2s infinite alternate; 
}

# CSS Переменные при стилизации new

Как говорилось ранее, все стили для тем и их инверсий будут сгенерированы путем фильтрации свойств (останутся только те, что отвечают за цвета) и добавления к селектору префикса темы или инверсии:

// Пример первого подхода методом использования замены цветов:
@use "ungic.theme" as *;
.ara {
    // primary = #2e9cb8
    color: color(primary, .5);
    display: block;
}
.gena {
    color: color(primary, .5);
}

// CSS результат при инверсии
.ara {
    color: #8fc4e3;
    display: block;
}
.gena {
    color: #8fc4e3;
}
.un-inverse .ara {
    color: #2c5167;
    // display: block; удалится 
}
.un-inverse .gena {
    color: #2c5167;
}

# Ограничения и недостатки данного подхода

  • Не подходит для использования в css переменных и @keyframes
  • Сгенерированный CSS файл будет больше весом, чем при использовании переменных.

# Преимущества

  • Поддержка всеми браузерами
  • Легкое и удобное манипулирование цветами с помощью нативных SASS методов

# Альтернативный подход, использовать CSS переменные

// Пример первого подхода методом использования замены цветов:
@use "ungic.theme" as *;
.ara {
    color: color-var(primary, .5);
    display: block;
}
.gena {
    color: color-var(primary, .5);
}

// CSS результат
:root {
    --uc-primary-005t: #8fc4e3;
}
.un-inverse {
    --uc-primary-005t: #2c5167;
}
.ara  {
    color: var(--uc-primary-005t);
    display: block;
}
.gena {
    color: var(--uc-primary-005t);
}

# Преимущества использования переменных:

  • Избежание раздутия конечных CSS файлов (размер файла будет значительно меньше, особенно при генераций множества тем и их инверсий)
  • Избежание наложения селекторов (более чистый и лаконичный подход)
  • Использование в любом месте включая @keyframes

# Недостатки использования переменных:

  • Технология относительно новая и поддерживается только модернизированными браузерами
  • Манипулировать цветами с помощью нативных методов SASS станет невозможным!

# Методы для работы с переменными:

color-var, gray-var методы принимают такие же параметры как и color, gray методы, но возвращают значение в виде переменной в var функции:

@use "ungic.theme" as *;

@debug color-var(primary); // var(--uc-primary);
@debug gray-var(.1);  // var(--uc-gray-001t)

Данные методы возвращают значения в виде переменных вместо цвета.

Так как, манипуляция цветами с помощью SASS методов станет не доступной, были созданы методы color-rgb и gray-rgb. Данные методы назначают переменной цвет в виде RGB списка, это не обходимо для того, чтобы можно было использовать RGBA метод и манипулировать прозрачностью цвета:

@use "ungic.theme" as *;

.test {
    color: rgba(color-rgb(primary), .2);
}

Однако! color-rgb и gray-rgb методы будут генерировать переменные только в режиме themeColorsVarsMode, в отличии от color-var, gray-var методов, которые постоянно генерируют переменные (в любом режиме фреймворка)

WARNING

color-rgb и gray-rgb методы будут генерировать переменные только в режиме themeColorsVarsMode, в отличии от color-var, gray-var методов, которые постоянно генерируют переменные (в любом режиме фреймворка).

Если themeColorsVarsMode параметр scss фреймворка будет ложным, то color-rgb и gray-rgb методы будут возвращать обычный цвет, который также будет совместим с RGBA функцией.

# themeColorsVarsMode режим или постоянная генерация переменных

Данный режим переключает все методы ungic.theme модуля в режим генерации переменных, это означает, что использование таких методов как color() или gray()* будет равноправным что и color-var() и gray-var(). То есть, включение данного режима принудительно переключает все методы на генерацию переменных! Данный параметр конфигурируется в секции scss плагина.

WARNING

При использовании themeColorsVarsMode режима (themeColorsVarsMode: true), все значения цветов возвращаемые методами color и gray будут переменными, а не цветом!

TIP

При включении themeColorsVarsMode режима, для правил, которые имеют св-ва со значением произвольного цвета будут как и прежде созданы собственные селектора:

// Пример первого подхода методом использования замены цветов:
@use "ungic.theme" as *;
.ara {
    color: color(primary, .5);
}
.gena {
    color: subs(white, dark);
}

// CSS результат
:root {
    --uc-primary-005t: #8fc4e3;
}
.un-inverse {
    --uc-primary-005t: #2c5167;
}
.ara  {
    color: var(--uc-primary-005t);
}
.gena {
    color: white
}
.un-inverse .gena {
    color: dark
}

# generateThemeColorsVars параметр

  • generateThemeColorsVars Boolean, Default: false

Данный параметр находится в секции конфигурации sass фреймворка. При активации данного параметра, будут сгенерированы переменные для всех цветов тем (не включая оттенки).

# Совместное использования обеих методов генерации цветов (тем).

Оба выше перечисленных метода могут работать совместно, что дает полный контроль автору при написании стилей. В случае, если автор предпочитает сделать базовым подходом - использование переменных, рекомендуется включить themeColorsVarsMode режим в настройках sass фреймворка. Данный режим переключит все методы работать на основе переменных.