Требования к стилизации
В этом разделе описаны технические требования к конкретным инструментам и общие правила написания стилей.
Tailwind CSS
MUST
- Конфигурация использует дизайн-токены:
module.exports = {
theme: {
extend: {
colors: {
'text-primary': 'var(--color-text-secondary)',
},
spacing: {
s: 'var(--space-s)',
},
},
},
};
-
Автоматическая сортировка классов:
prettier-plugin-tailwindcss -
Сканирование CSS Modules (если используются оба подхода):
module.exports = {
content: [
'./src/**/*.{ts,tsx}',
'./src/**/*.module.css', // Предотвращает удаление классов Tailwind в CSS Modules
],
};
SHOULD
Компонентный класс при повторении 3+ раза:
@layer components {
.card {
@apply bg-bg-surface rounded-m p-m shadow-1;
}
}
MAY
@apply допускается для:
- Сторонних компонентов без доступа к разметке
- Комбинаций из 4+ модификаторов
FORBIDDEN
- Кастомные утилиты в глобальных стилях (только в
tailwind.config.js)
⚠️ ВАЖНО
@apply увеличивает bundle size — каждый @apply дублирует утилиты в итоговом CSS.
CSS/SCSS Modules
MUST
- Собственный
.module.(s)cssфайл для каждого компонента - camelCase именование классов:
s.cardHeader - CSS variables используют дизайн-токены:
.card {
background: var(--color-bg-surface);
padding: var(--space-m);
}
MAY
Нативный CSS Nesting (Chrome 112+, Safari 16.5+, Firefox 117+):
.card {
background: var(--color-bg-surface);
& .header {
padding: var(--space-m);
}
&:hover {
transform: scale(1.02);
}
}
SHOULD
CSS variables предпочтительнее SCSS-переменных (runtime, темизация, JavaScript доступ)
FORBIDDEN
- Избыточное использование
@extendв SCSS :global()без привязки к родителю- Вложенные
:global()внутри:global()
⚠️ ВАЖНО
CSS Modules не имеют автоматического tree-shaking — используйте Knip для обнаружения неиспользуемых стилей.
MUI System
sx prop (MUI v5+)
MUST
Конфигурация темы использует дизайн-токены:
const theme = createTheme({
palette: {
text: {
primary: 'var(--mui-palette-text-primary)',
},
},
spacing: (factor) => `${0.25 * factor}rem`, // 1 unit = 4px
});
SHOULD
Повторяющиеся sx-стили выносятся при повторении 3+ раза:
// shared/styles/card.ts
export const cardSx = {
p: 2,
borderRadius: 1,
bgcolor: 'background.paper',
};
MAY
Мемоизация sx-объекта:
// Статичный — вне компонента
const cardSx = { p: 2, borderRadius: 1 };
// Динамический — useMemo
const cardSx = useMemo(
() => ({ bgcolor: isActive ? 'primary.main' : 'background.paper' }),
[isActive]
);
FORBIDDEN
sx для высокочастотных динамических значений (>1 раз в несколько секунд):
/* ❌ Неправильно */
<Box sx={{ top: scrollY }}>
/* ✅ Правильно */
<Box style={{ top: scrollY }}>
CSS Cascade Layers
SHOULD
Используйте @layer для управления приоритетами:
@layer reset, base, components, utilities;
@layer components {
.card {
background: var(--color-bg-surface);
}
}
@layer utilities {
.text-center {
text-align: center;
}
}
Преимущества:
- Предсказуемое переопределение без
!important - Совместимость с Tailwind v4
- Поддержка >95% браузеров
Поддержка: Chrome 99+, Safari 15.4+, Firefox 97+
Написание стилей
Селекторы
FORBIDDEN
- Составные селекторы через SCSS
&:
/* ❌ Неправильно */
.card {
&__header {
&__title {
}
}
}
/* ✅ Правильно */
.cardHeader {
}
.cardHeaderTitle {
}
- Селекторы по тегам:
div,ul,span - Селекторы по утилитарным классам:
.text-sm,.color-light
MAY
Современные селекторы с проверкой поддержки:
/* :has() — Chrome 105+, Safari 15.4+, Firefox 121+ (>90%) */
.card:has(.badge) {
padding-top: var(--space-xl);
}
.form:has(input:invalid) {
border-color: var(--color-error);
}
/* @scope — Chrome 118+, Safari 17.4+ (<90%, требует fallback) */
@supports (selector(:scope)) {
@scope (.card) {
.header {
padding: var(--space-m);
}
}
}
/* Fallback для старых браузеров */
@supports not (selector(:scope)) {
.card .header {
padding: var(--space-m);
}
}
Вложенность
Максимум 3 уровня вложенности
MAY
Допустимая вложенность:
- Псевдоклассы (
:hover,:focus) - Псевдоэлементы (
::before,::after) - Медиа-запросы (
@media,@container) - Модификаторы состояния (
.isActive,.isDisabled)
Единицы измерения
| Единица | Применение | Причина |
|---|---|---|
| rem | Шрифты, отступы, размеры, медиа-запросы | Accessibility (масштабирование в настройках браузера/ОС) |
| px | border, outline, box-shadow | Мелкие декоративные детали |
| em | Относительное масштабирование | Масштабируется от font-size родителя |
Базовый размер: 16px (browser default)