Photo by Balázs Kétyi on Unsplash · 25/8/2021
Cuando trabajamos con imágenes de tipo SVG vemos que en algunos casos no tienen por qué comportarse como las imágenes rasterizadas como JPEG, GIF, PNG, etc.
A diferencia de las imágenes rasterizadas que tienen un aspect ratio implícito definido por la matriz de píxeles que conforman la imagen, los SVGs pueden no tener definido un aspect ratio específico. En este caso podríamos decir que los documentos de tipo SVG tienen un comportamiento similar al de un <iframe>
y no tienen por qué ajustarse al tamaño del contenedor.
Un SVG no se comporta como el resto de imágenes, sin embargo, la especificación define una serie de propiedades que pueden configurarse para definir un aspect ratio y facilitar el renderizado en el browser.
La especificación de SVG indica que pueden añadirse 2 atributos width
y height
al SVG.
<svg version="1.1" width="120" height="120">
Sin profundizar, estas propiedades definen el tamaño del documento SVG pero no garantizan que la imagen se vaya a ajustar a esos tamaños en todos los browsers.
Para garantizar que un SVG se escale como esperamos, tenemos que definir la propiedad viewBox
.
Esta propiedad se especifica como un atributo del tag SVG y define varias cosas:
<svg version="1.1" viewBox="0 0 32 32">
La propiedad viewBox
es la que hará que nuestro SVG se escale de una manera similar a como lo hace una imagen rasterizada
A la hora de trabajar con SVGs en ReactJS tenemos varias opciones con sus pros y sus contras.
Una de las opciones, quizá la mas directa, es importar los SVG dentro de un tag <img>
.
Usando el tag <img>
conseguiremos:
loading=“lazy”
para que no se cargue el SVG hasta que entre dentro del viewport.Sin embargo, al importar un SVG de esta manera también tenemos un contra:
fill
. Sin embargo, podemos usar los filtros CSS para cambiar algún color.Si importamos el SVG inline, es decir, usando un tag <svg>
tendremos acceso a sus propiedades de color, lo que nos permitirá:
fill
y color
.Por contra:
Ya hemos visto que los SVG se pueden importar de dos maneras diferentes: Inline y en un <img>
. Ambas con sus pros y sus contras.
A continuación vamos a ver cómo podemos configurar nuestro proyecto de ReactJS con Webpack para importar los SVG.
El plugin @svgr/webpack nos va facilitar importar los SVGs de las dos maneras que hemos visto anteriormente, inline y como una URL para usar en un tag <img>
.
Lo primero de todo es instalar las dependencias, verás que hemos añadido file-loader, es probable que ya lo tengas en tu proyecto, pero por si acaso.
npm i -D @svgr/webpack file-loader
A continuación vamos a añadir un loader a Webpack para que se encargue de los ficheros .svg
. Abrimos el fichero de configuración de Webpack y añadimos lo siguiente:
{
test: /\.svg$/,
use: [
// Inserts the SVG inline.
'@svgr/webpack',
// Generates a URL to insert the SVG as an image.
{
loader: 'file-loader',
// Defines an output hash for cache.
options: {
outputPath: './assets/',
name: '[name]-[hash].[ext]'
}
}
]
}
Tras haber configurado Webpack, ya podremos importar una imagen SVG dentro de nuestros componentes de ReactJS.
A continuación vamos a importar el SVG de las dos maneras que hemos comentado.
// default import (svgImage) is going to be a URL.
// ReactComponent is a ReactJS component to be used inline.
import svgImage, { ReactComponent as MySVGComponent } from "demo-image.svg";
Ahora ya podremos usar nuestro SVG de la forma que más se ajuste a nuestras necesidades.
function demoComponent() {
return (
<>
{/** SVG inserted as an inline */}
<img
src={svgImage}
alt="Add a descriptive alternative text, this is usefull for blind people"
/>
{/** SVG inserted inline as a ReactComponent. */}
<ReactComponent style=\{\{ color: black \}\} />
</>
);
}
Cualquiera de las dos opciones de importación es válida a la hora de inyectar un SVG en nuestra aplicación ReactJS. Dependerá de cuáles sean nuestras necesidades.
Si queremos modificar el SVG usando CSS es mejor que lo importemos inline, por ejemplo para iconos.
Si se trata de una imagen tipo ilustración cuyos colores no se van a modificar, puedes importarlo dentro del tag <img>
Usando el plugin @svgr/webpack
puedes cambiar fácilmente de una opción a otra.
· Adrián Gómez
Powered by Astro + TailwindCSS + Markdown