SVG y canvas en HTML
En esta lección
HTML no solo sirve para texto e imágenes ya hechas: también puedes dibujar. Hay dos tecnologías para ello, y aunque a simple vista parecen hacer lo mismo, funcionan de formas muy distintas. SVG describe el dibujo con etiquetas, como si fuera HTML. Canvas es un lienzo en blanco en el que pintas píxeles con JavaScript. En esta lección aprenderás lo básico de las dos y, sobre todo, a elegir bien.
Qué es SVG
SVG (Scalable Vector Graphics) es un formato de imágenes vectoriales. En vez de guardar píxeles, guarda instrucciones: “un círculo aquí, de este radio, de este color”. Por eso:
- Se ve nítido a cualquier tamaño. Da igual que lo muestres a 16 píxeles o a 1600: el navegador lo vuelve a dibujar.
- Pesa muy poco cuando el dibujo es sencillo (iconos, logos, gráficos).
- Es texto. Lo puedes escribir a mano, editar, comprimir y cambiar con CSS o JavaScript.
Un SVG se puede escribir directamente dentro del HTML. A esto se le llama SVG en línea:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="orange" />
</svg>
Esto dibuja un círculo naranja. Cada figura es un elemento, igual que un <p> o un <img>.
El sistema de coordenadas y viewBox
En SVG, el punto (0, 0) está en la esquina superior izquierda. La x crece hacia la derecha y la y crece hacia abajo (al revés que en matemáticas).
El atributo viewBox="minX minY ancho alto" define el área de dibujo interna, es decir, qué coordenadas hay dentro del SVG. width y height definen el tamaño con el que se muestra en la página.
<!-- Se dibuja en un espacio de 100 x 100 unidades... -->
<!-- ...pero se muestra a 300 x 300 píxeles: todo se escala x3 -->
<svg viewBox="0 0 100 100" width="300" height="300">
<circle cx="50" cy="50" r="40" fill="orange" />
</svg>
Gracias a viewBox, puedes cambiar el tamaño del SVG (con width, height o CSS) sin tocar ninguna coordenada. Es lo que hace que un SVG sea realmente escalable.
Consejo: pon siempre
viewBox. Sin él, el dibujo no se escala y, si cambias el tamaño, se recorta.
Las figuras básicas
Rectángulo: <rect>
<rect x="10" y="10" width="80" height="40" rx="6" fill="#2563eb" />
x e y son la esquina superior izquierda. rx redondea las esquinas.
Círculo: <circle>
<circle cx="50" cy="50" r="20" fill="tomato" />
cx y cy son el centro; r, el radio. Para óvalos existe <ellipse> con rx y ry.
Línea: <line>
<line x1="0" y1="0" x2="100" y2="50" stroke="black" stroke-width="2" />
Una línea va de (x1, y1) a (x2, y2). Como no tiene relleno, necesita stroke para verse.
Texto: <text>
<text x="10" y="30" font-size="16" fill="#333">Vía 12 · 6b</text>
La y marca la línea base del texto, no su parte de arriba. Si pones y="0", el texto queda fuera, por encima.
Trazados: <path>
<path> es la figura más potente: dibuja cualquier forma con una lista de órdenes en el atributo d. Las más básicas:
| Orden | Significado |
|---|---|
M x y | Move: mueve el lápiz sin dibujar |
L x y | Line: dibuja una línea hasta ese punto |
H x / V y | Línea horizontal o vertical |
Z | Cierra la figura volviendo al inicio |
<!-- Un triángulo (una montaña) -->
<path d="M 10 90 L 50 20 L 90 90 Z" fill="#475569" />
También hay órdenes para curvas (C, Q, A), pero rara vez se escriben a mano: los programas de diseño como Figma o Inkscape las generan por ti.
Relleno y borde: fill y stroke
| Atributo | Qué hace |
|---|---|
fill | Color de relleno. none lo deja hueco |
stroke | Color del borde |
stroke-width | Grosor del borde |
stroke-linecap | Forma de los extremos: butt, round, square |
opacity | Transparencia de 0 a 1 |
Estas propiedades también se pueden poner en CSS cuando el SVG está en línea:
.icono circle { fill: #16a34a; }
.icono:hover circle { fill: #15803d; }
Tres formas de usar un SVG
1. Como imagen con <img>
Si tienes un archivo logo.svg, lo usas como cualquier otra imagen:
<img src="img/logo.svg" alt="Club Vertical" width="160" height="40">
Es lo más sencillo y el navegador lo guarda en caché. A cambio, no puedes cambiar sus colores con el CSS de tu página ni tocarlo con JavaScript.
2. En línea, dentro del HTML
Pegas el código <svg> directamente. Puedes darle estilos, animarlo y cambiarlo con JavaScript, pero engorda el HTML y no se cachea aparte.
3. Como fondo en CSS
.aviso { background-image: url("img/alerta.svg"); }
Útil para adornos que no aportan información.
Iconos accesibles
Un icono SVG en línea puede ser decorativo o transmitir información:
<!-- Decorativo: acompaña a un texto que ya lo dice todo -->
<button type="button">
<svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16">
<path d="M4 12 L10 18 L20 6" fill="none" stroke="currentColor" stroke-width="3" />
</svg>
Guardar
</button>
<!-- Informativo: es lo único que hay -->
<svg role="img" aria-labelledby="t-ok" viewBox="0 0 24 24" width="24" height="24">
<title id="t-ok">Completado</title>
<path d="M4 12 L10 18 L20 6" fill="none" stroke="currentColor" stroke-width="3" />
</svg>
El valor currentColor hace que el icono tome el color del texto que lo rodea. Así, si el botón cambia de color, el icono también.
Canvas: un lienzo para JavaScript
<canvas> es un rectángulo de píxeles vacío. En HTML solo lo declaras; todo el dibujo se hace con JavaScript:
<canvas id="grafico" width="300" height="150">
Gráfico de asistencia semanal: lunes 12, martes 20, miércoles 15.
</canvas>
El texto de dentro solo se muestra si el navegador no puede pintar el canvas, y también lo pueden leer las tecnologías de apoyo. Aprovéchalo para describir lo que se dibuja.
Cuidado: da el tamaño con los atributos
widthyheight, no solo con CSS. Si solo usas CSS, el lienzo interno sigue midiendo 300 x 150 y el dibujo se ve estirado y borroso.
Dibujar con el contexto 2D
Para dibujar necesitas el contexto, el objeto que tiene todos los métodos de pintura:
const lienzo = document.querySelector('#grafico');
const ctx = lienzo.getContext('2d');
// Un rectángulo relleno: x, y, ancho, alto
ctx.fillStyle = '#2563eb';
ctx.fillRect(20, 30, 60, 100);
// Un rectángulo solo con borde
ctx.strokeStyle = '#dc2626';
ctx.lineWidth = 3;
ctx.strokeRect(100, 30, 60, 100);
// Un círculo: centro x, centro y, radio, ángulo inicial, ángulo final
ctx.beginPath();
ctx.arc(230, 80, 40, 0, Math.PI * 2);
ctx.fillStyle = '#16a34a';
ctx.fill();
// Texto
ctx.fillStyle = '#111';
ctx.font = '16px sans-serif';
ctx.fillText('Asistencia', 20, 20);
Fíjate en el círculo: arc trabaja en radianes, y una vuelta completa son Math.PI * 2. Antes de cada figura nueva con trazados, llama a beginPath(); si no, se mezcla con la anterior.
La idea clave de canvas es que no recuerda lo que has dibujado. Una vez pintado un rectángulo, solo quedan píxeles. Si quieres moverlo, tienes que borrar (ctx.clearRect(0, 0, ancho, alto)) y volver a pintarlo todo en su nueva posición. Así funcionan las animaciones y los juegos.
¿SVG o canvas?
| SVG | Canvas | |
|---|---|---|
| Qué es | Figuras descritas con etiquetas | Píxeles pintados con JavaScript |
| Escala | Nítido a cualquier tamaño | Se pixela al ampliarlo |
| Cada figura | Es un elemento del DOM (CSS, eventos, accesible) | No existe: solo hay píxeles |
| Rendimiento | Va peor con miles de figuras | Aguanta miles de objetos por fotograma |
| Ideal para | Iconos, logos, mapas, gráficos simples, ilustraciones | Juegos, animaciones complejas, edición de fotos, visualizaciones con muchísimos datos |
Regla práctica: empieza por SVG. Pásate a canvas cuando tengas tantos elementos o tanto movimiento que el SVG vaya lento, o cuando necesites manipular píxeles (filtros de imagen, dibujo libre).
Errores frecuentes
- Olvidar el
viewBox. El SVG no se escala y se recorta al cambiar su tamaño. - Una
<line>sinstroke. No se ve nada, porque las líneas no tienen relleno. - Pensar que la
ycrece hacia arriba. En SVG y en canvas crece hacia abajo. - Dar tamaño al canvas solo con CSS. El dibujo sale deformado. Usa los atributos
widthyheight. - Olvidar
beginPath()en canvas. Las figuras se enlazan entre sí de forma inesperada. - Iconos SVG mudos. Si el icono es lo único que hay en un botón, necesita un texto accesible (
<title>,aria-labelo texto oculto).
Resumen
- SVG describe dibujos vectoriales con etiquetas:
<rect>,<circle>,<line>,<path>,<text>. viewBoxdefine el sistema de coordenadas interno y permite escalar el dibujo.fillrellena,strokedibuja el borde; ambos se pueden poner con CSS.- Un SVG se usa con
<img>(sencillo), en línea (se puede tocar con CSS y JS) o como fondo CSS. - Canvas es un lienzo de píxeles:
getContext('2d'),fillRect,arc,fillText. - Usa SVG para iconos y gráficos; canvas para juegos, animaciones pesadas y edición de imagen.
Si quieres repasar cómo se insertan imágenes normales, vuelve a imágenes en HTML. Y para sacar partido a canvas necesitarás JavaScript: empieza por el DOM.
Pruébalo tú
Cambia el código y pulsa Ejecutar (o Ctrl + Enter).
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.