ποΈ SVG Fundamentals and Implementation
SVG is the web's language for graphics that never blur β icons, logos, charts, and diagrams described with math instead of pixels. In this lesson you'll learn how SVG thinks, draw every core shape, decode the powerful <path> syntax, and finish with an accessible, interactive bar chart built entirely from vector elements.
π― Learning Objectives
By the end of this lesson, you will be able to:
- Explain how vector graphics differ from raster images and when to choose each
- Write the basic SVG shapes (
rect,circle,ellipse,line,polyline,polygon) with correct attributes - Read and write path commands (
M,L,C,Q,A,Z) and understand absolute vs. relative coordinates - Style SVG with attributes and CSS, and reuse shapes with
<g>,<defs>,<symbol>, and<use> - Build an accessible interactive chart with
<title>,<desc>, and ARIA
Estimated Time: 35β45 minutes β’ Difficulty: BeginnerβIntermediate
Hands-on: Hand-code a simple logo, then add hover interactivity to an SVG bar chart.
In This Lesson
What Is SVG?
Scalable Vector Graphics (SVG) is an XML-based format for describing two-dimensional graphics. Instead of storing a grid of colored pixels the way a JPEG or PNG does, SVG stores instructions: "draw a circle here with radius 40," "connect these points with a line." The browser follows those instructions to redraw the image fresh at whatever size it needs.
π‘ A useful analogy: A raster image is a mosaic made of tiny tiles β zoom in and you see the individual squares. A vector image is a recipe for drawing shapes, so the browser re-bakes it crisply at any size. One is a photograph of a drawing; the other is the drawing's blueprint.
Because SVG is just text markup that lives in the DOM, it inherits superpowers that raster images can't have:
- Scalability β razor-sharp from a 16px favicon to a billboard
- Small files β a logo can be a few hundred bytes
- Styleable β CSS targets individual shapes, including
:hover - Scriptable β JavaScript can create, move, and animate elements
- Accessible β text stays real text; shapes can carry descriptions
Vector vs. Raster
Neither format is "better" β they solve different problems. The rule of thumb: vectors for anything geometric (icons, logos, UI, diagrams, charts) and raster for anything photographic (photos, textures, painted artwork).
| Feature | SVG (vector) | PNG / JPEG (raster) |
|---|---|---|
| Scaling | Perfect at any size | Pixelates when enlarged |
| Best for | Icons, logos, charts, diagrams | Photos, complex textures |
| File size | Tiny for simple graphics | Smaller for detailed photos |
| Animation | Native via CSS / JS | Needs GIF frames or video |
| Interactivity | Per-element events | Whole image only |
| Accessibility | Real text & descriptions | alt text only |
π‘ Use both together
Most sites combine the two: SVG for the interface (icons, logos, charts) and raster for content photos. You don't pick a side β you pick the right tool per asset.
Structure & Coordinate System
An SVG is a root <svg> element containing shape elements. Here's the smallest useful example β a single circle:
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="crimson" stroke="black" stroke-width="2" />
</svg>
width/heightβ the on-screen size (can be overridden by CSS)viewBox="min-x min-y width height"β the internal coordinate space the shapes are drawn in. This is what makes SVG responsive: setwidth:100%in CSS and the viewBox scales to fitxmlnsβ the XML namespace (required for standalone.svgfiles)
π Key Terms
viewBox: the coordinate window. 0 0 100 100 means "coordinates run 0β100 in both directions," regardless of the pixel size on screen.
Origin: the point (0, 0) sits at the top-left. X increases to the right, Y increases downward β the opposite of the Cartesian graphs from math class.
The Basic Shapes
SVG ships with a handful of primitive shapes. Combine them and you can draw almost anything.
| Shape | Element | Key attributes |
|---|---|---|
| Rectangle | <rect> | x y width height rx ry |
| Circle | <circle> | cx cy r |
| Ellipse | <ellipse> | cx cy rx ry |
| Line | <line> | x1 y1 x2 y2 |
| Polyline | <polyline> | points |
| Polygon | <polygon> | points (auto-closed) |
| Path | <path> | d (anything) |
<svg viewBox="0 0 300 80" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="15" width="50" height="50" rx="8" fill="#3b82f6" />
<circle cx="105" cy="40" r="25" fill="#22c55e" />
<ellipse cx="175" cy="40" rx="30" ry="18" fill="#f59e0b" />
<polygon points="240,15 265,65 215,65" fill="#a855f7" />
</svg>
polyline stays open; a polygon automatically connects its last point back to its first.The Path Element
The <path> is the most powerful shape β every other shape can be expressed as a path. It draws using a mini-language in its d ("data") attribute, a sequence of single-letter commands followed by coordinates.
| Command | Means | Example |
|---|---|---|
M / m | Move to (pen up) | M10,10 |
L / l | Line to | L90,90 |
H / V | Horizontal / vertical line | H50 Β· V30 |
C / c | Cubic BΓ©zier curve | C10,10 20,20 30,30 |
Q / q | Quadratic BΓ©zier curve | Q10,10 20,20 |
A / a | Elliptical arc | A30,30 0 0 1 60,60 |
Z / z | Close path | Z |
Uppercase means absolute coordinates; lowercase means relative. Think of uppercase as GPS coordinates ("go to this exact spot") and lowercase as walking directions ("move 10 steps forward from where you are").
Here's a heart drawn with two cubic curves β the classic path demo:
<svg width="120" height="120" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<path d="M50,88
C10,55 10,20 35,20
C48,20 50,33 50,33
C50,33 52,20 65,20
C90,20 90,55 50,88 Z"
fill="crimson" />
</svg>
β οΈ Don't hand-draw complex paths
Reading path syntax is a valuable skill, but you rarely author intricate shapes by hand. Design in Figma, Illustrator, or Inkscape and export the SVG β then optimize it. Hand-editing is for tweaks and understanding, not for drawing a company logo point by point.
Styling & Reuse
Presentation attributes vs. CSS
You can style SVG two ways: with presentation attributes directly on the element, or with CSS. CSS wins for anything shared, interactive, or animated.
<!-- Presentation attributes (inline) -->
<circle cx="50" cy="50" r="40" fill="royalblue" stroke="black" stroke-width="2" />
<!-- Or with CSS -->
<style>
.dot { fill: royalblue; stroke: black; stroke-width: 2; transition: fill .3s; }
.dot:hover { fill: tomato; } /* impossible with a raster image */
</style>
<circle class="dot" cx="50" cy="50" r="40" />
The common styling properties are fill, stroke, stroke-width, fill-opacity, stroke-opacity, stroke-linecap, stroke-linejoin, and stroke-dasharray (for dashed lines).
Group, define, and reuse
Three elements keep complex SVGs manageable β and they map neatly onto ideas you already know from components:
<g>β a group. Apply one transform or style to many shapes at once.<defs>β a definitions block: shapes declared but not drawn until referenced.<symbol>+<use>β define a reusable icon once, stamp it anywhere (like a component).
<svg viewBox="0 0 200 60" xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="star" viewBox="0 0 100 100">
<polygon points="50,5 61,38 96,38 68,59 79,92 50,72 21,92 32,59 4,38 39,38" />
</symbol>
</defs>
<use href="#star" x="10" y="10" width="40" height="40" fill="gold" />
<use href="#star" x="80" y="10" width="40" height="40" fill="silver" />
<use href="#star" x="150" y="10" width="40" height="40" fill="#cd7f32" />
</svg>
β
Why <use> matters
Define the shape once, reuse it dozens of times, and each copy can override the fill or size. It's the same "write once, reuse everywhere" principle behind UI components β smaller files and a single source of truth.
Worked Example: Interactive Chart
Let's tie it together. Because inline SVG lives in the DOM, each bar can carry data attributes and respond to events β something a chart image could never do. Here's a compact, accessible bar chart with a hover tooltip.
<figure>
<svg id="sales" width="480" height="280" viewBox="0 0 480 280"
role="img" aria-labelledby="chartTitle chartDesc">
<title id="chartTitle">Monthly sales, 2025</title>
<desc id="chartDesc">Bar chart; sales peak in April at 55,000.</desc>
<!-- axis -->
<line x1="40" y1="240" x2="460" y2="240" stroke="#94a3b8" />
<!-- bars: height and data live on each rect -->
<rect class="bar" x="60" y="140" width="40" height="100" data-month="Jan" data-value="25000" />
<rect class="bar" x="130" y="100" width="40" height="140" data-month="Feb" data-value="35000" />
<rect class="bar" x="200" y="60" width="40" height="180" data-month="Mar" data-value="45000" />
<rect class="bar" x="270" y="20" width="40" height="220" data-month="Apr" data-value="55000" />
<rect class="bar" x="340" y="80" width="40" height="160" data-month="May" data-value="40000" />
</svg>
<div id="tip" class="tip" role="status"></div>
</figure>
<style>
.bar { fill: #3b82f6; transition: fill .2s; cursor: pointer; }
.bar:hover, .bar:focus { fill: #f59e0b; }
.tip { position: absolute; padding: 6px 10px; background: #1e293b; color: #fff;
border-radius: 6px; pointer-events: none; opacity: 0; transition: opacity .2s; }
</style>
<script>
const tip = document.getElementById('tip');
for (const bar of document.querySelectorAll('.bar')) {
bar.addEventListener('mousemove', (e) => {
const value = Number(bar.dataset.value).toLocaleString();
tip.textContent = `${bar.dataset.month}: $${value}`;
tip.style.left = `${e.pageX + 12}px`;
tip.style.top = `${e.pageY - 36}px`;
tip.style.opacity = '1';
});
bar.addEventListener('mouseleave', () => { tip.style.opacity = '0'; });
}
</script>
What this demonstrates
- Data stored on each element with
data-*attributes - CSS
:hover/:focustransitions for instant visual feedback - A modern
forβ¦ofloop with template literals andtoLocaleString() - Built-in accessibility via
role="img",<title>, and<desc>
Hands-on Exercise
ποΈ Build (and animate) a logo
Objective: Practice shapes, grouping, and CSS interactivity by hand-coding a small logo.
Instructions:
- Create an SVG with
viewBox="0 0 100 100". - Use at least three different shape types (e.g. a
circlebackdrop, apolygonmark, apathflourish). - Wrap them in a
<g>and add a CSS:hoverrule that changes a fill or scales the group. - Add a
<title>so the logo has an accessible name.
π‘ Hint
Set transform-box: fill-box; transform-origin: center; on the group so transform: scale(1.1) grows from the middle instead of the top-left corner.
β Sample solution
<svg viewBox="0 0 100 100" width="120" role="img" aria-labelledby="logoTitle">
<title id="logoTitle">Rocket badge logo</title>
<g class="logo">
<circle cx="50" cy="50" r="46" fill="#0f172a" />
<polygon points="50,20 62,55 38,55" fill="#f59e0b" />
<path d="M42,55 Q50,72 58,55 Z" fill="#ef4444" />
</g>
</svg>
<style>
.logo { transform-box: fill-box; transform-origin: center; transition: transform .3s; }
svg:hover .logo { transform: scale(1.1); }
</style>
π― Quick Quiz
Question 1: Which attribute defines the internal coordinate space that lets an SVG scale responsively?
Question 2: In a path's d attribute, what does a lowercase command letter such as l indicate?
Question 3: You need a photo of a product on your page. Which format is the right choice?
Best Practices
β Do
- Add a
viewBoxand control size with CSS for responsive graphics - Give meaningful SVGs
role="img", a<title>, and a<desc> - Optimize exported files with SVGOMG to strip editor cruft
- Reuse repeated shapes with
<symbol>and<use> - Prefer CSS for hover states and animation
β οΈ Don't
- Ship raw editor exports full of metadata, IDs, and redundant groups
- Hand-author complex paths when a design tool can generate them
- Forget alt text β an
<img src="logo.svg">still needs analtattribute - Use
createElementfor SVG in JS β it must becreateElementNSwith the SVG namespace
Summary & Quiz
π Key Takeaways
- SVG describes graphics with math, so they stay crisp at any size.
- Use vectors for geometry (icons, logos, charts) and raster for photos.
- The
viewBoxplus CSS sizing is what makes SVG responsive. - The
<path>element can draw anything; uppercase = absolute, lowercase = relative. - Inline SVG lives in the DOM, so shapes can be styled, scripted, and made accessible.
π Further Reading
- MDN β SVG reference & tutorials
- CSS-Tricks β SVG properties and CSS
- SVGOMG β online SVG optimizer
π What's Next?
SVG is one of the two ways to draw on the web. Next we meet the other: the Canvas API, a pixel-based drawing surface that trades SVG's DOM friendliness for raw rendering speed β perfect for games and heavy animation.
π Nice work!
You can now read, write, style, and script vector graphics. Let's switch to painting pixels.