Formas complexas

Recursos da Web: Máscaras SVG

Visão geral

Para cortar elementos em formas complexas e de formato livre, como pinceladas ou texturas orgânicas, use a máscara CSS (mask-image). Embora clip-path seja excelente para formas geométricas ou caminhos vetoriais, mask-image permite usar imagens (como PNGs com transparência) ou SVGs para definir a área visível de um elemento. Essa abordagem é mais expressiva porque oferece suporte à semitransparência, permitindo bordas suaves e texturas complexas que são difíceis ou impossíveis de alcançar com clip-path.

Implementação

Para implementar formas complexas usando máscaras CSS:

Como usar a transparência de uma imagem

É possível usar a transparência de uma imagem como uma máscara, com as partes opacas visíveis e as transparentes ocultas. Pode ser um PNG, SVG ou outra imagem com transparência, ou uma imagem gerada, como um gradiente CSS.

.shaped-element {
  /* MANDATORY: Use vendor prefix for wider support in older browsers */
  -webkit-mask-image: url('mask.svg');
  -webkit-mask-size: cover; /* Scale mask to cover element */
  -webkit-mask-repeat: no-repeat; /* Do not tile the mask */

  /* Standard property for modern browsers */
  mask-image: url('mask.svg');
  mask-size: cover;
  mask-repeat: no-repeat;
}

Como usar um elemento SVG em HTML

Também é possível referenciar um elemento <mask> definido em um SVG inline no HTML da página. Use maskContentUnits="objectBoundingBox" para que a máscara seja dimensionada automaticamente de acordo com o tamanho do elemento. Isso informa ao navegador para interpretar todas as coordenadas dentro da máscara como frações de 0 a 1 (como 0.5 para 50%) em vez de pixels absolutos.

Máscara de luminância x máscara alfa: por padrão, as máscaras SVG usam a luminância (brilho) para determinar a opacidade, em que o branco revela, o preto oculta e o cinza cria semitransparência. Se você quiser que a máscara use o canal Alfa (transparência) das formas SVG, especifique mask-type: alpha; no CSS ou mask-type="alpha" diretamente no elemento <mask> do SVG.

<!-- White areas reveal content, gray creates semi-transparency, black or transparent hides it -->
<svg width="0" height="0">
  <defs>
    <!-- objectBoundingBox scales mask coordinates (0 to 1) with the element's size -->
    <mask id="custom-shape" maskContentUnits="objectBoundingBox">
      <!-- Use white shapes to define fully opaque areas -->
      <circle cx="0.5" cy="0.5" r="0.5" fill="white" />
      <!-- Use gray shapes to define semi-transparent/faded areas -->
      <circle cx="0.5" cy="0.5" r="0.25" fill="gray" />
    </mask>
  </defs>
</svg>

<div class="masked-content">
  <!-- Content to be masked -->
</div>

<style>
.masked-content {
  /* Reference the SVG mask ID */
  -webkit-mask-image: url(#custom-shape);
  mask-image: url(#custom-shape);
}
</style>

Estratégias de fallback

Se um navegador não for compatível com mask-image ou com a versão prefixada:

  • O elemento não será cortado e vai aparecer como um retângulo normal.
  • Verifique se o conteúdo ainda está legível e se o layout não é corrompido sem a máscara (aprimoramento progressivo).
  • Se quiser, use a detecção de recursos para fornecer uma forma de substituição mais simples com clip-path.
/* Fallback for browsers that do not support masking */
@supports (not (mask-image: url(x))) and (not (-webkit-mask-image: url(x))) {
  .shaped-element {
    /* Use a simple rounded rectangle as fallback */
    clip-path: inset(5% round 15px);
  }
}