Saltar al contenido

Elegir entre recorte y máscara

La tabla de decisión completa: borde, eventos, coste, animabilidad, exportación e impresión. Y las combinaciones donde hacen falta los dos.

Las seis dimensiones

Dimensión clipPath mask
Valor por píxel Binario, dentro o fuera Continuo, 0 a 1
Borde Duro, con antialiasing de un píxel Tan suave como quieras
Eventos de puntero Recorta el área sensible No la toca
Coste de composición Bajo, es una región de recorte Alto, dos búferes y una multiplicación
Aislamiento No crea grupo aislado Crea grupo aislado
Animabilidad Interpolable entre formas compatibles Se anima el contenido, no la propiedad

Cada fila decide un caso.

Los cinco casos

Uno: una foto con forma de hexágono. Borde duro, sin transparencia parcial, y quieres que solo el hexágono responda al clic. Recorte. Además es más barato y se imprime bien.

Dos: una lista con scroll que se difumina en los bordes. Transición continua, y el texto difuminado debe seguir siendo seleccionable. Máscara, con un degradado. El recorte produciría un corte en seco.

Tres: un texto relleno con una imagen. Binario, la forma la dan los glifos. Recorte con text dentro del clipPath, o background-clip: text si estás en HTML, que es más simple y tiene mejor soporte para este caso concreto.

Cuatro: un logotipo que aparece con una barrida de izquierda a derecha. La transición es continua y hay que animarla. Máscara con un degradado cuyo x1/x2 se anima, o con una máscara de CSS animando mask-position. El recorte también funcionaría (animando inset()) y da un borde duro; la elección depende de si el diseño quiere un borde nítido de barrido o uno difuso.

Cinco: un panel modal que oscurece el fondo salvo un agujero circular sobre un elemento destacado. El agujero tiene que dejar pasar los clics al elemento de debajo. Aquí ninguna de las dos sirve por sí sola, y es el caso de la combinación.

Combinar los dos

En el caso cinco, el velo oscuro se dibuja con una máscara que tiene un agujero (para que el borde del agujero sea suave), pero además hay que resolver los eventos. La máscara no los corta, así que el velo bloquea los clics del agujero.

La solución es un velo compuesto por dos elementos:

HTML
<div class="velo" aria-hidden="true"></div>
CSS
.velo {  position: fixed;  inset: 0;  background: rgb(0 0 0 / .7);  pointer-events: none;                    /* deja pasar todo */  mask:    radial-gradient(circle 90px at var(--x) var(--y),                    transparent 0 70%, #000 100%);}

El pointer-events: none hace que el velo no capture nada, y la máscara le da el agujero suave. La zona oscura tampoco captura clics, lo que en un modal de verdad no sirve; para eso se añade un segundo elemento con clip-path que sí capture, con el agujero recortado. Pero para un resaltado de onboarding, donde solo quieres que el usuario pueda pulsar el elemento destacado y el resto de la interfaz sea navegable, el velo pasivo es exactamente lo correcto.

Otro caso de combinación frecuente: recortar para la geometría y enmascarar para el desvanecimiento.

CSS
.tarjeta-foto {  clip-path: inset(0 round 16px);   /* esquinas duras y limpias */  mask: linear-gradient(to top, transparent, #000 40%);}

El recorte da las esquinas redondeadas con borde nítido y corta los eventos; la máscara desvanece la parte inferior para que el texto superpuesto se lea. Las dos operaciones se aplican en cadena y no interfieren.

Cuándo ninguno de los dos es la respuesta

Tres casos donde la gente llega a este nivel buscando la herramienta y la herramienta es otra.

Ocultar la mitad de un elemento por un cambio de estado. Si el corte es rectangular y alineado con los ejes, overflow: hidden en un contenedor es más simple, más barato y se comporta mejor con el scroll.

Un borde con degradado. La técnica de dos máscaras con mask-composite: exclude funciona, y border-image con un linear-gradient es más directa y no crea grupo aislado. Comprueba primero si tu caso la admite.

Redondear las esquinas de un elemento. border-radius, siempre. Recorta el contenido, recorta los eventos, se imprime bien y es la primitiva que el motor tiene más optimizada. Un clip-path: inset(0 round 16px) hace lo mismo con más coste y sin la resolución proporcional de radios adyacentes.

Y una advertencia general: tanto clip-path como mask crean, en muchos motores, una capa de composición propia. Diez elementos enmascarados en una lista con scroll pueden multiplicar la memoria de vídeo y hacer que el scroll se entrecorte. Si el efecto es puramente decorativo y afecta a muchos elementos, mide antes de darlo por bueno.