Formas complejas

Funciones web: Máscaras SVG

Descripción general

Para recortar elementos en formas complejas y de forma libre, como pinceladas o texturas orgánicas, usa el enmascaramiento de CSS (mask-image). Mientras que clip-path es excelente para formas geométricas o rutas vectoriales, mask-image te permite usar imágenes (como PNG con transparencia) o SVG para definir el área visible de un elemento. Este enfoque es más expresivo porque admite la semitransparencia, lo que permite bordes suaves y texturas complejas que son difíciles o imposibles de lograr con clip-path.

Implementación

Para implementar formas complejas con máscaras CSS, haz lo siguiente:

Usa la transparencia de una imagen

Puedes usar la transparencia de una imagen como máscara, con las partes opacas visibles y las transparentes ocultas. Puede ser un PNG, un SVG o cualquier otra imagen con transparencia, o bien una imagen generada, como un gradiente de 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;
}

Cómo usar un elemento SVG en HTML

También puedes hacer referencia a un elemento <mask> definido en un SVG intercalado en el HTML de tu página. Usa maskContentUnits="objectBoundingBox" para que la máscara se escale automáticamente con el tamaño del elemento. Esto le indica al navegador que interprete todas las coordenadas dentro de la máscara como fracciones de 0 a 1 (como 0.5 para el 50%) en lugar de píxeles absolutos.

Luminancia frente a máscara alfa: De forma predeterminada, las máscaras SVG usan la luminancia (brillo) para determinar la opacidad, donde el blanco revela, el negro oculta y el gris crea semitransparencia. Si, en cambio, quieres que la máscara use el canal alfa (transparencia) de tus formas de SVG, puedes especificar mask-type: alpha; en tu CSS o mask-type="alpha" directamente en el elemento <mask> de 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>

Estrategias de resguardo

Si un navegador no admite mask-image ni la versión con prefijo, haz lo siguiente:

  • El elemento no se recortará y se mostrará como un rectángulo normal.
  • Asegúrate de que el contenido siga siendo legible y de que el diseño no se rompa sin la máscara (mejora progresiva).
  • De manera opcional, usa la detección de funciones para proporcionar una forma de resguardo más simple con 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);
  }
}