Saltar al contenido
svg-y-canvas.html · devschool

SVG y canvas en HTML

Lección 19 de 23 · 9 min de lectura · Actualizado el

En esta lección
  1. Qué es SVG
  2. El sistema de coordenadas y viewBox
  3. Las figuras básicas
  4. Relleno y borde: fill y stroke
  5. Tres formas de usar un SVG
  6. Canvas: un lienzo para JavaScript
  7. ¿SVG o canvas?
  8. Errores frecuentes
  9. Resumen

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:

OrdenSignificado
M x yMove: mueve el lápiz sin dibujar
L x yLine: dibuja una línea hasta ese punto
H x / V yLínea horizontal o vertical
ZCierra 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

AtributoQué hace
fillColor de relleno. none lo deja hueco
strokeColor del borde
stroke-widthGrosor del borde
stroke-linecapForma de los extremos: butt, round, square
opacityTransparencia 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 width y height, 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?

SVGCanvas
Qué esFiguras descritas con etiquetasPíxeles pintados con JavaScript
EscalaNítido a cualquier tamañoSe pixela al ampliarlo
Cada figuraEs un elemento del DOM (CSS, eventos, accesible)No existe: solo hay píxeles
RendimientoVa peor con miles de figurasAguanta miles de objetos por fotograma
Ideal paraIconos, logos, mapas, gráficos simples, ilustracionesJuegos, 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> sin stroke. No se ve nada, porque las líneas no tienen relleno.
  • Pensar que la y crece 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 width y height.
  • 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-label o texto oculto).

Resumen

  • SVG describe dibujos vectoriales con etiquetas: <rect>, <circle>, <line>, <path>, <text>.
  • viewBox define el sistema de coordenadas interno y permite escalar el dibujo.
  • fill rellena, stroke dibuja 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).

svg-y-canvas.html
Resultado

Pon a prueba lo que has aprendido

[HTML] ¿Por qué no se ve nada en este SVG?
<svg viewBox="0 0 100 100" width="100" height="100">
  <line x1="0" y1="50" x2="100" y2="50" />
</svg>

[HTML] Un SVG tiene viewBox="0 0 50 50" y lo muestras con width="200" height="200". ¿Qué pasa con un círculo de r="10"?

[HTML] Vas a hacer un juego con cientos de enemigos moviéndose a 60 fotogramas por segundo. ¿Qué eliges?

[HTML] ¿Qué dibuja este código?
const ctx = lienzo.getContext('2d');
ctx.beginPath();
ctx.arc(50, 50, 20, 0, Math.PI * 2);
ctx.fill();

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.