CSS-миксины (@mixin/@apply) вошли в раннюю стадию
реализации в Chromium под руководством инженеров Microsoft Edge. Разбираем синтаксис,
отличия от Sass, текущую поддержку браузеров и стратегию миграции — с примерами кода.
8 июля 2026 года в Chrome Platform Status появилась запись о новой функции: CSS mixins (@mixin / @apply / @macro). Запись, созданная инженерами Microsoft Edge — John Jansen, Kevin Babbitt и Leo Lee — знаменует начало реализации в Chromium одной из самых востребованных возможностей CSS за последнее десятилетие.
Годами разработчики полагались на Sass, Less и PostCSS для создания переиспользуемых блоков CSS. Спецификация CSS Functions and Mixins Module Level 1 (авторы — Miriam Suzanne и Tab Atkins) предлагает нативное браузерное решение — без шага сборки, без зависимостей, просто CSS.
Это уже не спекулятивная идея. Команда Edge создала баг-трекер Chromium, Chrome Canary уже поддерживает миксины за флагом, а Adam Argyle из Google публично демонстрирует синтаксис. Давайте разберёмся, что нас ждёт и как это изменит подход к CSS.
CSS-миксин — это переиспользуемый блок стилей и вложенных правил,
определяемый через at-rule @mixin. Вы даёте ему имя, опционально
принимаете параметры и разворачиваете его на месте с помощью @apply.
Простейший миксин — без параметров (@macro):
/* Определяем макрос: без параметров */ @macro --box { aspect-ratio: 1; inline-size: 100px; block-size: 100px; background: teal; } /* Используем где угодно */ .avatar { @apply --box; border-radius: 50%; } .icon { @apply --box; }
С @mixin можно добавлять типизированные параметры со значениями
по умолчанию:
/* Миксин с типизированными параметрами */ @mixin --button ( --face type(color): teal, --text type(color): white, --radius type(length): 4px ) { @result { background: var(--face); color: var(--text); border-radius: var(--radius); padding: 0.5em 1.25em; border: none; cursor: pointer; } } /* Применяем с аргументами */ button.primary { @apply --button(dodgerblue); } button.danger { @apply --button(crimson); }
Блок @result содержит объявления для вывода. Локальные кастомные
свойства вне @result остаются внутри миксина и не протекают на
элемент — критическая граница приватности, которую Sass не может обеспечить.
Параметры в прелюдии @mixin используют список через запятую.
Каждый параметр может иметь:
type() (например, type(color), type(length), type(*)): 1rem)/* Различные паттерны параметров */ /* Без параметров — используем @macro */ @macro --clearfix { @result { content: ""; display: table; clear: both; } } /* Позиционные параметры с умолчаниями */ @mixin --card ( --padding: 1rem, --bg: white, --radius: 8px ) { @result { padding: var(--padding); background: var(--bg); border-radius: var(--radius); box-shadow: 0 1px 3px rgba(0,0,0,0.1); } }
Блок @result обязателен для каждого миксина — это место,
где находятся стили для вывода. Всё вне @result — промежуточные
вычисления (кастомные свойства), которые никогда не попадают на элемент.
@mixin --responsive-padding (--scale: 1) { --base-pad: calc(1rem * var(--scale)); --lg-pad: calc(2rem * var(--scale)); @result { padding: var(--base-pad); } @result @media (min-width: 768px) { padding: var(--lg-pad); } }
--base-pad и --lg-pad — приватные переменные миксина.
Вызывающий элемент получает только объявление padding. В Sass
такой скоупинг невозможен.
Если вы знакомы с Sass, модель знакома, но механика принципиально иная. CSS-миксины — декларативные и каскадируемые; Sass-миксины — императивные и работают на этапе сборки.
| Возможность | Sass | CSS (@mixin/@apply) |
|---|---|---|
| Время обработки | На этапе сборки (компилируется в статический CSS) | В браузере (в CSS-движке) |
| Аргументы | Императивные, любые типы Sass | Декларативные, типизированные через type(), принимают кастомные свойства |
| Условная логика | @if, @else, @each, @while | Нет (используйте @media/@supports внутри @result) |
| Область видимости | Лексическая (глобальная или блочная) | Скоупинг через кастомные свойства в теле миксина; каскадируемые значения передаются |
| Вывод | Пишет объявления в stylesheet | Пишет вычисленные объявления в каскад |
| Взаимодействие с каскадом | Нет (вывод статичен) | Полное — аргументами могут быть кастомные свойства, обновляемые через каскад |
| Зависимости | Компилятор Sass, инструменты сборки | Нет — нативная функция браузера |
Главное отличие: аргументами могут быть кастомные свойства. Вызов
@apply --button(var(--theme-primary)) реагирует на каскад.
Меняете значение через класс или медиа-запрос — миксин пересчитывается.
Препроцессоры на это неспособны.
💡 Ключевая мысль: CSS-миксины не просто заменяют Sass-миксины — они реализуют паттерны, недоступные Sass. Адаптация стилей в рантайме через каскад — главная возможность. Препроцессоры генерируют статический вывод; CSS-миксины генерируют живые, каскадно-зависимые стили.
Спецификация CSS Functions and Mixins Module Level 1 включает и
пользовательские функции (@function). Если миксины
возвращают объявления, функции возвращают значения — цвета, длины, строки —
которые используются внутри значений свойств.
/* CSS-функция, возвращающая значение */ @function --negative (--value type(length)) { result: calc(-1 * var(--value)); } .box { margin-inline-start: --negative(var(--gap)); } /* Более сложная функция для fluid-типографики */ @function --fluid-clamp ( --min type(length), --max type(length), --min-vw type(length): 375px, --max-vw type(length): 1200px ) { --slope: calc((var(--max) - var(--min)) / (var(--max-vw) - var(--min-vw))); --intercept: calc(var(--min) - var(--slope) * var(--min-vw)); result: clamp(var(--min), var(--intercept) + var(--slope) * 100cqw, var(--max)); } h1 { font-size: --fluid-clamp(1.5rem, 3rem); }
| Функция | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| @mixin / @apply | Canary (флаг) | В разработке | Нет данных | Нет данных |
| @function | Canary (флаг) | В разработке | Нет данных | Нет данных |
| CSS Nesting | 120+ | 120+ | 117+ | 17.2+ |
Чтобы попробовать CSS-миксины в Chrome Canary:
# macOS open -a "Google Chrome Canary" --args --enable-features=CSSMixins # Linux google-chrome-unstable --enable-features=CSSMixins
Флаг CSSMixins включает как @mixin/@macro/@apply,
так и @function. Баг-трекер Chromium
(issue 406935599) —
место для отслеживания прогресса.
@mixin --btn ( --bg type(color), --fg type(color): white ) { --hover-bg: color-mix(in srgb, var(--bg), black 5%); @result { background: var(--bg); color: var(--fg); border: none; padding: 0.5em 1.25em; border-radius: 6px; cursor: pointer; } } .btn-primary { @apply --btn(dodgerblue); } .btn-success { @apply --btn(seagreen); }
@mixin --gradient-text ( --from type(color), --to type(color), --angle type(angle): 135deg ) { --grad: linear-gradient(var(--angle), var(--from), var(--to)); @result { background: var(--grad); background-clip: text; -webkit-background-clip: text; color: transparent; } } .hero-title { @apply --gradient-text(teal, purple); }
Нативные CSS-миксины не заменят весь Sass сразу — это постепенная миграция:
CSS Nesting (уже во всех современных браузерах) устраняет ещё одну зависимость от Sass. Вместе с nesting, container queries и новыми цветовыми функциями, нативные CSS-миксины завершают картину: будущее, в котором веб-разработчики могут писать на чистом CSS без препроцессоров.
Больше о возможностях современного CSS без JavaScript и препроцессоров — в моём обзоре CSS съедает JavaScript. Об адаптивных контейнерных макетах — в руководстве по CSS Container Queries. И о свежих CSS-функциях в Chrome — в обзоре Chrome 150.
Реализация CSS-миксинов в Chromium находится на стадии Prototype — самой ранней фазе Blink launch process. Даты релиза пока нет, Firefox и WebKit ещё не дали сигналов.
Что можно сделать прямо сейчас:
CSSMixinsНативные CSS-миксины — знаковая веха для платформы. Впервые за историю CSS самая популярная возможность препроцессоров получает нативную реализацию — и это не простой порт. Каскадно-зависимый, приватно-скоупированный дизайн с условным выводом действительно превосходит то, что предлагает Sass. Следующий год разработки Chromium будет завораживающим.
Нужна помощь в модернизации CSS-архитектуры или подготовке к нативным миксинам? Я доступен для консультаций по frontend-архитектуре и разработке. Посмотрите услуги или свяжитесь напрямую.
Я разрабатываю production-приложения на современном CSS и JavaScript. Обсудим ваш проект — бесплатная консультация.