HTML Graphics
HTML SVG Basics
SVG (Scalable Vector Graphics) lets you draw resolution-independent shapes, icons, charts and illustrations directly in your HTML using plain XML markup. Because SVG is text, it is searchable, styleable with CSS, scriptable with JavaScript, and stays razor-sharp at any zoom level. This page covers what SVG is, how vector graphics differ from raster images, the core shape elements, gradients, and when SVG is the right tool versus the <canvas> element. Every example below is a complete HTML document you can run in the editor.
What is SVG?
SVG is an XML-based markup language for describing two-dimensional vector graphics. Instead of storing a grid of pixels like a JPG or PNG, an SVG stores mathematical descriptions of shapes: "a circle of radius 40 at (60, 60), filled red." The browser renders those descriptions to pixels at draw time, so the picture is recalculated every time it is displayed and never looks blurry, no matter the screen resolution or zoom level.
You can embed SVG in an HTML page three ways: inline (an <svg> element written directly in the HTML, the most flexible because CSS and JS can reach into every shape), as an <img src="logo.svg"> reference, or as a CSS background-image. Inline SVG is used throughout this tutorial.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My First SVG</title>
<style>
body { display: grid; place-items: center; min-height: 100vh; margin: 0; background: #0f172a; }
</style>
</head>
<body>
<svg width="220" height="220" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="#fbbf24" stroke="#b45309" stroke-width="3" />
<circle cx="35" cy="40" r="6" fill="#1e293b" />
<circle cx="65" cy="40" r="6" fill="#1e293b" />
<path d="M30 62 Q50 82 70 62" fill="none" stroke="#1e293b" stroke-width="5" stroke-linecap="round" />
</svg>
</body>
</html>Run this in the Try it Yourself editor and change the fill colours or the radius r. Because SVG is just markup, editing a number instantly redraws the shape.
Vector vs Raster Graphics
| Aspect | Vector (SVG) | Raster (PNG / JPG) |
|---|---|---|
| Stored as | Shapes and math (paths, coordinates) | A grid of coloured pixels |
| Scaling | Infinitely sharp at any size | Blurry / pixelated when enlarged |
| File size | Small for flat shapes, logos, icons | Grows with resolution and detail |
| Editable | Each shape editable via code / CSS / JS | Only whole-pixel editing |
| Accessibility | Real text stays selectable & readable | Text is baked into pixels |
| Best for | Logos, icons, charts, diagrams, line art | Photographs, complex textures |
| Animation | CSS / SMIL / JS per element | Frame-based only |
The <svg> Element and viewBox
Every SVG drawing lives inside an <svg> root element. Two things matter most: the physical display size (width and height, or CSS sizing) and the viewBox, which defines the internal coordinate system. A viewBox of "0 0 100 100" means the drawing canvas is 100 units wide and 100 units tall, and those units are then scaled to whatever CSS size you give the element. Draw in convenient units once, display at any size.
The internal coordinate origin (0, 0) is the TOP-LEFT corner. X grows to the right and Y grows DOWNWARD, the same as most screen graphics.
Rectangles - <rect>
A <rect> is positioned by its top-left corner (x, y) and sized with width and height. The optional rx and ry attributes round the corners. fill paints the interior; stroke and stroke-width draw the outline.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Rectangles</title></head>
<body style="background:#f1f5f9;text-align:center;">
<h2><rect> shapes</h2>
<svg width="360" height="140" viewBox="0 0 360 140" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="20" width="100" height="100" fill="#6366f1" />
<rect x="130" y="20" width="100" height="100" rx="20" ry="20" fill="#ec4899" />
<rect x="250" y="20" width="100" height="100" fill="#22c55e"
stroke="#166534" stroke-width="6" />
</svg>
</body>
</html>Circles and Ellipses - <circle> / <ellipse>
A <circle> is centred at (cx, cy) with radius r. An <ellipse> also centres at (cx, cy) but takes two radii: rx (horizontal) and ry (vertical).
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Circles</title></head>
<body style="background:#0f172a;text-align:center;">
<svg width="360" height="160" viewBox="0 0 360 160" xmlns="http://www.w3.org/2000/svg">
<circle cx="70" cy="80" r="55" fill="#38bdf8" />
<circle cx="180" cy="80" r="55" fill="none" stroke="#f472b6" stroke-width="10" />
<ellipse cx="290" cy="80" rx="60" ry="35" fill="#facc15" />
</svg>
</body>
</html>Lines, Polylines and Polygons
A <line> connects (x1, y1) to (x2, y2) and needs a stroke to be visible. A <polyline> follows a list of points as connected segments (open). A <polygon> takes the same points list but automatically closes back to the start, making a filled shape like a triangle or star.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Lines</title></head>
<body style="background:#f8fafc;text-align:center;">
<svg width="360" height="180" viewBox="0 0 360 180" xmlns="http://www.w3.org/2000/svg">
<line x1="20" y1="20" x2="120" y2="150" stroke="#ef4444" stroke-width="6" stroke-linecap="round" />
<polyline points="140,150 160,40 190,150 220,60 250,150"
fill="none" stroke="#0ea5e9" stroke-width="5" />
<polygon points="310,40 350,150 270,150" fill="#a855f7" stroke="#6b21a8" stroke-width="4" />
</svg>
</body>
</html>Paths - <path>
The <path> element is the most powerful shape. Its single d attribute is a mini-language of drawing commands: M moves the pen, L draws a line, Q and C draw quadratic and cubic Bezier curves, A draws an arc, and Z closes the shape. Every other SVG shape can be expressed as a path, which is why icon sets ship as paths.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Paths</title></head>
<body style="background:#fff1f2;text-align:center;">
<svg width="360" height="200" viewBox="0 0 360 200" xmlns="http://www.w3.org/2000/svg">
<path d="M90 60 C90 30 40 30 40 65 C40 100 90 130 90 150
C90 130 140 100 140 65 C140 30 90 30 90 60 Z"
fill="#e11d48" />
<path d="M180 120 Q210 70 240 120 T300 120 T360 120"
fill="none" stroke="#0891b2" stroke-width="6" stroke-linecap="round" />
</svg>
</body>
</html>Uppercase path commands (M, L, C) use absolute coordinates; lowercase (m, l, c) use coordinates relative to the current pen position.
Text - <text>
The <text> element renders real, selectable characters as vector glyphs at position (x, y), where y is the text baseline. You can style it with font-size, font-family, fill, and text-anchor (start / middle / end) for alignment.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Text</title></head>
<body style="background:#111827;text-align:center;">
<svg width="360" height="140" viewBox="0 0 360 140" xmlns="http://www.w3.org/2000/svg">
<text x="180" y="70" text-anchor="middle"
font-family="Arial, sans-serif" font-size="48" font-weight="bold"
fill="#facc15" stroke="#b45309" stroke-width="1.5">SVG!</text>
<text x="180" y="110" text-anchor="middle"
font-family="Arial" font-size="18" fill="#93c5fd">Text stays crisp at any zoom</text>
</svg>
</body>
</html>Gradients
Flat fills are fine, but SVG can also paint shapes with smooth gradients. You define a <linearGradient> or <radialGradient> inside a <defs> block, give it an id, add <stop> colours, then reference it as fill="url(#id)". The same gradient can fill many shapes.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG Gradients</title></head>
<body style="background:#020617;text-align:center;">
<svg width="360" height="200" viewBox="0 0 360 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="sunset" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#f97316" />
<stop offset="50%" stop-color="#ec4899" />
<stop offset="100%" stop-color="#8b5cf6" />
</linearGradient>
<radialGradient id="glow">
<stop offset="0%" stop-color="#fff7ed" />
<stop offset="100%" stop-color="#f59e0b" />
</radialGradient>
</defs>
<rect x="20" y="30" width="150" height="140" rx="16" fill="url(#sunset)" />
<circle cx="270" cy="100" r="70" fill="url(#glow)" />
</svg>
</body>
</html>SVG vs Canvas
SVG and <canvas> both draw graphics, but they work very differently. SVG builds a retained scene graph: every shape is a real DOM element you can style, click and animate. Canvas is an immediate-mode pixel buffer: you issue drawing commands with JavaScript and the result is flat pixels with no memory of individual shapes.
| Question | Choose SVG | Choose Canvas |
|---|---|---|
| Model | Retained DOM (each shape is an element) | Immediate pixels (no shape objects) |
| Interactivity | Click / hover / CSS per shape - easy | You track hit-testing yourself |
| Scaling | Sharp at any resolution | Fixed pixels; redraw for crispness |
| Best for | Icons, charts, diagrams, UI graphics | Games, particle effects, image editing |
| Performance | Slows with thousands of elements | Handles many thousands of draws |
| Access via | HTML/CSS/JS DOM APIs | getContext('2d') JavaScript API |
Key Takeaways
- SVG stores shapes as math, so it scales infinitely without blurring.
- Everything lives inside an <svg> root; viewBox sets the internal coordinate grid.
- Core shapes: rect, circle, ellipse, line, polyline, polygon, path, text.
- fill paints interiors; stroke and stroke-width draw outlines.
- <path> with the d attribute can draw any shape, including curves and arcs.
- Gradients are defined in <defs> and referenced with fill="url(#id)".
- Use SVG for crisp, interactive, low-count graphics; use Canvas for pixel-heavy, high-count rendering.
