Haga clic en Elemento SVG para enfocar (y estilo) | Programar Plus

Un lector escribe en:

¿Hay algo en su sitio que me muestre cómo hacer que se pueda hacer clic en un SVG usando CSS? Como en, tengo un SVG y hago clic en parte de él y debería revelar un contorno en esa parte del elemento. Tengo una entrevista telefónica el martes para un trabajo como ilustrador SVG remoto y no quiero parecer un pavo.

Di que tengo un <svg> de los Estados Unidos y es así:

<svg class="us" viewBox="0 0 500 400">

  <path d="..." class="wisconsin" />

  <polygon points="..." class="colorado" />

  <g class="michigan">
    <path d="..." class="michigan--up">
    <path d="..." class="michigan--main">
  </g>

  <!-- etc -->

</svg>

Cada estado entonces es una especie de descendiente directo del <svg>, el selector sería svg.us > *.

Por lo general, cuando pienso en “se puede hacer clic”, pienso en JavaScript. Así es como podríamos observar los clics en cada estado. También aplicaremos una clase al estado en el que se hizo clic:

var allStates = $("svg.us > *");

allStates.on("click", function() {
  
  allStates.removeClass("on");
  $(this).addClass("on");
  
});

Esa clase hará el estilo por nosotros. Mencionaste un contorno, así que hagámoslo y también un color de relleno:

.on {
  fill: pink;
  stroke: red;
  stroke-width: 2;
}

¡Tada!

Vea el Estado del clic del lápiz para activar por Chris Coyier (@chriscoyier) en CodePen.

Pero DIJISTE específicamente “se puede hacer clic usando CSS”. Eso es un poco más complicado. Normalmente tenemos :focus en CSS, pero no creo que haya ninguna forma comprobada de hacer que un elemento SVG sea enfocable. Se habló (hace mucho tiempo) de una focusable atributo, pero creo que eso está fuera. La forma HTML es tabindex, que creo que funciona en algunos navegadores, pero no podemos contar con eso. Creo que la mejor manera es usar anclas en SVG (sí, ¡también podemos usarlas en SVG!) que se pueden enfocar en todos los navegadores. Luego aplica el :focus estilo al ancla que cae en cascada en las formas.

Amelia Bellamy-Royds hizo exactamente esto en un hilo de StackOverflow. Aquí está mi versión ligeramente simplificada:

<svg viewBox="0 0 95 50">
  <a xlink:href="https://css-tricks.com/click-svg-to-focus/#0">
    <circle cx="20" cy="25" r="5" data-Name="shape 1" data-tabindex="0" />
  </a>
  <a xlink:href="https://css-tricks.com/click-svg-to-focus/#0">
    <circle cx="40" cy="25" r="5" data-Name="shape 2" data-tabindex="0" />
  </a>
  <a xlink:href="https://css-tricks.com/click-svg-to-focus/#0">
    <circle cx="60" cy="25" r="5" data-Name="shape 3" data-tabindex="0" />
  </a>
  <a xlink:href="https://css-tricks.com/click-svg-to-focus/#0">
    <circle cx="80" cy="25" r="5" data-Name="shape 4" data-tabindex="0" />
  </a>
</svg>
a:focus {
  fill: pink;
  stroke: red;
  stroke-width: 1;
}

Deberias hacer eso:

Vea el Pen SVG con elementos enfocables de Chris Coyier (@chriscoyier) en CodePen.