Gestión de la interacción SVG con la propiedad Pointer Events
Publicado: 2022-03-10pointer-events
.Intente hacer clic o tocar la imagen SVG a continuación. Si coloca el puntero en el lugar correcto (la ruta sombreada), debería tener la página de inicio de Smashing Magazine abierta en una nueva pestaña del navegador. Si intentaste hacer clic en un espacio en blanco, es posible que estés realmente confundido.
Vea el Pen Amethyst de Tiffany Brown (@webinista) en CodePen.
Este es el dilema al que me enfrenté durante un proyecto reciente que incluía enlaces dentro de imágenes SVG. A veces, cuando hacía clic en la imagen, el enlace funcionaba. Otras veces no. confuso, ¿verdad?
Recurrí a la especificación SVG para obtener más información sobre lo que podría estar sucediendo y si SVG ofrece una solución. La respuesta: pointer-events
.
No debe confundirse con los eventos de puntero DOM ( D ocument O bject M odel), pointer-events
es tanto una propiedad CSS como un atributo de elemento SVG. Con él, podemos administrar qué partes de un documento o elemento SVG pueden recibir eventos de un dispositivo señalador, como un mouse, un trackpad o un dedo.
Una nota sobre la terminología: "eventos de puntero" es también el nombre de una función de plataforma web independiente del dispositivo para la entrada del usuario. Sin embargo, en este artículo, y para los fines de la propiedad pointer-events
, la frase "eventos de puntero" también incluye eventos táctiles y de mouse.
Fuera de la caja: "Modelo de forma" de SVG
El uso de CSS con HTML impone un modelo de diseño de cuadro en HTML. En el modelo de diseño de caja, cada elemento genera un rectángulo alrededor de su contenido. Ese rectángulo puede estar en línea, nivel en línea, nivel atómico en línea o bloque, pero sigue siendo un rectángulo con cuatro ángulos rectos y cuatro bordes. Cuando agregamos un enlace o un detector de eventos a un elemento, el área interactiva coincide con las dimensiones del rectángulo.
Nota : Agregar una clip-path
a un elemento interactivo altera sus límites interactivos. En otras palabras, si agrega una clip-path
hexagonal a a
elemento, solo se podrá hacer clic en los puntos dentro de la ruta de recorte. De manera similar, agregar una transformación de sesgo convertirá los rectángulos en romboides.
SVG no tiene un modelo de diseño de caja. Verá, cuando un documento SVG está contenido en un documento HTML, dentro de un diseño CSS, el elemento SVG raíz se adhiere al modelo de diseño de cuadro. Sus elementos secundarios no lo hacen. Como resultado, la mayoría de las propiedades relacionadas con el diseño de CSS no se aplican a SVG.
Entonces, en cambio, SVG tiene lo que llamaré un 'modelo de forma'. Cuando agregamos un enlace o un detector de eventos a un elemento o documento SVG, el área interactiva no será necesariamente un rectángulo. Los elementos SVG tienen un cuadro delimitador. El cuadro delimitador se define como: el rectángulo de ajuste más ajustado alineado con los ejes del sistema de coordenadas de usuario de ese elemento que lo encierra por completo a él y a sus descendientes.
Pero inicialmente, qué partes de un documento SVG son interactivas depende de qué partes estén visibles y/o pintadas .
Elementos pintados vs. visibles
Los elementos SVG se pueden "rellenar", pero también se pueden "trazar". El relleno se refiere al interior de una forma. El trazo se refiere a su contorno.
Juntos, "rellenar" y "trazar" son operaciones de pintura que representan elementos en la pantalla o página (también conocida como lienzo ). Cuando hablamos de elementos pintados , nos referimos a que el elemento tiene un relleno y/o un trazo. Por lo general, esto significa que el elemento también está visible.
Sin embargo, un elemento SVG puede pintarse sin ser visible. Esto puede suceder si el valor del atributo visible
o la propiedad CSS están hidden
o cuando no se display
none
. El elemento está ahí y ocupa un espacio teórico. Simplemente no podemos verlo (y es posible que la tecnología de asistencia no lo detecte).
Quizás de manera más confusa, un elemento también puede ser visible, es decir, tener un valor de visibility
calculado de visible
, sin ser pintado. Esto sucede cuando los elementos carecen tanto de un trazo como de un relleno.
Nota : los valores de color con transparencia alfa (p. ej rgba(0,0,0,0)
) no afectan si un elemento está pintado o visible. En otras palabras, si un elemento tiene un relleno o un trazo alfa transparente, se pinta aunque no se pueda ver.
Saber cuándo un elemento está pintado, visible o ninguno de los dos es crucial para comprender el impacto de cada valor pointer-events
.
Todo o nada o algo intermedio: los valores
pointer-events
es tanto una propiedad CSS como un atributo de elemento SVG. Su valor inicial es auto
, lo que significa que solo las partes pintadas y visibles recibirán eventos de puntero. La mayoría de los demás valores se pueden dividir en dos grupos:
- Valores que requieren que un elemento sea visible; y
- Valores que no.
painted
, fill
, stroke
, y all
caen en la última categoría. Sus contrapartes dependientes de la visibilidad ( visiblePainted
, visibleFill
, visibleStroke
y visible
) caen en el primero.
La especificación SVG 2.0 también define un valor bounding-box
. Cuando el valor de pointer-events
es bounding-box
, el área rectangular alrededor del elemento también puede recibir eventos de puntero. Al momento de escribir este artículo, solo Chrome 65+ admite el valor bounding-box
.

none
también es un valor válido. Evita que el elemento y sus hijos reciban eventos de puntero. La propiedad CSS pointer-events
también se puede usar con elementos HTML. Pero cuando se usa con HTML, solo auto
y none
son valores válidos.
Dado que los valores pointer-events
se demuestran mejor que se explican, veamos algunas demostraciones.
Aquí tenemos un círculo con un relleno y un trazo aplicado. Es a la vez pintado y visible . Todo el círculo puede recibir eventos de puntero, pero el área fuera del círculo no.
Vea el lápiz visible frente al pintado en SVG por Tiffany Brown (@webinista) en CodePen.
Deshabilite el relleno, para que su valor sea none
. Ahora, si intenta pasar el mouse, hacer clic o tocar el interior del círculo, no sucede nada. Pero si hace lo mismo para el área del trazo, los eventos de puntero aún se envían. Cambiar el valor de fill
a none
significa que esta área es visible , pero no pintada .
Hagamos un pequeño cambio en nuestro marcado. Agregaremos pointer-events="visible"
a nuestro elemento de circle
, mientras mantenemos fill=none
.
Vea el Pen Cómo agregar eventos de puntero: todo afecta la interactividad por Tiffany Brown (@webinista) en CodePen.
Ahora, el área sin pintar rodeada por el trazo puede recibir eventos de puntero.
Aumento del área en la que se puede hacer clic de una imagen SVG
Volvamos a la imagen del principio de este artículo. Nuestra "amatista" es un elemento de path
, a diferencia de un grupo de polígonos, cada uno con un stroke
y un fill
. Eso significa que no podemos simplemente agregar pointer-events="all"
y llamarlo un día.
En cambio, necesitamos aumentar el área de clic. Usemos lo que sabemos sobre elementos pintados y visibles. En el siguiente ejemplo, agregué un rectángulo a nuestro marcado de imagen.
Vea el lápiz que aumenta el área de clic de una imagen SVG de Tiffany Brown (@webinista) en CodePen.
Aunque este rectángulo no se ve, sigue siendo técnicamente visible (es decir, visibility: visible
). Su falta de relleno, sin embargo, significa que no está pintado . Nuestra imagen se ve igual. De hecho, todavía funciona igual: hacer clic en el espacio en blanco aún no activa una operación de navegación. Todavía necesitamos agregar un atributo pointer-events
a nuestro a
. El uso de los valores visible
o all
funcionará aquí.
Vea el lápiz que aumenta el área de clic de una imagen SVG de Tiffany Brown (@webinista) en CodePen.
Ahora toda la imagen puede recibir eventos de puntero.
El uso bounding-box
eliminaría la necesidad de un elemento fantasma. Todos los puntos dentro del cuadro delimitador recibirían eventos de puntero, incluido el espacio en blanco encerrado por la ruta. Pero nuevamente: pointer-events="bounding-box"
no es ampliamente compatible. Hasta que lo esté, podemos utilizar elementos sin pintar.
Uso pointer-events
al mezclar SVG y HTML
Otro caso en el que pointer-events
pueden ser útiles: usar SVG dentro de un botón HTML.
Vea el Pen Ovxmmy de Tiffany Brown (@webinista) en CodePen.
En la mayoría de los navegadores (Firefox e Internet Explorer 11 son excepciones aquí), el valor de event.target
será un elemento SVG en lugar de nuestro botón HTML. Agreguemos pointer-events="none"
a nuestra etiqueta SVG de apertura.
Vea los eventos de puntero Pen How: ninguno se puede usar con SVG y HTML por Tiffany Brown (@webinista) en CodePen.
Ahora, cuando los usuarios hagan clic o toquen nuestro botón, event.target
se referirá a nuestro button
.
Los expertos en DOM y JavaScript notarán que el uso de la palabra clave de function
en lugar de una función de flecha y this
en lugar de event.target
soluciona este problema. Sin embargo, usar pointer-events="none"
(o pointer-events: none;
en su CSS) significa que no tiene que guardar esa particular peculiaridad de JavaScript en la memoria.
Conclusión
SVG admite el mismo tipo de interactividad al que estamos acostumbrados con HTML. Podemos usarlo para crear gráficos que respondan a clics o toques. Podemos crear áreas vinculadas que no se adhieren al modelo de cuadro CSS y HTML. Y con la adición de pointer-events
, podemos mejorar la forma en que nuestros documentos SVG se comportan en respuesta a la interacción del usuario.
El soporte del navegador para pointer-events
SVG es robusto. Todos los navegadores que admiten SVG admiten la propiedad para documentos y elementos SVG. Cuando se usa con elementos HTML, el soporte es un poco menos robusto. No está disponible en Internet Explorer 10 o sus predecesores, ni en ninguna versión de Opera Mini.
Acabamos de arañar la superficie de pointer-events
en esta pieza. Para un tratamiento técnico más profundo, lea la Especificación SVG. MDN (Mozilla Developer Network) Web Docs ofrece más documentación amigable para desarrolladores web para pointer-events
, completa con ejemplos.