SVG (Scalable Vector Graphics) is one of the most powerful yet underused formats on the web. Unlike raster images that become blurry when scaled, SVGs remain pixel-perfect at any size — from a 16px favicon to a full-screen hero illustration. They're searchable, animatable, styleable with CSS, and often smaller in file size than their PNG equivalents.
This guide covers everything you need to use SVG effectively: the coordinate system, embedding methods, CSS styling, accessibility, optimization, sprites, animation techniques, and a decision framework for choosing between SVG and raster formats.
What Is SVG?
SVG is an XML-based markup language that describes two-dimensional graphics. Instead of storing color values for each pixel (like PNG or JPEG), SVG stores instructions — draw a circle here, a line there, fill this path with blue. The browser interprets these instructions and renders the graphic at whatever resolution is needed.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#3b82f6" />
</svg>
This simple example creates a blue circle that renders crisply whether displayed at 20px or 2000px wide. The file is just 104 bytes of text.
Understanding viewBox
The viewBox attribute is the single most important concept for working with SVG on the web. It defines the internal coordinate system:
viewBox="min-x min-y width height"
viewBox="0 0 24 24" /* 24×24 coordinate grid starting at origin */
- min-x, min-y: The top-left corner of the visible area (usually 0, 0)
- width, height: The dimensions of the coordinate canvas
The viewBox creates a virtual canvas. All coordinates inside the SVG are relative to this canvas. When you set the SVG's display size with CSS (e.g., width: 200px), the browser scales the viewBox content to fit — automatically maintaining aspect ratio. This is what makes SVGs truly responsive.
preserveAspectRatio
When the SVG's aspect ratio differs from its container, preserveAspectRatio controls alignment and scaling. The default (xMidYMid meet) centers the graphic and scales uniformly to fit. Use none to stretch the SVG to fill its container, or xMidYMid slice to cover the container like object-fit: cover.
Basic Shapes and Paths
SVG provides primitive shapes for common geometry:
<rect>— Rectangles and squares (with optional rounded corners via rx/ry)<circle>— Circles defined by center point and radius<ellipse>— Ellipses with separate x and y radii<line>— Straight lines between two points<polyline>— Connected line segments (open shape)<polygon>— Connected line segments that close automatically<path>— The universal shape using path commands (M, L, C, A, Z, etc.)
The <path> element is the most powerful — it can describe any shape using move (M), line (L), cubic bezier (C), arc (A), and close (Z) commands. Most SVG editors export everything as paths.
Embedding SVG in HTML
There are four main ways to include SVG on a web page, each with distinct trade-offs:
| Method | CSS Styling | JS Access | Caching | Best For |
|---|---|---|---|---|
| Inline <svg> | Full control | Full access | No (part of HTML) | Icons, interactive graphics |
| <img src="file.svg"> | None internal | No access | Yes | Static illustrations, logos |
| CSS background-image | None internal | No access | Yes | Decorative patterns, icons |
| <object> / <iframe> | Via internal stylesheet | Via contentDocument | Yes | Complex interactive SVGs |
Inline SVG
Inline SVG is placed directly in the HTML document. This gives you full CSS and JavaScript access to every element inside the SVG:
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 2L2 7l10 5 10-5-10-5z" fill="currentColor"/>
</svg>
Using fill="currentColor" makes the SVG inherit the text color from CSS, allowing you to change icon colors with a single color property.
SVG as an Image
The img tag treats SVG as an opaque image — cached independently and isolated from the page's styles:
<img src="/images/illustration.svg" alt="Team collaboration" width="600" height="400">
Always include width and height attributes to prevent layout shift, and meaningful alt text for accessibility.
Styling SVG with CSS
When SVG is inline, you can style it with the same CSS you use for HTML — but SVG has its own set of properties:
- fill: The interior color (equivalent to background-color)
- stroke: The outline color (equivalent to border-color)
- stroke-width: Outline thickness
- stroke-dasharray: Creates dashed lines (useful for animations)
- opacity / fill-opacity / stroke-opacity: Transparency controls
.icon:hover path {
fill: #3b82f6;
transition: fill 0.2s ease;
}
CSS transitions and animations work on SVG properties, enabling smooth color changes, stroke animations, and transforms without JavaScript.
SVG Accessibility
SVGs must be properly marked up for assistive technology. The approach depends on whether the graphic is decorative or informative:
Decorative SVGs (Hide from screen readers)
<svg aria-hidden="true" focusable="false">...</svg>
Informative SVGs (Describe to screen readers)
<svg role="img" aria-labelledby="chart-title chart-desc">
<title id="chart-title">Monthly Revenue</title>
<desc id="chart-desc">Bar chart showing revenue growth from $10K in January to $45K in June.</desc>
...
</svg>
aria-hidden="true".
SVG Optimization
SVG files exported from design tools (Figma, Illustrator, Sketch) contain significant bloat — editor metadata, redundant transforms, excessive precision, empty groups, and default attributes. Optimization can reduce file size by 30–70%.
SVGO (SVG Optimizer)
SVGO is the industry-standard tool for SVG optimization. It removes metadata, simplifies paths, collapses unnecessary groups, and strips default values:
npx svgo input.svg -o output.svg
npx svgo --folder ./icons/ --output ./icons-optimized/
Manual Optimization Tips
- Remove
xmlns:xlink, editor comments, and metadata elements - Reduce coordinate precision (2 decimal places is usually sufficient)
- Convert shapes to paths only when necessary — basic shapes are more readable
- Remove hidden or off-canvas elements
- Use CSS classes instead of inline styles for repeated attributes
- Gzip/Brotli compression on the server reduces transfer size further
SVG Sprites
SVG sprites combine multiple icons into a single file, reducing HTTP requests. Each icon is defined as a <symbol> and referenced with <use>:
/* sprites.svg */
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</symbol>
<symbol id="icon-menu" viewBox="0 0 24 24">
<path d="M4 6h16M4 12h16M4 18h16"/>
</symbol>
</svg>
/* Usage anywhere in the page */
<svg class="icon" aria-hidden="true">
<use href="#icon-search"></use>
</svg>
This technique is excellent for icon systems — one file, full CSS control, and no duplicate markup.
Animating SVG
SVG offers multiple animation approaches:
- CSS transitions/animations: Apply to inline SVG elements like any HTML element. Ideal for simple hover effects and state changes.
- SMIL (<animate>): SVG's built-in animation language. Declarative and powerful but being phased out in some contexts.
- JavaScript (GSAP, Anime.js, Framer Motion): Full programmatic control for complex sequences. Best for scroll-triggered animations and interactive graphics.
- stroke-dasharray trick: Animate stroke-dashoffset to create line-drawing effects — popular for logo reveals and path animations.
/* Line draw animation with CSS */
.draw-path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: draw 2s ease forwards;
}
@keyframes draw {
to { stroke-dashoffset: 0; }
}
SVG vs Raster Formats: When to Use What
| Criteria | Use SVG | Use PNG/WebP |
|---|---|---|
| Logos and icons | ✓ Always | Only as fallback |
| Illustrations (flat/geometric) | ✓ Usually smaller | If extremely complex |
| Photographs | Never | ✓ Always |
| Charts and graphs | ✓ Scalable + accessible | Only for static exports |
| Animations | ✓ Lightweight | Use video/GIF only if needed |
| Needs pixel manipulation | Not suited | ✓ Canvas or raster |
| Must scale without quality loss | ✓ Core strength | Requires multiple sizes |