Skip to content
3D & graphics for UILesson 1 of 3Beginner15 min

SVG essentials

SVG draws in resolution-independent user units inside a viewBox, so one graphic stays crisp at any size. Learn the coordinate system, paths, and currentColor.

Kept on this device only.

In one line: SVG draws shapes in abstract user units inside a viewBox, and the browser maps that coordinate space onto however many pixels you give it — so one file stays razor-sharp from a 16px favicon to a wall-sized banner.

What it is

SVG (Scalable Vector Graphics) is a markup language for vector drawing: instead of a grid of pixels, you describe shapes — rectangles, circles, lines, paths — as math in a coordinate system. Each shape is placed using user units, abstract numbers that have no inherent pixel size.

The bridge from those abstract units to the rendered box is the viewBox. It declares a window onto user space — viewBox="minX minY width height" — and the browser scales that window to fill whatever box CSS or the width/height attributes give the element. Because the drawing is described mathematically and only rasterized at the final size, an SVG is resolution-independent: there is no "native resolution" to blur or pixelate.

Why it matters

  • Crisp at any DPI or size. The same file renders sharp on a 1× laptop, a 3× phone, and a print export, because the browser re-rasterizes the vectors at the device's true pixel density.
  • Themeable with currentColor. Inline SVG inherits CSS, so a fill="currentColor" icon recolors with the surrounding text — light mode, dark mode, hover states, all for free.
  • Tiny for icons and logos. A handful of path commands weighs far less than a PNG at several resolutions, and there is only one asset to ship.
  • Inspectable DOM. Inline SVG is real DOM: you can target nodes with CSS, animate them, attach events, and read them in DevTools like any other element.

See it

Live demo
Tweak it2
100
Shrink the viewBox and the same shapes zoom in — SVG draws in user units, not pixels.

The square, circle, and line are drawn at fixed user coordinates — they never move. Shrink the viewBox with the knob and watch those same shapes appear to zoom in; grow it and they shrink into a larger expanse of empty user space. Nothing about the shapes changed, only the window onto them.

How it works

The core attribute is viewBox="minX minY width height". minX/minY set the top-left corner of the visible region in user units, and width/height set how many user units are visible. Halve the width and height and you are looking at a quarter of the area — the same drawing fills the box, so it appears twice as large.

If you omit width and height attributes on the <svg>, the element has no intrinsic pixel size and CSS sizes it freely (width: 100%, width: 1.5rem, and so on) while the viewBox preserves the internal coordinate space. That combination — a viewBox and no fixed pixel dimensions — is what makes an SVG truly fluid.

preserveAspectRatio controls how the viewBox fits when its aspect ratio differs from the rendered box — the default xMidYMid meet centers and letterboxes rather than stretching.

The drawing itself is built from a few elements: <rect>, <circle>, <line>, and the general-purpose <path>. A <path>'s d attribute is a compact mini-language — M moves the pen, L draws a line, C draws a cubic Bézier curve, and Z closes the shape back to the start. Every shape takes fill (interior) and stroke (outline), and setting either to currentColor ties it to the inherited CSS color.

Build it

A clean inline icon: a viewBox for the coordinate space, no fixed width/height so CSS sizes it, stroke="currentColor" so it inherits the text color, and aria-hidden because it is decorative.

HTML
check-icon.svg — fluid, themeable, decorative
<svg
  viewBox="0 0 24 24"
  fill="none"
  stroke="currentColor"
  stroke-width="2"
  stroke-linecap="round"
  stroke-linejoin="round"
  aria-hidden="true"
  focusable="false"
>
  <path d="M4 12 L10 18 L20 6" />
</svg>

Size it from CSS — svg { width: 1.25rem; height: 1.25rem; } — and it stays crisp at any scale while picking up whatever color its container sets.

Make it yours

Use the controls beside the demo above to change viewbox size and show coordinate grid — each change updates the example live.

Experiment in the playground
  • Push units to its minimum (50) and the shapes balloon to fill the box; push it to 400 and they retreat into open space — same shapes, different window.
  • Toggle the grid off to see how unreadable raw user space is, then back on to map each shape to its coordinates.
  • Read the live viewBox string as you drag: notice that only the last two numbers (width and height) change, and that smaller numbers mean a tighter, more zoomed-in view.

Reproduce it with an LLM

Reproduce it with an LLM

You are a senior front-end engineer. Hand-author a small, clean inline SVG icon — a 24×24 'bookmark' glyph — that scales perfectly: set a `viewBox="0 0 24 24"` (no fixed width/height so CSS controls size), draw it with a single `<path>` using relative commands where sensible, use `fill="none" stroke="currentColor"` with `stroke-width`, `stroke-linecap`, and `stroke-linejoin` so it inherits text color, and make it accessible: decorative by default (`aria-hidden="true" focusable="false"`), with a note on how to give it an accessible name (role=img + <title>) when it conveys meaning. Explain each attribute in one line. Return only the SVG plus the short notes.

Pitfalls & accessibility

  • Prefer inline SVG over <img> when you need theming or animation: an SVG referenced via <img src="icon.svg"> cannot inherit currentColor or be styled by the page's CSS.

Further reading