Как наложить 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.

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

    Часто задаваемые вопросы