Маскирование и композитинг (mask-image) в CSS

Маскирование в CSS: когда clip-path уже не вывозит

Присаживайся, коллега. Давай по-честному: сколько раз ты сталкивался с ситуацией, когда дизайнер притаскивает макет, где картинка плавно растворяется в фоне, или, что еще хуже, имеет сложную форму с мягкими краями и полупрозрачностью? Обычным свойством opacity тут не отделаешься, а если фон под картинкой — градиент или другой сложный паттерн, то начинаются настоящие танцы с бубном.

Обычно в такие моменты в голову приходит clip-path. Это крутой инструмент, и мы уже разбирали, как с его помощью делать создание сложных фигур через clip-path. Но у него есть жирный минус: он работает бинарно. Либо пиксель виден, либо нет. Никакой мягкой растушевки или полупрозрачности. И вот тут на сцену выходит mask-image — тяжелая артиллерия для тех, кто хочет делать интерфейсы уровня «Apple».

Как мы страдали раньше

До того как современные браузеры подружились с CSS-масками, жизнь была похожа на средневековую пытку. У нас было три пути, и все они вели в тупик:

  • PNG-заплатки: Мы накладывали поверх картинки прозрачный PNG-файл, который имитировал переход в фон. Поменяли цвет фона? Перерисовывай все картинки в Photoshop. Это был ад для поддержки.
  • Инлайновый SVG: Мы оборачивали контент в огромные куски SVG-кода с тегами <mask> или <clippath>. Это раздувало DOM и превращало чтение кода в разгадывание ребусов.
  • Canvas-хаки: Если нужно было что-то динамическое, подключали JS и рисовали через Canvas. О производительности и доступности в такие моменты старались не думать.

Как делать правильно в 2026 году

Сегодня mask-image — это фактически background-image, только наоборот. Вместо того чтобы рисовать что-то на элементе, маска определяет, какие части элемента будут видны. Самое мощное — это использование градиентов в качестве масок.

Но современный подход идет дальше. Теперь мы используем mask-composite. Это свойство позволяет смешивать несколько масок, используя логические операции: сложение, вычитание, пересечение. Например, ты можешь взять одну маску-градиент и «вычесть» из неё форму иконки. При этом важно не забывать про пропорции контента, используя свойство aspect-ratio, чтобы маска не «поплыла» на разных экранах.

В 2026 году стандарт окончательно устаканился, и мы можем использовать маски без лишних префиксов (хотя для старых Safari -webkit- все еще иногда мелькает в автопрефиксерах, но мы-то смотрим в будущее).

Готовый сниппет кода

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


.cool-card {
    width: 300px;
    aspect-ratio: 1 / 1;
    background: url('hero-image.jpg') center/cover;

    /* Определяем две маски: градиент и круг */
    --mask-gradient: linear-gradient(to bottom, transparent, black 50%);
    --mask-circle: radial-gradient(circle at center, transparent 20%, black 21%);

    /* Применяем маски */
    mask-image: var(--mask-gradient), var(--mask-circle);
    
    /* Композитинг: оставляем только то, что входит в обе маски (пересечение) */
    /* В современном CSS используем ключевые слова стандарта */
    mask-composite: intersect;
    
    /* Для совместимости со старым WebKit (Safari/Chrome) */
    -webkit-mask-composite: source-in;
    
    transition: mask-image 0.3s ease;
}

.cool-card:hover {
    /* Маски можно анимировать! */
    --mask-circle: radial-gradient(circle at center, transparent 0%, black 0%);
}

Частая ошибка новичков

Самый частый затык — это непонимание разницы между Alpha Mask и Luminance Mask.

По умолчанию CSS использует mask-mode: alpha. Это значит, что браузер смотрит только на прозрачность твоей маски. Если ты используешь в качестве маски картинку, где есть черный и белый цвета, но нет прозрачности (альфа-канала), то маска… просто не сработает. Весь элемент останется видимым.

Если тебе нужно, чтобы маска работала по яркости (белое — видно, черное — скрыто), нужно явно прописать mask-mode: luminance. Но на практике проще всегда работать с прозрачностью в linear-gradient или PNG/SVG, так меньше шансов выстрелить себе в ногу при кроссбраузерной верстке.

И помни: маски — это про прозрачность, а не про цвет. Не пытайся задать цвет внутри mask-image, он там просто игнорируется.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх