SVG for the Web

Learn how to create and manipulate scalable vector graphics for modern web projects.

#svg

#vector graphics

#animation

#intermediate

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:

  1. Scalability: Look sharp at any size without pixelation
  2. Small file size: Often smaller than equivalent raster images
  3. Accessibility: Text in SVGs is selectable and readable by screen readers
  4. Animatable: Can be animated with CSS or JavaScript
  5. Stylable: Can be styled with CSS
  6. 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

  1. Create: Design in vector tools like Adobe Illustrator, Figma, or Inkscape
  2. Export: Save as SVG
  3. Optimize: Remove unnecessary code with tools like SVGO
  4. 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.