SVG and icons
Pictures made of instructions rather than pixels: crisp at any size, coloured like text, and cheap to ship.
Pictures made of instructions
Every image so far has been a grid of pixels — a photograph, a screenshot. SVG is the other kind: a picture described as shapes and lines, which the browser draws at whatever size it is asked for. A logo is as sharp on a 5K screen as on a phone, because there are no pixels to run out of.
An SVG is markup, like the rest of the page. It can live in its own file and be shown with <img src="icon.svg">, or it can sit inline in the document, which is what this chapter uses for icons.
One drawing, many sizes
The viewBox is a coordinate system, not a size: viewBox="0 0 24 24" says the drawing was made on a grid 24 units wide and 24 tall, with the origin at the top left. The width and height attributes then decide how much space it takes on the page, and the browser scales the whole grid to fit.
That is why one file works everywhere. Without a viewBox the drawing has no coordinate space to scale from, so its paths keep their raw numbers and can look cropped or tiny as the width and height change. Draw in a viewBox you choose, then let the page decide the size.
A tick, drawn inline
<svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
<path d="M4 12l5 5L20 6" fill="none" stroke="currentColor" stroke-width="2.5"
stroke-linecap="round" stroke-linejoin="round" />
</svg>Why inline earns its place
An inline SVG is part of the page, so it can take the colour of the words around it: stroke="currentColor" means the shape is drawn in whatever colour the text where it sits is written in. An external file cannot know that without a second copy.
The viewBox is what makes scaling work: it says which coordinate space the drawing was made in. The width and height then decide how big it appears, and the same drawing fits every size without being redrawn.
Shapes are elements
Inside the SVG, each shape is its own element. <rect> takes x, y, width and height; <circle> takes cx, cy and r; <line> takes x1, y1, x2 and y2. They are drawn in source order, so a shape written later sits on top of one written earlier.
A <path> is the general tool: its d attribute is a short list of commands — move to, line to, curve to, close — and it can draw anything the named shapes cannot. fill paints the inside and stroke paints the outline; both are presentation attributes, and both can be inherited from the SVG element itself.
Coordinates are yours to choose
Inside the viewBox, the numbers are yours to choose. A 24 by 24 grid puts the origin at the top left, with x growing to the right and y growing down, so a circle at cx="12" cy="12" r="10" sits in the middle and reaches two units from each edge. A rectangle at x="0" y="0" width="24" height="24" fills the grid exactly. Change the viewBox to 0 0 48 48 without changing the shapes and they occupy only the top-left quarter — the drawing did not move, the grid it is measured against did. That is the whole mental model: choose a grid, draw in it, and let width and height scale it.
A picture needs a name — or none
An icon is usually decoration beside a word: the button already says Save recipe, and the star adds nothing a listener needs. Mark it aria-hidden="true" so it is skipped instead of announced as an unlabelled graphic.
When the picture is the only content — a chart, a diagram, a logo standing alone — it needs a name of its own: role="img" with an aria-label, or a <title> as the first child. The same rule as every other image: a name if it carries meaning, nothing if it does not.
A star that follows the text
The Save button should carry a small star. Draw one inline inside the button — a viewBox and a path are enough — colour it with currentColor, and mark it decorative.
3 left to do
- The button carries an inline SVG
- The drawing declares its viewBox
- The icon is hidden from screen readers
<svg viewBox="0 0 24 24" aria-hidden="true"> with a <path d="…" fill="currentColor"> inside, placed before the button’s words.
Three SVG mistakes: leaving out the viewBox, so the drawing has no coordinate space to scale; using an inline SVG for a photograph, which is larger and slower than the picture; and forgetting the name. An icon beside a label is aria-hidden="true"; a chart or diagram standing alone needs a <title> or an aria-label.
Try these next
- Draw a circle and a rectangle in the same viewBox and move one by changing its coordinates.
- Give a standalone chart a
<title>as its first child and read the page with a screen reader. - Change the width and height of an inline icon and confirm the drawing stays sharp.
A chart drawn from shapes
The chart is an empty SVG. Give it a viewBox and draw three bars as `<rect>` elements, then add a `<title>` inside the SVG that names what the chart shows.
1 left to do
- There is an inline SVG
- The drawing declares its viewBox
A viewBox of 0 0 300 160 gives you room. Each bar needs x, y, width and height; the first child of the SVG can be <title>Rainfall by month</title>.
Prefer the shape you can describe in a few lines. A traced photograph saved as SVG is larger than the photograph and draws slowly — SVG is for icons and diagrams, not pictures.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
Why does an SVG stay sharp at any size?
