@rotcetihra/c2c
v1.0.2
Published
Атомарный CSS-компилятор на Sass, работающий на основе конфигурационных файлов по принципу AOT.
Maintainers
Readme
C2C — Config-to-CSS Compiler
C2C (Config-to-CSS) — это декларативный AOT (Ahead-Of-Time) компилятор и движок генерации атомарных CSS-утилит, написанный на современном Dart Sass.
Проект вдохновлен философией Tailwind CSS, но переносит логику сборки дизайн-системы непосредственно
на уровень препроцессора. Вместо написания шаблонного CSS-кода вручную, вы описываете структуру
вашей дизайн-системы в виде Sass-карт (Maps), а движок автоматически разворачивает их в
структурированные атомарные классы, включая адаптивные брейкпоинты, интерактивные состояния и их
пересечения.
🚀 Главные особенности
- Декларативность: Полное разделение данных (вашей конфигурации) и логики рендеринга.
- Продвинутый полиморфизм: Генераторы компилятора автоматически адаптируются под тип переданных данных (обработка плоских строк, списков и комплексных карт-шаблонов).
- Комбинаторика вариантов: Автоматическая генерация модификаторов состояний (
h:,f:,a:) и адаптивных медиа-запросов (md:,lg:) для любого модуля одной строчкой в конфиге. - Строгая валидация: Встроенная система контроля типов и обязательных полей верхнего и вложенного уровней — понятные сообщения об ошибках в консоли компилятора при сборке.
- Готов к Production: Спроектирован с учетом обязательной фильтрации через PurgeCSS / PostCSS, что позволяет генерировать любые объемы утилит на этапе разработки без раздувания финального бандла.
💡 Обратите внимание: Это статический AOT-компилятор (генерация до сборки), а не JIT-движок. Он компилирует конфигурационные матрицы в статический CSS-файл, из которого сборщик затем вычищает неиспользуемые классы.
📦 Установка
Вы можете установить компилятор C2C как стандартную dev-зависимость через ваш любимый пакетный менеджер.
# Через npm
npm install -D @rotcetihra/c2c
# Через yarn
yarn add -D @rotcetihra/c2c
# Через pnpm
pnpm add -D @rotcetihra/c2c🔌 Базовое подключение
Чтобы начать работу, достаточно импортировать компилятор в ваш главный файл стилей и передать
конфигурационную карту в метод-оркестратор. Благодаря встроенной системе модулей Dart Sass (@use),
все внутренние механизмы компилятора доступны через единую точку входа.
// main.scss проекта
@use "pkg:@rotcetihra/c2c" as c2c;
// 1. Описываем конфигурацию вашего модуля
$display-config: (
// Имя модуля (Используется для отладки).
"name": "layout",
// Блок с описанием утилит по их свойствам.
"properties": (
(
"use": (
// Сгенерировать точки останова (`sm:`, `md:`, `lg:` и др.).
"breakpoints": true,
// Сгенерировать только перечисленные состояния.
"states": (
"h",
// :hover
"f",
// :focus
"a" // :active
),
),
"values": (
// Свойство, на основе которого будут генерироваться утилиты.
"display": (
// "Имя утилиты": "Значение утилиты"
"block": "block",
"inline": "inline",
"flex": "flex",
"hidden": "none"
),
),
)
)
);
// 2. Запускаем компиляцию
@include c2c.by($display-config);📌 Примечание к импорту: Префикс
pkg:поддерживается современным Dart Sass и большинством популярных сборщиков (Vite, Webpack сsass-loader, Rspack). Если ваш сборщик использует устаревшие настройки разрешения путей, импорт может выглядеть как@use "~c2c" as c2c;или требовать прямого указания пути кnode_modules.
📐 Архитектура конфигурации (Configuration Matrix)
В основе C2C лежит концепция конфигурационной матрицы модуля. Каждый модуль (например,
display, spacing, colors) описывается в виде единой многомерной карты Sass (Map).
Движок устроен ортогонально: свойства отображения (брейкпоинты, ховеры) отделены от самих генерируемых данных. Вы можете комбинировать разные типы генераторов внутри одной конфигурации.
Полный каркас конфигурации модуля
Ниже представлена полная структура карты, которую принимает оркестратор c2c.by(). Каждая секция
является опциональной и запускает соответствующий метод компиляции:
$module-config: (
// 1. Идентификатор модуля
"name": "module-name",
// 2. Статические утилиты (Один класс = Одно свойство = Одно значение)
"properties": (/* ... */),
// 3. Динамические числовые диапазоны
"steps": (/* ... */),
// 4. Дробные и сеточные утилиты
"fractions": (/* ... */),
// 5. Цветовые утилиты
"palettes": (/* ... */),
// 6. Комплексные составные классы (Один класс = Пачка CSS-свойств)
"classes": (/* ... */),
// 7. Глобальные именованные CSS-блоки (На данный момент поддерживается только @keyframes)
"blocks": (/* ... */)
);Общая анатомия внутренних блоков
Каждый генератор (properties, steps и т.д.) внутри конфигурации ожидает карту, состоящую из двух
ключевых частей:
"use"(Настройки вариантов): Управляет генерацией модификаторов. Здесь вы указываете, нужно ли генерировать для этого конкретного блока адаптивные брейкпоинты ("breakpoints": true) или интерактивные состояния ("states": ("h", "f"))."values"(Данные для компиляции): Карта, структура которой специфична для каждого конкретного метода (строки, списки или вложенные карты).
Абстрактный пример структуры генератора:
"properties":(("use":("breakpoints":true,"states": ("h"),
),
"values": (
// Данные, которые будут прогнаны через циклы модификаторов
)
)
);Такой подход позволяет гибко настраивать генерацию кода: например, для модуля display вам могут
быть жизненно необходимы брейкпоинты (md:block), но абсолютно не нужны ховеры, в то время как для
модуля palettes (цветовых схем) вам понадобятся и брейкпоинты, и ховеры одновременно.
🛠 Руководство по методам компиляции
В этом разделе подробно описаны все доступные миксины-генераторы компилятора C2C. Каждый метод спроектирован как изолированный математический движок, который принимает очищенные данные из вашей конфигурации и разворачивает их в валидный CSS-код.
🧩 Главный принцип: Полиморфизм данных
Ключевая особенность компилятора C2C — его «всеядность» и гибкость к типам данных во входных
параметрах (values). Движок под капотом использует инспекцию типов (мета-проверки на строки,
списки и карты).
Это означает, что один и тот же метод компиляции может вести себя абсолютно по-разному в зависимости от того, как вы описали целевое CSS-свойство:
- Плоская строка (
String): Запускает классический атомарный рендеринг (одно свойство = одно динамическое значение). - Список (
List): Позволяет генерировать комбинированные классы, где одно динамическое значение одновременно присваивается массиву свойств (например,inset-xсразу дляleftиright). - Карта-шаблон (
Map): Включает продвинутый режим шаблонизации. Движок ищет внутри строки-значения специальный знак плейсхолдера (*) и подставляет вычисленный шаг или цвет прямо внутрь сложных CSS-функций (например,rgba(*, var(--opacity))илиtranslateX(*)).
Ниже приведены подробные спецификации для каждого метода компиляции с примерами входных конфигураций
(Map) и результатом их компиляции в CSS-код.
4.1. Оркестратор by($config)
Миксин by() является главной входной точкой (оркестратором) конвейера C2C. Он инкапсулирует
логику верхнего уровня: принимает сырую конфигурационную карту модуля, проверяет её целостность,
извлекает метаданные (имя модуля, глобальные флаги) и автоматически распределяет блоки данных по
соответствующим генераторам нижнего уровня с помощью динамического вызова миксинов
(meta.get-mixin).
Вам не нужно вручную вызывать properties, steps или palettes — оркестратор сделает это сам на
основе ключей вашей конфигурации.
📝 Пример конфигурации модуля
Передаем карту модуля в миксин c2c.by(). В данном примере мы объединяем статические свойства и
динамические шаги в рамках одного модуля spacing:
@use "pkg:@rotcetihra/c2c" as c2c;
$spacing-module: (
"name": "spacing",
// Статический блок (вызовет метод properties)
"properties": (
(
"use": (
"breakpoints": true,
),
"values": (
"box-sizing": (
"box-border": "border-box",
"box-content": "content-box",
),
),
),
),
// Динамический блок (вызовет метод steps)
"steps": (
(
"use": (
"breakpoints": true,
),
"meta": (
"from": 0,
"to": 2,
"step": 1,
"unit": "rem",
),
"values": (
"p": "padding",
),
),
),
);
// Запуск глобального конвейера сборки модуля
@include c2c.by($spacing-module);📄 Результат компиляции в CSS
Оркестратор самостоятельно распознал типы блоков, прогнал их через внутренний цикл брейкпоинтов (для
тех блоков, где был флаг breakpoints: true) и сгенерировал плоский CSS-код:
/* Базовые статические утилиты */
.box-border {
box-sizing: border-box;
}
.box-content {
box-sizing: content-box;
}
/* Базовые динамические шаги */
.p-0 {
padding: 0rem;
}
.p-1 {
padding: 1rem;
}
.p-2 {
padding: 2rem;
}
/* Адаптивные модификаторы (внутри медиа-запросов) */
@media (min-width: 768px) {
.md\:box-border {
box-sizing: border-box;
}
.md\:box-content {
box-sizing: content-box;
}
.md\:p-0 {
padding: 0rem;
}
.md\:p-1 {
padding: 1rem;
}
.md\:p-2 {
padding: 2rem;
}
}4.2. Метод properties (Статические утилиты)
Метод properties предназначен для generation традиционных статических утилит, где имя класса,
целевое CSS-свойство и его значение жестко зафиксированы в конфигурации. Этот генератор идеально
подходит для таких модулей, как display, position, overflow, text-align, font-weight и
других нечисловых CSS-свойств.
Генератор ожидает строгую двумерную карту (2D Map) в ключе values, которая раскладывается по
следующему принципу: CSS-Свойство -> ( Желаемый CSS-Класс: Итоговое CSS-Значение )
📝 Пример конфигурации модуля
В данном примере настраивается генерация утилит для управления позиционированием и отображением элементов с поддержкой адаптивных брейкпоинтов и ховер-состояний:
@use "pkg:@rotcetihra/c2c" as c2c;
$layout-module: (
"name": "layout",
"properties": (
(
// Настройки вариантов (модификаторов)
"use": (
"breakpoints": true,
"states": (
"h",
),
),
// Матрица статических значений
"values": (
"position": (
"absolute": "absolute",
"relative": "relative",
"fixed": "fixed",
),
"pointer-events": (
"click-allow": "auto",
"click-none": "none",
),
)
),
),
);
@include c2c.by($layout-module);📄 Результат компиляции в CSS
Благодаря встроенной в метод безопасной интерполяции строк, пустые модификаторы контекста бесследно исчезают в базовых классах, но автоматически разворачиваются при генерации вариантов:
/* Базовые утилиты */
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.fixed {
position: fixed;
}
.click-allow {
pointer-events: auto;
}
.click-none {
pointer-events: none;
}
/* Модификаторы состояний (Глобальные) */
.h\:absolute:hover {
position: absolute;
}
.h\:relative:hover {
position: relative;
}
.h\:fixed:hover {
position: fixed;
}
.h\:click-allow:hover {
pointer-events: auto;
}
.h\:click-none:hover {
pointer-events: none;
}
/* Адаптивные модификаторы (внутри медиа-запросов) */
@media (min-width: 768px) {
.md\:absolute {
position: absolute;
}
.md\:relative {
position: relative;
}
.md\:fixed {
position: fixed;
}
.md\:click-allow {
pointer-events: auto;
}
.md\:click-none {
pointer-events: none;
}
/* Адаптивные модификаторы состояний */
.md\:h\:absolute:hover {
position: absolute;
}
.md\:h\:relative:hover {
position: relative;
}
.md\:h\:fixed:hover {
position: fixed;
}
.md\:h\:click-allow:hover {
pointer-events: auto;
}
.md\:h\:click-none:hover {
pointer-events: none;
}
}4.3. Метод steps (Динамические числовые диапазоны)
Метод steps — это мощный математический генератор, который избавляет от ручного описания
однотипных числовых классов (отступы, размеры, углы поворота, индексы слоев). Вместо перечисления
каждого значения, вы задаете диапазон и шаг в блоке "meta", а движок сам рассчитывает итерации
цикла.
Генератор ожидает обязательную карту конфигурации "meta" со следующими ключами:
from(Number) — стартовое значение диапазона.to(Number) — конечное значение диапазона.step(Number) — шаг инкремента.unit(String | Null) — единица измерения (например,px,rem,%,degилиnullдля безразмерных величин).
🧩 Три режима работы (Полиморфизм данных)
В ключе values метод принимает три типа данных, полностью меняющих логику вывода:
- Строка (
String): Классическое одиночное свойство. Пара"w": "width"развернется в.w-0,.w-1и т.д. - Список (
List): Группировка свойств. Пара"mx": ("margin-left", "margin-right")создаст утилиту, управляющую сразу обоими свойствами. - Карта (
Map): Продвинутая шаблонизация. Позволяет оборачивать вычисленное число в сложные CSS-функции. Знак плейсхолдера*внутри строки указывает движку, куда именно нужно подставить вычисленное значение с единицей измерения.
📝 Пример конфигурации модуля
В данном примере мы настраиваем комплексный модуль dimensions, используя все три режима
полиморфизма:
@use "pkg:@rotcetihra/c2c" as c2c;
$steps-module: (
"name": "dimensions",
"steps": (
(
"use": (
"breakpoints": true,
),
// Описание математического диапазона
"meta": (
"from": 0,
"to": 10,
"step": 5,
"unit": "px",
),
// Матрица полиморфных значений
"values": (
// 1. Строка: Одиночное свойство
"w": "width",
// 2. Список: Группа свойств (осевой отступ)
"my": ("margin-top", "margin-bottom"),
// 3. Карта: Шаблонизация CSS-переменной с плейсхолдером *
"translate-y": (
"--tw-translate-y": "translateY(*)",
),
),
),
),
);
@include c2c.by($steps-module);📄 Результат компиляции в CSS
Движок проитерировал диапазон от 0 до 10 с шагом 5 (получилось три шага: 0, 5, 10), применил единицу
измерения px, корректно обработал списки и подставил значение внутрь функции translateY() вместо
знака *:
/* --- Шаг 0 (0px) --- */
.w-0 {
width: 0px;
}
.my-0 {
margin-top: 0px;
margin-bottom: 0px;
}
.translate-y-0 {
--tw-translate-y: translateY(0px);
}
/* --- Шаг 5 (5px) --- */
.w-5 {
width: 5px;
}
.my-5 {
margin-top: 5px;
margin-bottom: 5px;
}
.translate-y-5 {
--tw-translate-y: translateY(5px);
}
/* --- Шаг 10 (10px) --- */
.w-10 {
width: 10px;
}
.my-10 {
margin-top: 10px;
margin-bottom: 10px;
}
.translate-y-10 {
--tw-translate-y: translateY(10px);
}
/* Адаптивные модификаторы (внутри медиа-запросов) */
@media (min-width: 768px) {
.md\:w-0 {
width: 0px;
}
.md\:my-0 {
margin-top: 0px;
margin-bottom: 0px;
}
.md\:translate-y-0 {
--tw-translate-y: translateY(0px);
}
.md\:w-5 {
width: 5px;
}
.md\:my-5 {
margin-top: 5px;
margin-bottom: 5px;
}
.md\:translate-y-5 {
--tw-translate-y: translateY(5px);
}
.md\:w-10 {
width: 10px;
}
.md\:my-10 {
margin-top: 10px;
margin-bottom: 10px;
}
.md\:translate-y-10 {
--tw-translate-y: translateY(10px);
}
}4.4. Метод fractions (Дроби и Сетки)
Метод fractions — специализированный генератор для создания пропорциональных и сеточных утилит
(например, адаптивных сеток в стиле cols-1/3, w-2/5). Он автоматически рассчитывает дроби во
вложенных циклах @while, генерирует правильные имена классов с экранированием слэша (\/) и умеет
работать в двух принципиально разных режимах калькуляции.
Для управления диапазонами и логикой генерации блок "meta" принимает следующие обязательные
параметры:
from(Number) — стартовая точка для числителя и знаменателя (обычно0или1).to(Number) — максимальный предел разрешения сетки или знаменателя (например,4для четвертей или12для стандартной двенадцатиколоночной сетки).unit(String | Null) — единица измерения для вычисляемых значений (например,%илиvh).divide(Boolean) — Главный переключатель режима:true(Режим процентов): Движок делит числитель на знаменатель и умножает на 100 ((1 / 2) * 100 = 50%). Идеально дляwidth,height,flex-basis.false(Режим разделителя/сеток): Движок не считает математику, а выводит числитель и знаменатель через пробел со слэшем (1 / 2). Идеально для CSS Grid утилит вродеgrid-column-start.incorrect(Boolean) — разрешить генерацию неправильных дробей, где числитель больше знаменателя или равен ему (например,w-4/3илиw-2/2). При значенииfalseгенерируются строго правильные дроби (числитель всегда меньше знаменателя).negative(Boolean) — инвертировать вычисленное процентное значение в отрицательное (умножает результат на-1). Используется для утилит отрицательных сдвигов.
📝 Пример конфигурации модуля
В данном примере мы объявляем два разных блока в рамках одного модуля: один для процентной ширины (с математическим делением от 1 до 3), второй — для позиционирования в CSS Grid (без деления):
@use "pkg:@rotcetihra/c2c" as c2c;
$grid-module: (
"name": "grid-system",
"fractions": (
(
"use": (
"breakpoints": true,
),
"meta": (
"from": 1,
"to": 3,
"unit": "%",
"divide": true,
// Включаем деление в проценты
"incorrect": false,
// Запрещаем дроби вроде 2/2 или 3/2
"negative": false,
),
"values": (
"w": "width",
),
),
(
"use": (
"breakpoints": true,
),
"meta": (
"from": 1,
"to": 2,
"unit": null,
"divide": false,
// Отключаем деление, выводим строку "1 / 2"
"incorrect": true,
// Разрешаем неправильные дроби (2/1 и т.д.)
"negative": false,
),
"values": (
"col-start": "grid-column-start",
),
),
),
);
@include c2c.by($grid-module);📄 Результат компиляции в CSS
Обратите внимание, как движок автоматически экранирует символ слэша \/ в именах классов, как
отрабатывают вложенные циклы и как меняется CSS-значение в зависимости от флага divide:
/* --- Блок 1: Процентная ширина (divide: true, incorrect: false) --- */
.w-1\/2 {
width: 50%;
}
.w-1\/3 {
width: 33.3333333%;
}
.w-2\/3 {
width: 66.6666666%;
}
/* Классы вроде .w-1/1 или .w-2/2 не создаются, так как числитель строго меньше знаменателя */
/* --- Блок 2: Сеточное позиционирование (divide: false, incorrect: true) --- */
.col-start-1\/1 {
grid-column-start: 1 / 1;
}
.col-start-2\/1 {
grid-column-start: 2 / 1;
} /* Сгенерировано благодаря incorrect: true */
.col-start-1\/2 {
grid-column-start: 1 / 2;
}
.col-start-2\/2 {
grid-column-start: 2 / 2;
}
/* Адаптивные модификаторы (внутри медиа-запросов) */
@media (min-width: 768px) {
.md\:w-1\/2 {
width: 50%;
}
.md\:w-1\/3 {
width: 33.3333333%;
}
.md\:w-2\/3 {
width: 66.6666666%;
}
.md\:col-start-1\/1 {
grid-column-start: 1 / 1;
}
.md\:col-start-2\/1 {
grid-column-start: 2 / 1;
}
.md\:col-start-1\/2 {
grid-column-start: 1 / 2;
}
.md\:col-start-2\/2 {
grid-column-start: 2 / 2;
}
}4.5. Метод palettes (Цветовые схемы)
Метод palettes — это специализированный генератор для массового создания цветовых утилит (текст,
фоны, границы, заливка SVG). Он автоматически берет встроенную в компилятор палитру цветов и
прогоняет её через переданные вами префиксы классов.
Вшитая палитра компилятора включает два типа структуры цветов, которые генерируют разные виды классов:
- Цвета со шкалой оттенков: Для цветов с цифровыми индексами яркости (например,
blue-500) метод генерирует трехсоставный класс (например,.bg-blue-500). - Одиночные цвета: Для базовых цветов без оттенков (например,
white) метод генерирует лаконичный двухсоставный класс без лишних дефисов (.bg-white).
📝 Пример конфигурации модуля
Каждая группа настроек оформляется в виде карты, которая передается внутри списка (List) конфигураций конкретного метода. Вы лишь указываете префикс класса и целевое CSS-свойство:
@use "pkg:@rotcetihra/c2c" as c2c;
$colors-module: (
"name": "design-colors",
// Передаем список конфигураций для метода palettes
"palettes": (
// Первая конфигурационная карта: фоны с поддержкой ховеров
(
"use": (
"breakpoints": true,
"states": (
"h",
),
),
"values": (
"bg": "background-color",
),
),
// Вторая конфигурационная карта: цвет текста (без ховеров)
(
"use": (
"breakpoints": true,
"states": false,
),
"values": (
"text": "color",
),
),
),
);
@include c2c.by($colors-module);📄 Результат компиляции в CSS
Компилятор берет встроенные цвета и разворачивает их для каждого префикса из вашего списка конфигураций с учетом заданных вариантов:
/* --- Базовые цветовые утилиты (Фоны и Текст) --- */
.bg-white {
background-color: #ffffff;
}
.bg-blue-500 {
background-color: #3b82f6;
}
.text-white {
color: #ffffff;
}
.text-blue-500 {
color: #3b82f6;
}
/* --- Модификаторы состояний (Только для первой карты, где были разрешены states) --- */
.h\:bg-white:hover {
background-color: #ffffff;
}
.h\:bg-blue-500:hover {
background-color: #3b82f6;
}
/* --- Адаптивные модификаторы (внутри медиа-запросов) --- */
@media (min-width: 768px) {
.md\:bg-white {
background-color: #ffffff;
}
.md\:bg-blue-500 {
background-color: #3b82f6;
}
.md\:text-white {
color: #ffffff;
}
.md\:text-blue-500 {
color: #3b82f6;
}
/* Адаптивные ховеры для фонов */
.md\:h\:bg-white:hover {
background-color: #ffffff;
}
.md\:h\:bg-blue-500:hover {
background-color: #3b82f6;
}
}4.6. Метод classes (Составные утилиты)
Метод classes предназначен для генерации комплексных составных утилит. В отличие от метода
properties, где структура данных строится от свойства к классу, здесь логика инвертирована:
Желаемый CSS-Класс -> ( Карта статических CSS-Свойств и их Значений )
Этот генератор идеально подходит для создания утилит, которые должны применять сразу несколько
CSS-правил к одному селектору (например, утилиты центрирования, сброса обтекания clearfix,
создания красивых эффектов или фиксированных кастомных компонентов).
📝 Пример конфигурации модуля
Каждая конфигурация оформляется в виде карты внутри общего списка (List) метода classes. В
данном примере настраивается генерация утилит для центрирования контента и создания эффекта скрытия
элементов с поддержкой адаптивных модификаторов:
@use "pkg:@rotcetihra/c2c" as c2c;
$effects-module: (
"name": "custom-utilities",
// Передаем список конфигураций для метода classes
"classes": (
(
// Настройки вариантов (модификаторов)
"use": (
"breakpoints": true,
"states": (
"h",
),
),
// Матрица составных классов
"values": (
// Утилита для центрирования флекс-контента
"flex-center": (
"display": "flex",
"align-items": "center",
"justify-content": "center",
),
// Утилита для создания "невидимого", но доступного элемента
"sr-only": (
"position": "absolute",
"width": "1px",
"height": "1px",
"padding": "0",
"margin": "-1px",
"overflow": "hidden",
"clip": "rect(0, 0, 0, 0)",
"border-width": "0",
)
)
),
),
);
@include c2c.by($effects-module);📄 Результат компиляции в CSS
Компилятор разворачивает имя класса, генерирует для него все указанные внутри свойства как единый блок и накатывает модификаторы брейкпоинтов и состояний:
/* --- Базовые составные утилиты --- */
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border-width: 0;
}
/* --- Модификаторы состояний --- */
.h\:flex-center:hover {
display: flex;
align-items: center;
justify-content: center;
}
.h\:sr-only:hover {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border-width: 0;
}
/* --- Адаптивные модификаторы (внутри медиа-запросов) --- */
@media (min-width: 768px) {
.md\:flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.md\:sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border-width: 0;
}
/* Адаптивные модификаторы состояний */
.md\:h\:flex-center:hover {
display: flex;
align-items: center;
justify-content: center;
}
.md\:h\:sr-only:hover {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border-width: 0;
}
}4.7. Метод blocks (Глобальные CSS-директивы)
Метод blocks предназначен для генерации сложных именованных CSS-конструкций и глобальных директив,
которые выходят за рамки обычных классов.
⚠️ Важное ограничение: На текущий момент компилятор поддерживает генерацию только одного типа блоков — анимационных циклов
keyframes. Поддержка других глобальных директив будет добавлена в будущих релизах.
Поскольку анимации являются глобальными правилами автоматизации интерфейса, этот метод генерирует
чистые CSS-блоки @keyframes без привязки к адаптивным брейкпоинтам или интерактивным состояниям
(параметр "use" здесь игнорируется или опускается).
Структура данных внутри values строится по следующему многомерному принципу:
Имя анимации -> ( Шаг таймлайна/Ключевой кадр -> ( CSS-Свойства и их Значения ) )
📝 Пример конфигурации модуля
Конфигурационная карта передается внутри общего списка (List) метода blocks. В данном примере
мы описываем параметры для создания двух стандартных анимаций интерфейса: плавного появления
(fade-in) и бесконечного вращения (spin):
@use "pkg:@rotcetihra/c2c" as c2c;
$animations-module: (
"name": "global-animations",
// Передаем список конфигураций для метода blocks
"blocks": (
(
// Указываем тип блока, который мы конфигурируем
"type": "keyframes",
// Матрица ключевых кадров анимаций
"values": (
// Анимация 1: Плавное проявление
"fade-in": (
"from": (
"opacity": "0",
),
"to": (
"opacity": "1",
),
),
// Анимация 2: Цикличное вращение лоадера
"spin": (
"0%": (
"transform": "rotate(0deg)",
),
"100%": (
"transform": "rotate(360deg)",
),
)
)
),
),
);
@include c2c.by($animations-module);📄 Результат компиляции в CSS
Компилятор обрабатывает переданную многомерную карту, изолирует каждый шаг таймлайна и разворачивает
валидные директивы @keyframes, которые затем можно использовать в стандартных свойствах
animation вашего проекта:
/* --- Глобальные блоки анимаций CSS --- */
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}5. Управление вариантами: Модификаторы (use)
Одной из самых мощных возможностей компилятора C2C является система автоматической генерации
вариантов (модификаторов) для базовых классов. Вместо того чтобы вручную дублировать конфигурации
для адаптивной верстки или интерактивных состояний, вы управляете этим с помощью декларативного
блока "use", который присутствует в каждой конфигурационной карте.
Блок "use" принимает следующие параметры:
breakpoints(Boolean) — включать ли генерацию адаптивных префиксов. Если установлено вtrue, компилятор автоматически обернет утилиты в медиа-запросы и добавит префиксы видаsm:,md:,lg:к именам классов.states(Boolean | List) — флаг или список целевых псевдоклассов. Принимает два типа значений:true— автоматически генерирует весь встроенный список состояний компилятора.- Список вида
("h", "f", "a")— генерирует только указанные псевдоклассы (режимonly).
📋 Встроенная карта состояний компилятора
При использовании states: true или точечном выборе сокращений, компилятор опирается на следующий
зашитый набор состояний:
| Сокращение | Псевдокласс | Категория | Описание |
| ----------- | ------------------ | --------------- | ----------------------------------------------------- |
| h | :hover | Интерактивность | Наведение курсора (защищено @media (hover: hover)) |
| f | :focus | Интерактивность | Получение фокуса элементом |
| a | :active | Интерактивность | Состояние в момент нажатия (клик) |
| fw | :focus-within | Доступность | Фокус на самом элементе или любом его потомке |
| fv | :focus-visible | Доступность | Фокус от клавиатуры (скрывает контур при клике мышью) |
| t | :target | Навигация | Элемент, на который ссылается текущий URL (якорь) |
| v | :visited | Навигация | Ссылка, по которой пользователь уже переходил |
| val | :valid | Формы | Поле ввода с корректно заполненными данными |
| inval | :invalid | Формы | Поле ввода с ошибкой валидации |
| req | :required | Формы | Обязательное для заполнения поле ввода |
| dis | :disabled | Формы | Заблокированный элемент (кнопка или инпут) |
| first | :first-child | Структура | Первый дочерний элемент в контейнере |
| last | :last-child | Структура | Последний дочерний элемент в контейнере |
| odd | :nth-child(odd) | Структура | Нечетные элементы (эффект "зебры" в списках/таблицах) |
| even | :nth-child(even) | Структура | Четные элементы |
📝 Пример конфигурации с точечным выбором состояний
Пример оформления блока "use" внутри списка конфигураций для метода properties, где мы
активируем брейкпоинты и выбираем только hover и focus:
@use "pkg:@rotcetihra/c2c" as c2c;
$interactive-module: (
"name": "interactive-components",
"properties": (
(
// Настраиваем генерацию вариантов
"use": (
"breakpoints": true,
"states": (
"h",
"f",
),
// Генерируем ТОЛЬКО hover и focus
),
"values": (
"outline": (
"accent": "2px solid #3b82f6",
"none": "none",
),
)
),
),
);
@include c2c.by($interactive-module);📄 Результат компиляции в CSS
Компилятор подставляет короткое сокращение в качестве префикса класса (например, h\:), а полное
имя псевдокласса — в конец селектора:
/* Базовые утилиты */
.outline-accent {
outline: 2px solid #3b82f6;
}
.outline-none {
outline: none;
}
/* Глобальные модификаторы состояний (точечная выборка) */
.h\:outline-accent:hover {
outline: 2px solid #3b82f6;
}
.h\:outline-none:hover {
outline: none;
}
.f\:outline-accent:focus {
outline: 2px solid #3b82f6;
}
.f\:outline-none:focus {
outline: none;
}
/* Адаптивный слой (внутри медиа-запроса) */
@media (min-width: 768px) {
.md\:outline-accent {
outline: 2px solid #3b82f6;
}
.md\:outline-none {
outline: none;
}
/* Адаптивные состояния */
.md\:h\:outline-accent:hover {
outline: 2px solid #3b82f6;
}
.md\:h\:outline-none:hover {
outline: none;
}
.md\:f\:outline-accent:focus {
outline: 2px solid #3b82f6;
}
.md\:f\:outline-none:focus {
outline: none;
}
}6. Валидация и Логирование ошибок (Error Handling)
Компилятор C2C оснащен строгим изолированным миксином валидации, который проверяет целостность структуры данных перед тем, как запустить конвейер генерации CSS. Если в вашей конфигурации отсутствует обязательный параметр или вложенное подполе, компилятор не станет генерировать сломанный CSS, а мгновенно прервет сборку проекта, выбросив системное исключение с точным указанием места ошибки.
🔍 Карта обязательных полей
Валидатор автоматически проверяет каждую конфигурационную карту внутри списков методов на наличие следующих обязательных ключей:
| Метод компиляции | Обязательные поля верхнего уровня | Обязательные вложенные подполя |
| ---------------- | --------------------------------- | -------------------------------- |
| properties | "values" | Нет |
| classes | "values" | Нет |
| palettes | "values" | Нет |
| blocks | "values" | Нет |
| steps | "meta", "values" | "meta" -> "step", "from", "to" |
| fractions | "meta", "values" | "meta" -> "from", "to" |
Если вы конфигурируете сложный метод (например, steps или fractions), валидатор рекурсивно
спустится в карту "meta" и проверит наличие всех математических границ диапазона.
🚨 Строгая цепочка локализации ошибок
При обнаружении пропущенного поля компилятор вызывает директиву @error, останавливая сборку. Вывод
ошибки стандартизирован и собирает полную цепочку контекста через двойное двоеточие по принципу:
Имя модуля :: Метод (Группа) :: Индекс карты в списке :: Пропущенный параметр
📝 Формат системного исключения:
Error: Отсутствует обязательное поле '[Имя модуля]::[Группа]::[Индекс конфигурации]::[Параметр]'.
Примеры реального вывода ошибок в консоль:
- Если вы забыли указать шаг
stepво второй карте конфигурации методаstepsвнутри модуляspacing:
Error: Отсутствует обязательное поле 'spacing::steps::2::meta::step'.
- Если вы забыли передать блок
valuesв первой карте конфигурации методаpropertiesвнутри модуляdisplay:
Error: Отсутствует обязательное поле 'display::properties::1::values'.
7. Интеграция с PurgeCSS (Production Build)
Поскольку C2C генерирует утилиты динамически на основе конфигурационных матриц, ваш CSS-файл на этапе разработки может весить достаточно много. Для очистки неиспользуемого кода в продакшн-сборке настоятельно рекомендуется использовать PurgeCSS (или встроенные инструменты сборщиков, такие как PostCSS PurgeCSS).
⚠️ Важная особенность экстракции классов
Из-за того, что компилятор C2C активно использует спецсимволы для разделения модификаторов
(двоеточие \: для состояний и брейкпоинтов) и дробей (экранированный слэш \/), стандартные
экстракторы PurgeCSS не смогут распознать эти классы в ваших HTML/JS файлах и полностью удалят их из
финальной сборки.
Чтобы этого не произошло, необходимо настроить кастомный Extractor, который обучит PurgeCSS корректно считывать спецсимволы C2C.
⚙️ Настройка конфигурации (PurgeCSS Config)
Добавьте следующее регулярное выражение в массив defaultExtractor вашего конфигурационного файла
(например, purgecss.config.js или в настройки плагина PostCSS):
module.exports = {
content: [
"./src/**/*.html",
"./src/**/*.js",
"./src/**/*.vue",
"./src/**/*.jsx",
// Укажите пути ко всем вашим шаблонам
],
defaultExtractor: (content) => {
// Регулярное выражение, которое захватывает классы со спецсимволами \: и \/
return content.match(/[A-Za-z0-9_-]+(?::[A-Za-z0-9_-]+)*(?:\/[A-Za-z0-9_-]+)?/g) || [];
},
};💡 Как это работает?
Данное регулярное выражение гарантирует, что PurgeCSS корректно свяжет строковую запись в вашем HTML-шаблоне с селектором в CSS-файле:
- Строка
class="md:hover:bg-blue-500"в HTML будет успешно сопоставлена со сгенерированным селектором.md\:hover\:bg-blue-500. - Строка
class="w-1/2"в HTML свяжется с селектором.w-1\/2.
Без этой настройки ваша адаптивная верстка и дробные сетки сломаются в продакшене, так как PurgeCSS посчитает их неиспользуемыми.
8. Лицензия (License)
Этот проект распространяется под свободной лицензией MIT.
Это означает, что вы можете совершенно бесплатно использовать компилятор C2C как в личных, так как и в коммерческих проектах, изменять код, форкать репозиторий или интегрировать его в свои проприетарные продукты без каких-либо жестких ограничений.
Полный текст лицензии находится в файле LICENSE в корневом каталоге данного репозитория.
Разработано с фокусом на скорость, чистоту кода и гибкость конфигурации. Если у вас возникли вопросы или предложения по улучшению компилятора — создавайте Issues или присылайте Pull Requests! 🚀
