What SVG is — and why it's special
SVG (Scalable Vector Graphics) describes images as shapes and coordinates in XML, instead of a grid of pixels like a JPG or PNG. Because it's math, it scales to any size with zero blur, the file is tiny, and every shape is a real DOM element you can style, script, and animate.
Three ways to put SVG on a page
| Method | Looks like | Use when |
|---|---|---|
| Inline | <svg>…</svg> right in the HTML | You want to style/animate the shapes with CSS & JS. |
| As an image | <img src="logo.svg"> | A static logo or icon; no internal styling needed. |
| CSS background | background: url(bg.svg) | Decorative patterns & backgrounds. |
The canvas: viewBox & coordinates
Every SVG has an internal coordinate system set by viewBox="minX minY width height". Coordinates start at (0,0) top-left, x grows right, y grows down. Crucially, this is separate from the rendered pixel size — a 0 0 100 100 viewBox can display at any size and stay sharp.
<svg viewBox="0 0 100 100" width="200"> <!-- a circle at the center, no matter the display size --> <circle cx="50" cy="50" r="40"/> </svg>
viewBox as the graph paper you draw on, and width/CSS as the size of the printout. Design once in viewBox units; let it render at any pixel size. This is why SVG is resolution-independent.Basic shapes
SVG ships with a small kit of primitive shapes, each a tag with coordinate attributes:
<rect x="10" y="20" width="60" height="50" rx="8"/> rounded corners via rx <circle cx="120" cy="45" r="28"/> center x/y + radius <ellipse cx="200" cy="45" rx="34" ry="22"/> <line x1="260" y1="20" x2="310" y2="70"/>
<polygon> (a closed shape from a list of points) and <polyline> (the same, left open) — handy for arrows, stars, and simple charts.Paths: draw anything
The <path> element can draw any shape via a single d attribute — a string of drawing commands. Uppercase commands use absolute coordinates, lowercase use relative.
| Command | Means |
|---|---|
| M x y | Move the pen to a point (no line drawn). |
| L x y | Line to a point. |
| C … | Cubic Bézier curve (two control points). |
| Q … | Quadratic curve (one control point). |
| Z | Close the path back to the start. |
d string. Knowing the commands lets you read and tweak them.Fill & stroke
Shapes have two paint properties: fill (the inside) and stroke (the outline). Stroke has its own modifiers — width, line caps, and joins.
<circle fill="none" stroke="#7c3aed" stroke-width="6" stroke-linecap="round" stroke-dasharray="8 6"/>
fill: #d97706). CSS wins, which is what makes hover and animation possible (Step 7).Gradients & <defs>
Gradients are defined once inside <defs> with an id, then referenced by any shape via fill="url(#id)". Change the definition once and every shape using it updates.
<defs> <linearGradient id="lg" x1="0" y1="0" x2="1" y2="1"> <stop offset="0%" stop-color="#f59e0b"/> <stop offset="100%" stop-color="#e11d48"/> </linearGradient> </defs> <rect fill="url(#lg)" … />
<defs> is also where you put reusable bits like filters (drop shadows, blur), clip paths, and patterns — define once, reference by id anywhere.Styling & hover with CSS
Inline SVG shapes obey CSS like any element. You can transition fill, stroke, opacity, and transform on :hover — the foundation of interactive icons and diagrams. Hover the circle:
circle { fill: #d97706; transition: fill .3s, transform .3s; transform-origin: center; transform-box: fill-box; } circle:hover { fill: #7c3aed; transform: scale(1.25); }
transform-box: fill-box and transform-origin: center. Without them, SVG transforms pivot around the viewBox's (0,0), not the shape.Animating SVG — three ways
There are three ways to make SVG move. CSS is the one you'll use most:
| Approach | How | Best for |
|---|---|---|
| CSS | transition & @keyframes on shapes | Most things — hovers, loops, draw-ins. |
| SMIL | <animate> / <animateTransform> inside the SVG | Self-contained, declarative motion (no CSS/JS). |
| JavaScript | GSAP, anime.js, or the Web Animations API | Complex sequencing, scroll-driven, interactivity. |
CSS keyframes (a looping pulse)
SMIL: <animateTransform> (rotates itself, no CSS)
<rect x="42" y="42" width="36" height="36"> <animateTransform attributeName="transform" type="rotate" from="0 60 60" to="360 60 60" dur="3s" repeatCount="indefinite"/> </rect>
transform-box gotcha from Step 7. For anything elaborate, drive it with GSAP.The signature effect: self-drawing lines
The most beloved SVG trick. A dashed stroke can be offset to hide itself, then the offset animated to 0 so the line appears to draw itself. Hit replay:
/* pathLength="1" normalizes the length, so this works on any path */ path { stroke-dasharray: 1; stroke-dashoffset: 1; } fully hidden path.go { animation: draw 2s ease forwards; } @keyframes draw { to { stroke-dashoffset: 0; } }
pathLength="1" trick is the pro move: it makes the path report its length as exactly 1, so dasharray: 1 always covers it perfectly — no need to measure the real length with JavaScript.SVG checklist
- Use SVG for icons, logos, charts & line art — it stays sharp at any size
- Inline the SVG when you want to style or animate its shapes
-
viewBoxdefines the coordinate grid, independent of pixel size - Shapes take
fill&stroke; gradients/filters live in<defs> - Animate with CSS (set
transform-box: fill-box), SMIL, or JS - Self-draw lines with
pathLength="1"+ animatedstroke-dashoffset - Add a
role="img"+aria-label(or<title>) for accessibility