wandres.dev
RECORTE Y MÁSCARAS · clip-path, mask, shape-outside

Recortar es binario, enmascarar tiene alfa

La diferencia conceptual entre las dos operaciones, qué puede hacer cada una que la otra no puede, y por qué el coste de rendimiento es distinto.

⏱ 15 min

clip-path y mask se presentan como alternativas y no lo son: son dos operaciones distintas que casualmente sirven para lo mismo en el caso más simple. Una decide para cada píxel si está o no está; la otra decide cuánto está. De esa diferencia de un bit frente a ocho salen todas las demás, incluidas las de coste.

🎯 Al terminar esta lección sabrás
  • Formular las dos operaciones en términos del canal alfa resultante.
  • Enumerar tres efectos que solo son posibles con máscara.
  • Enumerar dos ventajas que solo tiene el recorte.
  • Elegir entre las dos con un criterio y no por costumbre.

Las dos operaciones, en una línea cada una

Recortar multiplica el alfa de cada píxel por 0 o por 1, según esté dentro o fuera de una región geométrica.

Enmascarar multiplica el alfa de cada píxel por un número entre 0 y 1, tomado de otra imagen.

El recorte es el caso particular de la máscara donde la máscara solo tiene valores extremos. Cualquier cosa que haga clip-path la puede hacer mask; lo contrario no.

En la práctica el recorte no es exactamente binario en los bordes, porque el rasterizador aplica antialiasing y los píxeles que la frontera atraviesa reciben una cobertura parcial. Pero esa suavización es de un píxel y no la controlas: es una consecuencia del muestreo, no un parámetro.

Lo que solo puede la máscara

Cualquier transición gradual. Un desvanecimiento del contenido hacia un borde, una viñeta, un difuminado. clip-path no puede: solo sabe cortar.

.lista-larga {
  mask-image: linear-gradient(to bottom, #000 80%, transparent);
}

Formas que vienen de una imagen. La silueta de un logotipo, una textura, un pincel. Cualquier PNG con canal alfa o cualquier SVG sirve de máscara, y su forma puede ser arbitrariamente compleja sin escribir una sola coordenada.

.texturado {
  background: linear-gradient(in oklch, #89b4fa, #f38ba8);
  mask-image: url(pincelada.png);
  mask-size: cover;
  mask-repeat: no-repeat;
}

Composición de varias regiones. mask-composite combina capas de máscara con las operaciones de conjuntos, y eso permite construir regiones —un anillo, un marco, la diferencia de dos formas— que ninguna forma básica describe.

Lo que solo puede el recorte

Aceptar eventos de puntero solo dentro de la forma. Un elemento recortado con clip-path no responde al clic fuera de la región recortada: la detección de impacto respeta el recorte. Con mask, en cambio, la caja sigue entera a efectos de eventos, y un elemento enmascarado a la mitad sigue interceptando clics en la parte invisible.

Esa diferencia es la que decide en un montón de casos. Una tarjeta con la esquina cortada en diagonal recortada con clip-path deja pasar el clic a lo que hay debajo en la esquina; enmascarada, lo intercepta. La primera es casi siempre la que quieres.

Describirse con geometría y no con una imagen. Una forma en clip-path es una expresión que el motor evalúa; una máscara es una imagen que hay que generar y almacenar. Para una forma simple, el recorte gasta menos memoria y menos ancho de banda.

El coste

Los dos son operaciones sobre el resultado del pintado y los dos obligan a componer el elemento aparte, así que ninguno es gratis. Pero no cuestan lo mismo.

Un clip-path con una forma básica se evalúa analíticamente contra cada píxel del borde. No hay nada que almacenar y la región interior no requiere ninguna operación por píxel.

Una mask requiere generar el mapa de píxeles de la máscara, con su propio coste de rasterización si es un degradado o su propia descarga si es una imagen, guardarlo en memoria, y después multiplicarlo canal a canal contra el elemento. Es más trabajo y más memoria.

La regla que se deriva: si la forma es geométrica y los bordes son duros, usa clip-path. Reserva mask para lo que de verdad necesita alfa intermedio.

ℹ️
Los dos crean contexto de apilamiento, y ninguno crea bloque contenedor

Tanto clip-path como mask con valor distinto del inicial crean contexto de apilamiento. Ninguno de los dos crea bloque contenedor para descendientes con position: fixed, cosa que filter sí hace. Si estás depurando un elemento fijo que se ha quedado atrapado, el sospechoso es filter o transform, no el recorte.

Los dos ocultan sin quitar, y eso convierte cualquier interacción oculta en un fallo de accesibilidad

La consecuencia que más caro sale de que estas dos propiedades operen al final del pintado es que no cambian nada del documento. Un botón recortado fuera de la región visible o enmascarado a alfa cero sigue estando en el árbol de accesibilidad, sigue recibiendo el foco al tabular, y sigue siendo anunciado por un lector de pantalla. La diferencia entre las dos empeora el asunto en lugar de aclararlo: con clip-path el elemento tampoco es clicable en esa zona, así que un usuario de teclado puede recibir el foco en un control que no ve y que tampoco podría activar con el ratón aunque lo viera; con mask el control es invisible pero perfectamente clicable, lo cual es todavía peor porque crea una trampa. Los dos casos son el mismo fallo de fondo: se ha usado una herramienta de presentación para expresar disponibilidad. Y aparece con una frecuencia sorprendente, porque el patrón “recorto el contenedor para que solo se vea una parte” es la forma natural de hacer un carrusel, un acordeón o un panel deslizante, y en los tres hay controles dentro de la parte oculta. Las defensas son concretas y hay que aplicarlas siempre que se recorte contenido interactivo. Para lo que está temporalmente fuera de vista pero sigue en el flujo, inert en el contenedor quita el foco y las interacciones de todo el subárbol de una vez, que es exactamente la semántica que querías. Para lo que no debe existir mientras no se vea, display: none o el atributo hidden. Y si el recorte es puramente decorativo y no oculta nada interactivo, no hace falta nada, pero hay que haberlo comprobado, porque el día que alguien meta un enlace en esa esquina nadie va a acordarse de que estaba recortada. La prueba de un minuto es tabular por el componente con los ojos cerrados y ver dónde acaba el foco.

⚔️ Elige con criterio
  1. Recorta una esquina en diagonal con clip-path y con mask y comprueba dónde se puede hacer clic.
  2. Haz un desvanecimiento del final de una lista e intenta reproducirlo con clip-path.
  3. Enmascara un degradado con un PNG con alfa y mira el resultado.
  4. Tabula por un carrusel con contenido recortado y busca el foco perdido.
  5. Aplica inert al contenedor oculto y vuelve a tabular.