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>