Хотите заказать веб-сайт? Связаться с нами

mask-image в CSS: подробное руководство

Свойство mask-image в CSS позволяет применять к любому HTML-элементу слой маски, буквально «вырезая» нужную область или создавая плавные переходы прозрачности.

Представьте, что вы работаете с Фотошопом, где на слое лежит картинка, а поверх нее — черно-белая маска. В этом случае белая область маски оставляет пиксели видимыми, черная — скрывает их, а оттенки серого создают полупрозрачность.

mask-image создает маски по такому же принципу, что и Photoshop, но только прямо в коде вашего сайта.

Использование масок открывает безграничные возможности для творчества без ущерба производительности. Вместо того чтобы обрезать изображение в графическом редакторе и сохранять его как PNG с прозрачностью, вы можете оставить исходное изображение нетронутым, а маску применить через CSS. Это особенно удобно для контентных сайтов, где изображения могут меняться, а форма их отображения остается неизменной. Более того, mask-image работает не только с картинками, но и с любыми HTML-блоками: текст можно превратить в маску для видео, а градиент — использовать для плавного затухания краев фотографии.

mask-image в CSS: подробное руководство

Изображения для масок: форматы и ресурсы

Прежде чем погружаться в дебри кода, важно понять, с чем именно мы будем работать. Свойство mask-image принимает в качестве значения URL внешнего файла или функцию градиента.

Базовый синтаксис

/* Прямая ссылка на изображение */
mask-image: url('mask.png');
/* Несколько изображений */
mask-image: url('mask1.png'), url('mask2.png');
/* Линейный градиент */
mask-image: linear-gradient(black, transparent);
/* Ссылка на внешний SVG */
mask-image: url('mask.svg');  
/* Ссылка на элемент внутри SVG */
mask-image: url('#star-mask');  
/* Инлайн SVG */
mask-image: url('data:image/svg+xml;utf8,<svg ...></svg>');

Ключевые особенности

  1. Черный цвет — область будет видимой
  2. Прозрачный/белый — область будет скрытой
  3. Полупрозрачный — создает частичную прозрачность

Форматы изображений для масок играют ключевую роль в конечном результате. Маска работает на основе альфа-канала (прозрачности) или яркости пикселей исходного файла. Существует два основных подхода к созданию таких файлов.

Первый подход

Использование растровых изображений. Лучше всего для этих целей подходит формат PNG с поддержкой 8-битной прозрачности. Почему именно PNG? Потому что JPG не поддерживает прозрачность, и если вы попытаетесь использовать JPG в качестве маски, браузер интерпретирует белые области как видимые, а черные — как скрытые, но добиться полутонов будет сложнее. PNG с градиентом прозрачности позволяет создавать сложные эффекты «исчезновения». Вы также можете использовать формат WEBP, так как он тоже поддерживает альфа-канал и весит меньше, что положительно сказывается на скорости загрузки страниц.

Второй подход

Использование векторной графики в формате SVG. Это, пожалуй, самый гибкий способ, так как SVG масштабируется без потери качества. Вы можете нарисовать в любом векторном редакторе (Figma, Illustrator, Inkscape) звезду, сердечко или сложный абстрактный узор, сохранить его как SVG-файл, а затем применить его как маску. При этом внутренняя заливка SVG не важна, так как браузер считывает именно контуры фигуры. Белая область внутри контура будет видимой, а все, что за пределами контура — скрытым.

Где брать готовые маски?

Можно создавать их самостоятельно в Фотошопе, сохраняя черные силуэты на прозрачном фоне. Либо использовать библиотеки векторных иконок, такие как (откроется в новой вкладке)FontAwesome или (откроется в новой вкладке)Material Icons, экспортируя их в SVG. Также существуют специализированные генераторы CSS-масок, где можно выбрать форму и скачать код.

Синтаксис свойства и подключение внешних файлов

Синтаксис свойства mask-image интуитивно понятен для тех, кто знаком со свойством background-image. Он предполагает указание одного или нескольких источников маски через запятую. Базовое использование выглядит следующим образом:

Пример 1

.elementWithMask {
  /* Путь к файлу PNG с альфа-каналом */
  mask-image: url('/images/circle-mask.png');
  
  /* Важно: задаем размеры, иначе маска может не отобразиться корректно */
  mask-size: cover;
  mask-repeat: no-repeat;
  
  /* Для корректной работы в некоторых браузерах */
  -webkit-mask-image: url('/images/circle-mask.png');
  -webkit-mask-size: cover;
  -webkit-mask-repeat: no-repeat;
  
  /* Сам элемент - это картинка */  
  width: min(400px, 100%);
  height: auto;
}

В этом примере мы берем картинку и применяем к ней маску в виде круга. В итоге картинка будет видна только внутри области круга. Обратите внимание на префикс -webkit-. На данный момент поддержка mask-image в браузерах отличная, но для максимальной совместимости с Safari и старыми версиями браузеров рекомендуется дублировать свойства с вендорным префиксом.

Если ваша маска находится в формате SVG и встроена прямо в HTML или CSS, вы можете ссылаться на её ID. Это позволяет не делать лишний HTTP-запрос.

Пример 2

.element-with-svg-mask {
  width: min(600px, 100%);
  height: auto;  
  mask-image: url('#star-mask');  
}

А в HTML где-то выше должен быть определен сам SVG:

<svg style="position: absolute;" width="0" height="0">
  <defs>
    <mask id="star-mask" maskContentUnits="objectBoundingBox">
      <polygon points="0.5,0 0.61,0.35 1,0.35 0.68,0.57 0.79,0.91 0.5,0.72 0.21,0.91 0.32,0.57 0,0.35 0.39,0.35" fill="white"/>
    </mask>
  </defs>
</svg>

В этом случае звезда будет вырезана прямо поверх вашей фотографии. Использование встроенного SVG предпочтительнее, так как маска масштабируется вместе с контейнером.

Использование градиентов в качестве маски

Одним из самых мощных приемов является создание масок без использования внешних файлов, исключительно средствами CSS.

Для этого используются градиентные функции. Использование градиентов в качестве маски позволяет создавать эффекты плавного появления, виньетки или сложные переходы между цветами.

Градиент в маске работает по тому же принципу: белый цвет — полностью видимая область, черный — полностью прозрачная. Чем ближе цвет к черному, тем прозрачнее становится элемент. Рассмотрим пример, где нижняя часть изображения плавно исчезает, создавая эффект растворения в фоне.

Пример 3

.fading-image {
  width: min(800px, 100%);
  height: auto;  
  
  /* Линейный градиент от черного цвета к прозрачному */  
  mask-image: linear-gradient(to bottom, black 50%, transparent 100%);
}

В результате верхняя половина картинки останется неизменной, а нижняя половина будет становиться всё прозрачнее, пока не исчезнет полностью. Мы можем усложнить задачу и сделать маску в виде радиального градиента, чтобы создать эффект «прожектора».

Пример 4

.fading-image {
  /* Радиальный градиент: в центре черный (видимый), к краям прозрачный */  
  mask-image: radial-gradient(circle at 50% 50%, black 10%, transparent 70%);
}

Здесь интересный момент: обычно мы привыкли, что белый — видимый, черный — нет. Но градиент в примере выше построен от черного к прозрачному. Это значит, что в центре круга элемент будет… невидим? Нет, тут нужно быть внимательным.

Синтаксис градиента для масок идентичен обычному градиенту, но интерпретируются цвета по шкале яркости/альфа-канала.

Черный цвет (black) в контексте маски означает «полностью прозрачно». Белый (white) — «полностью видимо». Прозрачный (transparent) — тоже «прозрачно», так как он равен rgba(0,0,0,0). Чтобы получить видимый центр, нужно использовать белый цвет.

Комбинируя несколько градиентов, можно создавать действительно уникальные формы. Главное помнить про разделение запятыми: множественные маски накладываются друг на друга, увеличивая итоговую непрозрачность (как в фотошопе).

Управление размером и положением маски

Мало просто наложить маску, нужно уметь контролировать, как именно она ляжет на элемент. Для этого существуют свойства-компаньоны, очень похожие на свойства фона. Управление размером и положением маски осуществляется с помощью mask-size, mask-position и mask-repeat.
  1. mask-size принимает значения cover, contain или конкретные размеры (100px 50px). cover масштабирует изображение маски так, чтобы оно полностью покрывало элемент (при этом края могут обрезаться). contain масштабирует так, чтобы маска целиком поместилась в элемент (могут появиться пустые области).
  2. mask-position работает аналогично background-position. По умолчанию маска располагается в левом верхнем углу (0% 0%), но вы можете сместить её в центр (center) или задать точные координаты (20px 30px).
  3. mask-repeat контролирует замощение (тайлинг) маски. Значение no-repeat используется чаще всего, но можно создать и повторяющийся узор.

Рассмотрим пример, где нам нужно, чтобы маска в виде звезды располагалась не по центру, а в правом нижнем углу, и была строго определенного размера.

Пример 3

.star-masked-img {
  width: min(600px, 100%);
  height: auto;
    
  /* Предположим, у нас есть PNG звезды */  
  mask-image: url('star-shape.png');
  
  /* Маска не должна повторяться */  
  mask-repeat: no-repeat;
  
  /* Размер маски: 200 пикселей в ширину, 200 в высоту */  
  mask-size: 200px 200px;
  
  /* Позиция: 20 пикселей от правого края и 15 от нижнего */  
  mask-position: right 20px bottom 15px;
}

Благодаря этим настройкам мы получаем точный контроль над отображением. Это особенно важно при адаптивной верстке, когда размеры контейнера меняются. В таких случаях лучше использовать относительные единицы, например, проценты: mask-size: 50% auto; или mask-position: 30% center;. Стоит отметить, что свойство mask-position работает только в том случае, если маска не заполняет собой весь контейнер (то есть если mask-size меньше размеров элемента или используется mask-repeat: no-repeat).

Робот собирает из блоков сайт

Собери свой код. Запусти сайт!

От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.

Собери свой первый проект под руководством практикующих разработчиков.

Подробнее о курсе

Свойство mask-composite для сложных форм

Когда мы начинаем комбинировать несколько слоев масок, возникает необходимость управлять их взаимодействием друг с другом. Именно здесь на помощь приходит свойство mask-composite.

Свойство mask-composite для сложных форм определяет, как несколько масок будут сочетаться. Представьте, что у вас есть маска в виде круга и маска в виде квадрата. Вы можете их сложить, вычесть или пересечь.

Значения для mask-composite

  1. add — это значение по умолчанию. Маски просто накладываются друг на друга. Результирующая область — это объединение всех областей.
  2. subtract — из первой маски вычитаются последующие. То есть область первой маски останется, но из нее будут удалены участки, которые перекрываются со второй маской.
  3. intersect — результирующей областью становится только то место, где пересекаются все маски.
  4. exclude — видимыми остаются области, которые не пересекаются (симметричная разность). Это как если бы мы оставили всё, кроме пересечений.

Этот функционал открывает огромные возможности для создания кнопок причудливой формы, иконок или узоров без использования SVG. Давайте представим, что нам нужно создать фигуру «месяц» (серп). Это можно сделать, вычтя из большого круга маленький круг, немного смещенный в сторону.

Пример 4

.crescent-moon {
  aspect-ratio: 1;
  width: 250px;  
  background: #f5e56b;
  mask-image: radial-gradient(circle at 110px 100px, white 100px, transparent 0),
    radial-gradient(circle at 168px 100px, black 80px, transparent 0);
  mask-composite: exclude;
  mask-repeat: no-repeat;
}

В этом коде мы используем две градиентные маски. Первая создает большой круг (видимая область — белый цвет). Вторая создает меньший круг (черный цвет означает, что эта область будет прозрачной). Свойство mask-composite: exclude делает так, что видимой остается область первого круга, за исключением места пересечения со вторым, что и дает форму полумесяца.

Важно помнить о кроссбраузерности: поддержка mask-composite чуть хуже, чем у обычных масок, и в браузерах на движке WebKit (Safari) могут быть нюансы с интерпретацией значений subtract и exclude. Часто для достижения одинакового результата во всех браузерах приходится использовать -webkit-mask-composite с его специфическим набором ключевых слов (source-over, source-out, xor и т.д.).

Практический пример. Маскируем текст и видео

Рассмотрим интересный вариант использования масок: создание текста, заполненного видео. Он наглядно демонстрирует мощь технологии.

Допустим, у нас есть крупный заголовок H1, и мы хотим, чтобы он был заполнен движущимся видео. Раньше для этого требовалось использовать сложные JS-библиотеки. Сейчас это делается в пару строк CSS.

Пример 5


<div class="video-content">
  <svg width="0" height="0" style="position: absolute;">
    <defs>
      <mask id="ocean" maskContentUnits="objectBoundingBox">
        <path d="M0.936,0.007 v0.364 h-0.079 V0.007 h-0.064 v0.807 L0.732,0.007 h-0.072 l-0.057,0.75 h-0.097 v-0.156 h0.085 v-0.219 h-0.085 v-0.139 h0.1 V0.007 h-0.234 l-0.06,0.362 h-0.013 V0.007 h-0.064 v0.364 c-0.001,-0.017,-0.003,-0.035,-0.004,-0.052 c-0.006,-0.06,-0.014,-0.114,-0.024,-0.162 c-0.01,-0.048,-0.023,-0.086,-0.037,-0.115 C0.154,0.014,0.138,0,0.12,0 s-0.033,0.013,-0.048,0.04 c-0.015,0.027,-0.027,0.064,-0.038,0.11 c-0.011,0.047,-0.019,0.1,-0.025,0.159 C0.003,0.369,0,0.431,0,0.497 s0.003,0.126,0.008,0.185 c0.006,0.06,0.014,0.113,0.024,0.161 c0.01,0.048,0.023,0.086,0.037,0.114 c0.015,0.028,0.031,0.042,0.049,0.042 s0.034,-0.014,0.048,-0.041 c0.015,-0.027,0.027,-0.064,0.038,-0.111 c0.011,-0.047,0.019,-0.1,0.025,-0.159 c0.002,-0.018,0.003,-0.036,0.004,-0.054 v0.358 h0.064 v-0.378 h0.011 l0.063,0.378 h0.279 l0.012,-0.193 h0.066 l0.012,0.193 h0.116 v-0.386 h0.079 v0.386 h0.064 V0.007 h-0.064 M0.17,0.592 c-0.002,0.031,-0.005,0.059,-0.01,0.085 c-0.004,0.025,-0.01,0.046,-0.017,0.06 c-0.007,0.015,-0.015,0.022,-0.024,0.022 s-0.017,-0.007,-0.024,-0.022 c-0.007,-0.014,-0.012,-0.034,-0.017,-0.058 c-0.004,-0.025,-0.008,-0.052,-0.01,-0.083 c-0.002,-0.031,-0.003,-0.063,-0.003,-0.097 s0.001,-0.064,0.003,-0.095 c0.002,-0.031,0.005,-0.059,0.01,-0.083 c0.004,-0.025,0.01,-0.044,0.017,-0.059 c0.007,-0.015,0.015,-0.022,0.024,-0.022 s0.017,0.007,0.024,0.021 c0.007,0.014,0.012,0.033,0.017,0.058 c0.004,0.025,0.008,0.052,0.01,0.083 c0.002,0.031,0.003,0.062,0.003,0.096 s-0.001,0.064,-0.003,0.095 M0.36,0.483 L0.441,0.011 v0.936 l-0.082,-0.463 M0.674,0.619 l0.022,-0.347,0.022,0.347 h-0.044" fill="white" />
      </mask>
    </defs>
  </svg>
  <video src="video-ocean.mp4" type="video/mp4" autoplay loop muted playsinline class="masked-video">
  </video>
</div>
.video-content {  
  mask-image: url(#ocean);
}
.masked-video {
  width: 100%;
}

В этом примере маска использует SVG с белыми буквами, эти области становятся видимыми (прорезается окно к видео), а остальная часть скрывает видео. Это дает эффект надписи, заполненной видео.

Особенности анимации и трансформации масок

Маски — это не статичное явление. Их можно и нужно анимировать, создавая интерактивные и привлекающие внимание компоненты. Особенности анимации и трансформации масок заключаются в том, что мы можем менять их положение, размер и даже саму форму градиента.

Для анимации лучше всего использовать CSS-переходы или ключевые кадры.

Анимировать изменение градиента (например, с линейного на радиальный) нельзя, а вот анимировать позицию или размер — вполне.

Рассмотрим кнопку, у которой эффект появления (обрезания) появляется при наведении курсора.

Пример 6

.animated-mask-button {
  padding: 16px 42px;
  background: linear-gradient(90deg, #ff7e5f, #feb47b);
  color: white;
  border: none;
  font-size: 18px;
  cursor: pointer;
  position: relative;
  outline: none;
  
  /* Базовая маска: вся кнопка видна */
  mask-image: linear-gradient(90deg, white 100%, transparent 0);
  mask-size: 200% 100%;
  mask-position: 0 0;
  
  transition: mask-position 0.4s ease, -webkit-mask-position 0.4s ease;
}

.animated-mask-button:hover {
  /* Смещаем градиент маски, создавая эффект вырезания слева направо */
  mask-position: 100% 0;
}

В этом примере мы создаем линейный градиент, который изначально полностью белый, то есть кнопка видна целиком. Размер маски мы устанавливаем в 200% от ширины кнопки, что создает пространство для движения. При наведении позиция маски смещается на 100% вправо. Но так как наш градиент имеет жесткую границу (white 100%, transparent 0), то в итоге в области видимости оказывается та часть градиента, где находится белый цвет. Смещая его, мы заставляем белую полосу «проходить» по кнопке, создавая эффект появления или исчезновения.

Анимировать SVG-маски сложнее, так как нужно менять атрибуты самого SVG, но градиентные маски анимируются очень плавно и легко, используя все преимущества аппаратного ускорения браузера.

Поддержка браузерами

Поддержка браузерами для mask-image находится на очень высоком уровне. Свойство стабильно работает во всех актуальных версиях Chrome, Firefox, Safari, Edge и Opera. Основные проблемы могут возникнуть только в Internet Explorer (который официально мертв) и в очень старых мобильных браузерах.

Тем не менее, при разработке коммерческого сайта для веб-студии важно предусмотреть сценарий, когда маска не сработает. Пользователь не должен увидеть сломанный дизайн. Для этого используется принцип прогрессивного улучшения.

Самый простой способ обеспечить безопасность — использовать @supports.

Пример 7

.hero-section {
  background: url('fallback-image.jpg');
  /* Обычное изображение, если маска не поддерживается */
}

@supports (mask-image: linear-gradient(black, white)) or (-webkit-mask-image: linear-gradient(black, white)) {
  .hero-section {
    background: url('main-image.jpg');
    mask-image: radial-gradient(circle at center, white 30%, transparent 100%);
  }
}

В этом примере браузер сначала применит обычный фон. Затем он проверит, поддерживает ли он свойство mask-image. Если поддерживает, то правила внутри @supports перезапишут предыдущие, и изображение получит маску. Пользователи современных браузеров увидят задуманный эффект, а пользователи устаревших браузеров увидят просто картинку без обрезания, что вполне приемлемо.

Также не стоит забывать о том, что свойство mask является шорткатом и позволяет задать все параметры (изображение, позицию, размер, повтор, композитинг) в одной строке, что делает код чище, но для лучшей поддержки старых версий браузеров иногда предпочтительнее использовать отдельные свойства.

Заключение

Освоив даже такой продвинутый инструмент, как mask-image, вы делаете серьезный шаг от новичка к профессионалу. Однако маски — это лишь малая часть огромного мира современной верстки. Если вы хотите систематизировать знания, научиться создавать сложную анимацию, адаптивные интерфейсы и коммерческие проекты с нуля, обратите внимание на наш онлайн-курс «Веб-верстка с нуля до профессионала». Мы собрали в нем всю самую важную информацию: от семантики и Flexbox до продвинутых графических эффектов и оптимизации производительности.

Если же вам нужен не учебный проект, а готовый рабочий инструмент для бизнеса, и вы хотите получить сайт, который будет не только красивым (с использованием тех же масок), но и приносить реальную прибыль, — доверьте эту задачу нашей веб-студии. Мы воплотим в жизнь самые смелые дизайнерские идеи с учетом всех тонкостей юзабилити и современных трендов.

Теги: