SVG for the Web
Learn how to create and manipulate scalable vector graphics for modern web projects.
SVG (Scalable Vector Graphics) is a powerful XML-based vector image format for the web. Unlike raster images (JPEG, PNG), SVGs maintain perfect quality at any size, making them ideal for responsive designs, icons, illustrations, and animations.
Why Use SVG?
SVGs offer several advantages over other image formats:
- Scalability: Look sharp at any size without pixelation
- Small file size: Often smaller than equivalent raster images
- Accessibility: Text in SVGs is selectable and readable by screen readers
- Animatable: Can be animated with CSS or JavaScript
- Stylable: Can be styled with CSS
- Programmable: Can be created and manipulated with JavaScript
Getting Started with SVG
SVGs can be used in HTML in multiple ways:
1. Inline SVG
<!DOCTYPE html>
<html>
<body>
<!-- SVG directly in your HTML -->
<svg width="100" height="100" viewBox="0 0 100 100">
<circle
cx="50"
cy="50"
r="40"
stroke="green"
stroke-width="4"
fill="yellow"
/>
</svg>
</body>
</html>
2. As an Image
<!-- Using an <img> tag -->
<img src="circle.svg" alt="Yellow circle with green outline" />
<!-- Using CSS background-image -->
<div style="background-image: url('circle.svg');"></div>
3. Using an Object Tag
<object type="image/svg+xml" data="circle.svg">
Fallback content if SVG isn't supported
</object>
Basic SVG Elements
SVG has a variety of built-in shape elements:
Rectangles
<svg width="200" height="100">
<rect x="10" y="10" width="180" height="80" rx="10" ry="10" /* rounded corners
*/ fill="blue" stroke="black" stroke-width="2" />
</svg>
Circles
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" stroke="black" stroke-width="2" />
</svg>
Ellipses
<svg width="200" height="100">
<ellipse
cx="100"
cy="50"
rx="80"
ry="40"
fill="green"
stroke="black"
stroke-width="2"
/>
</svg>
Lines
<svg width="200" height="100">
<line x1="10" y1="10" x2="190" y2="90" stroke="purple" stroke-width="3" />
</svg>
Polylines
<svg width="200" height="100">
<polyline
points="10,10 30,90 50,30 70,90 90,10"
fill="none"
stroke="orange"
stroke-width="2"
/>
</svg>
Polygons
<svg width="200" height="100">
<polygon
points="50,10 90,90 10,90"
fill="teal"
stroke="black"
stroke-width="2"
/>
</svg>
Paths (Most Powerful)
Paths are the most versatile SVG element, capable of creating any shape:
<svg width="200" height="100">
<path d="M10,90 Q50,10 90,90" fill="none" stroke="black" stroke-width="2" />
</svg>
Path commands:
- M: Move to (x,y)
- L: Line to (x,y)
- H: Horizontal line to x
- V: Vertical line to y
- C: Cubic Bezier curve
- Q: Quadratic Bezier curve
- A: Arc
- Z: Close path
Adding Text to SVG
<svg width="200" height="100">
<text x="20" y="50" font-family="Arial" font-size="20" fill="black">
SVG Text
</text>
</svg>
You can even follow a path with text:
<svg width="300" height="150">
<path id="curve" d="M20,80 Q150,20 280,80" fill="transparent" />
<text>
<textPath href="#curve">Text following a curved path</textPath>
</text>
</svg>
SVG Coordinate System
The SVG coordinate system starts at the top-left (0,0) and increases right and down. The viewBox
attribute is crucial for controlling how the SVG scales:
<svg width="200" height="100" viewBox="0 0 100 50">
<!-- Content here is drawn in a 100×50 coordinate system -->
<!-- but rendered in a 200×100 pixel area -->
</svg>
Grouping Elements
The <g>
element groups SVG elements together:
<svg width="200" height="100">
<g fill="blue" stroke="black" stroke-width="2">
<!-- These shapes all inherit the group's styles -->
<circle cx="30" cy="50" r="20" />
<circle cx="70" cy="50" r="20" />
<rect x="100" y="30" width="40" height="40" />
</g>
</svg>
Reusing Elements with Symbols
Define once, use multiple times with <symbol>
and <use>
:
<svg width="300" height="100">
<!-- Define a symbol -->
<symbol id="star" viewBox="0 0 32 32">
<polygon points="16,0 21,11 32,11 23,19 26,32 16,25 6,32 9,19 0,11 11,11" />
</symbol>
<!-- Use the symbol multiple times -->
<use href="#star" x="25" y="25" width="50" height="50" fill="gold" />
<use href="#star" x="125" y="25" width="50" height="50" fill="orange" />
<use href="#star" x="225" y="25" width="50" height="50" fill="red" />
</svg>
Styling SVG with CSS
SVG elements can be styled with CSS, just like HTML:
<svg width="200" height="100">
<style>
circle {
fill: yellow;
stroke: black;
stroke-width: 2;
}
circle:hover {
fill: orange;
transform: scale(1.1);
transition: all 0.3s ease;
}
</style>
<circle cx="50" cy="50" r="40" />
</svg>
External CSS works too:
/* styles.css */
.my-circle {
fill: yellow;
stroke: black;
stroke-width: 2;
}
.my-circle:hover {
fill: orange;
}
<svg width="200" height="100">
<circle class="my-circle" cx="50" cy="50" r="40" />
</svg>
Basic SVG Transformations
Transform SVG elements with the transform
attribute:
<svg width="200" height="200">
<!-- Translate (move) -->
<rect
x="0"
y="0"
width="20"
height="20"
fill="red"
transform="translate(50, 50)"
/>
<!-- Rotate (around origin) -->
<rect
x="0"
y="0"
width="20"
height="20"
fill="green"
transform="rotate(45)"
/>
<!-- Rotate around point (100,100) -->
<rect
x="90"
y="90"
width="20"
height="20"
fill="blue"
transform="rotate(45, 100, 100)"
/>
<!-- Scale -->
<rect
x="150"
y="50"
width="10"
height="10"
fill="purple"
transform="scale(2)"
/>
<!-- Multiple transformations (applied from right to left) -->
<rect
x="0"
y="0"
width="20"
height="20"
fill="orange"
transform="translate(150, 150) rotate(45) scale(1.5)"
/>
</svg>
Creating Responsive SVGs
Make your SVGs responsive with these techniques:
<!-- Simple responsive SVG -->
<svg width="100%" height="auto" viewBox="0 0 200 100">
<circle cx="100" cy="50" r="40" fill="cornflowerblue" />
</svg>
<!-- Using CSS for more control -->
<style>
.responsive-svg {
width: 100%;
max-width: 500px;
height: auto;
}
</style>
<svg class="responsive-svg" viewBox="0 0 200 100">
<circle cx="100" cy="50" r="40" fill="cornflowerblue" />
</svg>
SVG Gradients
Add depth to your graphics with gradients:
Linear Gradient
<svg width="200" height="100">
<!-- Define the gradient -->
<defs>
<linearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,0,0);" />
<stop offset="100%" style="stop-color:rgb(0,0,255);" />
</linearGradient>
</defs>
<!-- Use the gradient -->
<rect x="10" y="10" width="180" height="80" fill="url(#gradient1)" />
</svg>
Radial Gradient
<svg width="200" height="200">
<defs>
<radialGradient id="gradient2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:white;" />
<stop offset="100%" style="stop-color:purple;" />
</radialGradient>
</defs>
<circle cx="100" cy="100" r="80" fill="url(#gradient2)" />
</svg>
SVG Filters
Create advanced effects with SVG filters:
<svg width="200" height="100">
<defs>
<filter id="blur-effect">
<feGaussianBlur stdDeviation="2" />
</filter>
</defs>
<circle cx="50" cy="50" r="40" fill="teal" />
<circle cx="150" cy="50" r="40" fill="teal" filter="url(#blur-effect)" />
</svg>
Animating SVG with CSS
SVG elements can be animated with CSS:
<svg width="200" height="100">
<style>
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
</style>
<circle class="pulse" cx="100" cy="50" r="40" fill="coral" />
</svg>
Animating SVG with SMIL
SVG has its own built-in animation system (though it’s being phased out in favor of CSS/JS):
<svg width="200" height="100">
<circle cx="100" cy="50" r="40" fill="lightblue">
<animate
attributeName="r"
values="40;20;40"
dur="3s"
repeatCount="indefinite"
/>
</circle>
</svg>
Interactive SVG with JavaScript
Make your SVGs interactive with JavaScript:
<svg width="200" height="100" id="interactive-svg">
<circle cx="100" cy="50" r="40" fill="tomato" id="interactive-circle" />
</svg>
<script>
const circle = document.getElementById("interactive-circle");
circle.addEventListener("click", function () {
// Change the color when clicked
const currentColor = this.getAttribute("fill");
const newColor = currentColor === "tomato" ? "steelblue" : "tomato";
this.setAttribute("fill", newColor);
});
circle.addEventListener("mouseover", function () {
// Scale up on hover
this.setAttribute("r", "45");
});
circle.addEventListener("mouseout", function () {
// Return to original size
this.setAttribute("r", "40");
});
</script>
SVG as Data Visualization
SVG is perfect for data visualization. Here’s a simple bar chart:
<svg width="300" height="200">
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis {
stroke: #333;
stroke-width: 1;
}
.label {
font-family: sans-serif;
font-size: 12px;
}
</style>
<!-- Y axis -->
<line x1="40" y1="20" x2="40" y2="180" class="axis" />
<!-- X axis -->
<line x1="40" y1="180" x2="280" y2="180" class="axis" />
<!-- Bars -->
<rect class="bar" x="60" y="50" width="30" height="130" />
<rect class="bar" x="110" y="80" width="30" height="100" />
<rect class="bar" x="160" y="20" width="30" height="160" />
<rect class="bar" x="210" y="100" width="30" height="80" />
<!-- Labels -->
<text x="75" y="195" class="label">Q1</text>
<text x="125" y="195" class="label">Q2</text>
<text x="175" y="195" class="label">Q3</text>
<text x="225" y="195" class="label">Q4</text>
</svg>
B[Export as SVG]
B --> C[Optimize SVG]
C --> D{How to use?}
D -->|Static| E[Insert as Image]
D -->|Interactive| F[Inline in HTML]
D -->|Animated| G[Add CSS/JS]
E --> H[Deploy]
F --> H
G --> H
“ —>
Creating and Optimizing SVGs
- Create: Design in vector tools like Adobe Illustrator, Figma, or Inkscape
- Export: Save as SVG
- Optimize: Remove unnecessary code with tools like SVGO
- Implement: Add to your website
Example of Optimizing SVG
Before optimization:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100"
height="100"
viewBox="0 0 100 100"
>
<circle
cx="50"
cy="50"
r="40"
style="fill: #ff0000; stroke: #000000; stroke-width: 2px;"
/>
</svg>
After optimization:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#f00" stroke="#000" stroke-width="2" />
</svg>
Practical Example: SVG Icon System
Create a reusable icon system with SVG symbols:
<svg style="display: none;">
<!-- Icon definitions -->
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
</symbol>
<symbol id="icon-search" viewBox="0 0 24 24">
<path
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
/>
</symbol>
<symbol id="icon-settings" viewBox="0 0 24 24">
<path
d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"
/>
</symbol>
</svg>
<!-- Using the icons -->
<div>
<svg class="icon" width="24" height="24"><use href="#icon-home"></use></svg>
<svg class="icon" width="24" height="24"><use href="#icon-search"></use></svg>
<svg class="icon" width="24" height="24">
<use href="#icon-settings"></use>
</svg>
</div>
<style>
.icon {
fill: currentColor; /* Inherits text color */
vertical-align: middle;
}
</style>
Conclusion
SVG is a powerful format for creating scalable, accessible, and interactive graphics for the web. Whether you’re designing icons, creating data visualizations, or building interactive user interfaces, SVG offers benefits that bitmap images simply can’t match.
Start simple by incorporating basic SVG shapes into your designs, then gradually explore more advanced features like gradients, animations, and interactivity. With SVG, you can create graphics that look crisp on any device while keeping file sizes small and making your websites more engaging and accessible.