Смешивание изображений с помощью CSS cross-fade()
Композитинг двух изображений в CSS без дополнительной разметки или JavaScript раньше означал наложение элементов с помощью position: absolute и жонглирование значениями opacity для каждого из них. Функция cross-fade() полностью устраняет эти издержки, создавая единое смешанное значение <image> непосредственно в вашей таблице стилей.
Ключевые моменты
cross-fade()— это CSS-функция для работы с изображениями, которая композитирует два или более изображения с заданными весами прозрачности в единое значение<image>, используемое везде, где CSS ожидает изображение.- Процентные веса контролируют прозрачность каждого входного изображения в смеси. Пропущенные проценты автоматически распределяются из остатка от 100%.
- Поддержка браузерами неравномерна: Chromium и Safari поддерживают устаревший синтаксис
-webkit-cross-fade(), в то время как Firefox не имеет никакой реализации по состоянию на начало 2026 года. - Используйте блоки
@supportsдля наложения префиксного устаревшего синтаксиса и синтаксиса спецификации поверх надёжного резервного изображения для прогрессивного улучшения.
Что на самом деле делает CSS cross-fade()
cross-fade() — это генерирующая изображения CSS-функция, определённая в спецификации CSS Images Level 4. Она принимает два или более изображения — растровые файлы, градиенты, SVG или сплошные цвета — смешивает их с заданными весами и выводит единое значение <image>. Поскольку результат является типом изображения, вы можете использовать его везде, где CSS ожидает изображение: background-image, mask-image или свойство content на псевдоэлементах.
Это различие важно. В отличие от наложения двух значений background-image с применением background-blend-mode, cross-fade() композитирует входные данные в один результат перед рендерингом. Никаких дополнительных DOM-узлов, никаких побочных эффектов контекста наложения.
Как работают процентные веса
Каждый аргумент принимает необязательный процент, который контролирует непрозрачность этого входного изображения в финальной смеси. Несколько правил управляют математикой:
- Проценты не указаны: входные изображения делятся поровну. Два изображения получают по 50%; три изображения получают по ~33,3%.
- Некоторые проценты пропущены: браузер суммирует объявленные значения, вычитает из 100% и равномерно распределяет остаток среди неуказанных входных изображений.
- Сумма превышает 100%: остаток отрицательный, поэтому любое неуказанное входное изображение обрабатывается как 0% (полностью прозрачное).
- Сумма ниже 100%: недостаток действует как невидимый прозрачный слой, заполняющий разрыв.
/* Равномерное смешивание — проценты не нужны */
cross-fade(url(a.jpg), url(b.jpg)) /* 50% / 50% */
/* Взвешенное смешивание */
cross-fade(url(a.jpg) 70%, url(b.jpg) 30%)
/* Три входных изображения, одно не указано — получает остаток (30%) */
cross-fade(url(a.jpg) 40%, url(b.jpg) 30%, url(c.jpg))
Синтаксис спецификации против реализации WebKit
Здесь начинаются неровности. Спецификация CSS Images Level 4 определяет cross-fade() с поддержкой нескольких входных изображений и независимых процентов для каждого. Более старая реализация WebKit — всё ещё то, что фактически рендерят браузеры на базе Chromium и Safari — принимает ровно два аргумента и один процент, применяемый только к первому изображению.
По состоянию на начало 2026 года: браузеры на базе Chromium поддерживают устаревший синтаксис с префиксом -webkit-. Safari поддерживает как префиксный, так и непрефиксный устаревший синтаксис. Firefox вообще не реализует cross-fade(). Вы можете проверить текущий статус на WebStatus.
Используйте @supports для наложения обоих синтаксисов с надёжным резервным вариантом:
/* Базовый резервный вариант — все браузеры */
.hero {
background-image: url('fallback.jpg');
}
/* Устаревший синтаксис WebKit — Chrome, Safari */
@supports (background-image: -webkit-cross-fade(url(a), url(b), 50%)) {
.hero {
background-image: -webkit-cross-fade(
url('photo.jpg'),
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6)),
60%
);
}
}
/* Синтаксис спецификации — ориентация на будущее */
@supports (background-image: cross-fade(url(a) 50%, url(b))) {
.hero {
background-image: cross-fade(
url('photo.jpg') 60%,
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6))
);
}
}
Discover how at OpenReplay.com.
Практические случаи использования смешивания изображений в CSS
Композитинг изображений в CSS с помощью cross-fade() наиболее полезен, когда вы хотите визуальный эффект без добавления разметки:
- Тонирование изображений: смешайте фотографию со сплошным цветом или градиентом, чтобы применить фирменный оттенок непосредственно в CSS.
- Градиентные наложения: наложите затемняющий градиент поверх изображения героя для читаемости текста без псевдоэлемента.
- Лёгкие эффекты текстуры: смешайте SVG-текстуру с плоским цветным фоном.
Для чего это не подходит: анимированные переходы между изображениями по таймеру. Для этого анимации opacity с ключевыми кадрами на наложенных элементах остаются более совместимым и контролируемым подходом.
cross-fade() в сравнении со связанными CSS-инструментами
| Потребность | Используйте |
|---|---|
| Смешать два изображения по весу прозрачности | cross-fade() |
| Смешать цветовые значения | color-mix() |
| Применить режимы наложения между фоновыми слоями | background-blend-mode |
| Смешать элемент с тем, что находится за ним | mix-blend-mode |
Примечание о доступности
Фоновые изображения — включая те, что созданы с помощью cross-fade() — невидимы для программ чтения с экрана. Если смешанное изображение передаёт смысл, критически важный для страницы, представьте этот контент в HTML вместо этого и обеспечьте достаточный цветовой контраст между любым текстом и смешанным фоном.
Заключение
cross-fade() — это целенаправленный инструмент: он композитирует изображения на уровне таблицы стилей, сохраняет вашу разметку чистой и работает сегодня в Chromium и Safari с префиксом -webkit-. Напишите сначала резервный вариант, наложите блок @supports сверху, и у вас будет прогрессивно улучшенное решение для смешивания изображений в CSS, которое корректно деградирует в Firefox до появления поддержки.
Часто задаваемые вопросы
На практике это ненадёжно работает в разных браузерах. Если вам нужна плавная анимация перехода между двумя изображениями, наложите их как отдельные элементы или фоновые слои и анимируйте их значения opacity вместо этого.
Да. Функция cross-fade() принимает любой допустимый тип CSS-изображения в качестве входных данных, включая linear-gradient(), radial-gradient(), conic-gradient() и ссылки на SVG. Это делает её полезной для смешивания фотографии с градиентным наложением в одном объявлении.
Размеры результирующего изображения вычисляются как средневзвешенное значение размеров входных изображений. Поведение рендеринга может немного отличаться в браузерах, реализующих старый синтаксис WebKit.
Широко распространённого полифилла нет. Наиболее надёжное решение для Firefox — использовать несколько слоёв background-image в сочетании с background-blend-mode или наложить элементы с абсолютным позиционированием и контролировать их прозрачность индивидуально.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..