Как наложить SVG на 4 блока с контентом через маску
При создании сложных макетов часто возникает задача разместить одно SVG-изображение поверх нескольких блоков с контентом, при этом фон блоков должен просвечивать через маску, а контент - оставаться читаемым. В этой статье мы разберём правильную технику вёрстки с использованием CSS mask, которая решает проблему без z-index и лишних медиазапросов.
Проблема: SVG поверх блоков
Представьте: у вас есть 4 карточки с белым фоном и текстом. Сверху на них накладывается одно SVG-изображение (например, волна или сложная геометрия). Вы хотите, чтобы SVG работало как маска: в одних местах фон блоков оставался белым, в других - становился прозрачным или цветным. При попытке использовать z-index контент уезжает вниз, а фон перекрывается.
Правильное решение: CSS mask и абсолютное позиционирование
Вместо того чтобы делать 4 отдельных фоновых изображения или мучиться с z-index, используйте один контейнер с position: relative. Внутри разместите 4 блока с контентом (с position: relative и z-index: 1), а SVG - как абсолютно позиционированный элемент с z-index: 2 и свойством mask-image.
Пошаговая инструкция
- Шаг 1. Создайте общий контейнер:
display: flex; flex-wrap: wrap; position: relative; - Шаг 2. Каждый блок с контентом:
flex: 1 1 50%; position: relative; z-index: 1; background: white; - Шаг 3. SVG-элемент:
position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; mask-image: url('wave.svg'); mask-size: cover; pointer-events: none; - Шаг 4. Убедитесь, что у SVG нет собственного фона - только прозрачные области для маски.
Почему z-index не работал?
z-index работает только между элементами на одном уровне стека. Если SVG и блоки находятся в разных контекстах наложения (например, один из них имеет transform или opacity), z-index может игнорироваться. В нашем решении все элементы находятся в одном контейнере с position: relative, что создаёт единый контекст.
Преимущества подхода с одной маской
- Одно SVG вместо четырёх - меньше кода и HTTP-запросов.
- Нет лишних @media для каждого блока.
- Маска легко адаптируется под разные размеры экрана через
mask-size: containилиcover. - Контент остаётся кликабельным благодаря
pointer-events: noneна SVG.
Пример кода для адаптивности
Если маска должна менять форму на мобильных, используйте медиазапросы только для контейнера SVG:
@media (max-width: 768px) {
.svg-mask {
mask-image: url('wave-mobile.svg');
}
}Это проще, чем переопределять фон для каждого из четырёх блоков отдельно.
Советы по SVG-маскам
- Используйте
mask-mode: luminanceилиmask-mode: alphaв зависимости от типа SVG. - Для старых браузеров добавьте префикс
-webkit-mask-image. - Проверяйте, чтобы SVG имел корректные атрибуты
viewBoxиxmlns.
Этот подход избавляет от лишних медиазапросов и дублирования кода, делая вёрстку чистой и поддерживаемой. Попробуйте - и ваши блоки будут выглядеть профессионально на любом экране.