Estilos CSS y Javascript

La etiqueta <style> y <script>


Hasta ahora, en prácticamente todos los casos, hemos utilizado atributos en nuestro código SVG para indicar características, incluso para las características de estilo o de presentación, como fill o stroke.

Sin embargo, muchos de estos atributos es posible utilizarlos desde CSS, por lo que puede interesarnos a la hora de simplificar código. Observemos el siguiente ejemplo, donde utilizamos algunos atributos de presentación en el propio código HTML:

<svg viewBox="0 0 50 50" height="300" style="background: grey">
  <rect x="15" y="15" width="20" height="20"
        stroke="deeppink" stroke-width="1" fill="indigo" />
</svg>

Todos están definidos como atributos en la propiedad etiqueta que le corresponde. Veamos formas alternativas de hacer esto.

La etiqueta <style>

Este SVG se puede reescribir de otra forma equivalente, utilizando la etiqueta <style>. Dicha etiqueta, permite definir en su interior estilos de presentación que antes aplicabamos a sus elementos en format de atributo, y que ahora podemos hacerlo en forma de propiedad CSS, aplicada a su correspondiente etiqueta:

<svg viewBox="0 0 50 50">
  <style>
    svg {
      height: 300px;
      background: grey;
    }
    rect {
      stroke: deeppink;
      stroke-width: 1px;
      fill: indigo;
    }
  </style>
  <rect x="15" y="15" width="20" height="20" />
</svg>

Puede parecer en este ejemplo que esta forma no es interesante, puesto que se ve más código y quizás más complejo de leer. Sin embargo, cuando el código SVG tiene más elementos, puede ser más interesante usar el bloque de <style>, ya que aplicamos los estilos a múltiples elementos del mismo tipo de una sola vez, sin necesidad de repetirlos.

En el siguiente ejemplo, el bloque <style> le da estilo a 5 elementos <rect>:

<svg viewBox="0 0 50 50">
  <style>
    svg {
      height: 300px;
      background: grey;
    }
    rect {
      stroke: deeppink;
      stroke-width: 1px;
      fill: indigo;
      animation: spin 1s infinite;
      transform-origin: 50% 50%;
    }
    @keyframes spin {
      from { transform: rotate(0); }
      to { transform: rotate(360deg); }
    }
  </style>

  <rect x="5" y="35" width="10" height="10" />
  <rect x="35" y="5" width="10" height="10" />
  <rect x="15" y="15" width="20" height="20" />
  <rect x="35" y="35" width="10" height="10" />
  <rect x="5" y="5" width="10" height="10" />
</svg>

Recuerda que ya hemos visto que existe una forma de utilizar grupos SVG con la etiqueta <g>, de modo que se apliquen los atributos a todos los miembros agrupados en su interior, sin necesidad de utilizar el <style>. Utiliza la que más cómoda sea en cada caso:

<svg viewBox="0 0 50 50">
  <style>
    svg {
      height: 300px;
      background: grey;
    }
  </style>
  <g stroke="deeppink" stroke-width="1" fill="indigo">
    <rect x="5" y="35" width="10" height="10" />
    <rect x="35" y="5" width="10" height="10" />
    <rect x="15" y="15" width="20" height="20" />
    <rect x="35" y="35" width="10" height="10" />
    <rect x="5" y="5" width="10" height="10" />
  </g>
</svg>

La etiqueta <script>

De la misma forma que ocurre con los estilos, podemos utilizar una etiqueta <script> para añadir código Javascript en nuestro SVG. Si la imagen va a ser renderizada en un navegador, este conoce Javascript y por lo tanto puede trabajar con él, e incluso acceder a su propio DOM y trabajar con los elementos, atributos y sus valores.

El siguiente ejemplo, accede a cada uno de los cuadrados del SVG y haciendo uso del DOM, cada vez que el usuario pinche en uno de ellos, te dirá sus coordenadas y su tamaño en forma de alerta de navegador:

<svg viewBox="0 0 50 50">
  <style>
    svg {
      height: 300px;
      background: grey;
    }
  </style>
  <script type="module">
    const rects = [...document.querySelectorAll("rect")];
    rects.forEach(rect => rect.addEventListener("click", () => {
      const x = rect.getAttribute("x");
      const y = rect.getAttribute("y");
      const w = rect.getAttribute("width");
      const h = rect.getAttribute("height");
      alert(`Click en rect: (${x},${y}) -> ${w}x${h}`);
    }));
  </script>
  <g stroke="deeppink" stroke-width="1" fill="indigo">
    <rect x="5" y="35" width="10" height="10" />
    <rect x="35" y="5" width="10" height="10" />
    <rect x="15" y="15" width="20" height="20" />
    <rect x="35" y="35" width="10" height="10" />
    <rect x="5" y="5" width="10" height="10" />
  </g>
</svg>

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev