LogoSVG

SVG 101

Your comprehensive guide to Scalable Vector Graphics. From basic shapes to complex paths and animations, learn how to create crisp, scalable images for the web.

Fundamentals

What is SVG?

SVG stands for Scalable Vector Graphics. Unlike raster images (JPEG, PNG) which are made of pixels, SVG is an XML-based format that defines images using lines, curves, and shapes. This means they can be scaled to any size without losing quality.

  • Resolution Independent: Looks crisp on any screen density.
  • Small File Size: Often smaller than equivalent bitmaps for simple graphics.
  • Scriptable: Can be manipulated with CSS and JavaScript.
  • Accessible: Text inside SVG is selectable and readable by screen readers.

Why SVG matters for the modern web?

Performance
SVGs are often smaller in file size than raster equivalents, especially for logos and icons. They compress well with GZIP.
Responsiveness
They scale infinitely without pixelation, looking sharp on everything from mobile screens to high-DPI Retina displays.
Interactivity
Every part of an SVG is a DOM element. You can use CSS for hover states and animations, or JavaScript for complex interactions.
Accessibility & SEO
Text within SVGs is searchable and selectable. Screen readers can interpret the structure if labeled correctly.

The SVG Element & ViewBox

The <svg> tag is the container for your graphics. The viewBox attribute is arguably the most important concept to understand. It defines the coordinate system and aspect ratio.

viewBox="min-x min-y width height" defines the visible area of the infinite canvas.

Basic SVG Structure
A simple SVG with a viewBox defining a 100x100 coordinate system. Hover to see a subtle scale effect.
<svg width="400" height="400" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" class="border border-dashed border-slate-300 bg-slate-50/50">
  <!-- Grid lines for context -->
  <defs>
    <pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse">
      <path d="M 10 0 L 0 0 0 10" fill="none" stroke="gray" stroke-width="0.5" opacity="0.2"/>
    </pattern>
  </defs>
  <rect width="100" height="100" fill="url(#grid)" />
  
  <!-- The coordinate system goes from 0,0 to 100,100 -->
  <circle cx="50" cy="50" r="30" fill="#3b82f6" class="hover:fill-blue-600 transition-colors duration-300 cursor-pointer" />
  <text x="50" y="90" font-size="8" text-anchor="middle" fill="#64748b">(50, 50)</text>
</svg>
(50, 50)

Basic Shapes

Rectangles & Circles

SVG provides primitives for common geometric shapes. Try hovering over them!

Rectangle
Use <rect> with x, y, width, height, and optional rx/ry for rounded corners.
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Standard Rect with hover effect -->
  <rect x="10" y="10" width="80" height="80" fill="#ef4444" class="transition-all duration-500 hover:rx-20 hover:fill-red-600 cursor-pointer" />
  
  <!-- Rounded Rect with opacity hover -->
  <rect x="110" y="10" width="80" height="80" rx="15" fill="#f97316" class="transition-opacity duration-300 hover:opacity-75 cursor-pointer" />
</svg>
Circle & Ellipse
<circle> takes cx, cy, r. <ellipse> takes cx, cy, rx, ry.
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Circle that pulses on hover -->
  <circle cx="50" cy="50" r="40" fill="#eab308" class="transition-all duration-500 hover:r-45 cursor-pointer" />
  
  <!-- Ellipse that rotates on hover (via CSS group wrapper usually, but here via direct transform origin if supported or CSS) -->
  <ellipse cx="150" cy="50" rx="40" ry="25" fill="#84cc16" class="hover:fill-lime-600 transition-colors cursor-pointer" />
</svg>

Lines, Polylines & Polygons

Line
<line> connects two points. Here's an animated dash array example.
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <style>
    .dashed-line { animation: dash 1s linear infinite; }
    @keyframes dash { to { stroke-dashoffset: -20; } }
  </style>
  <line x1="10" y1="50" x2="190" y2="50" stroke="currentColor" stroke-width="4" stroke-dasharray="10, 10" class="dashed-line text-indigo-500" />
</svg>
Polyline & Polygon
<polyline> is open, <polygon> is closed. Check out the star!
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Polyline: Zigzag -->
  <polyline points="10,50 30,20 50,80 70,20 90,50" fill="none" stroke="#06b6d4" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
  
  <!-- Polygon: Star Shape -->
  <polygon points="150,10 162,35 190,35 168,52 176,80 150,62 124,80 132,52 110,35 138,35" fill="#8b5cf6" class="hover:rotate-12 transition-transform origin-center duration-300 cursor-pointer" style="transform-origin: 150px 45px;" />
</svg>

The Path

The Path Element

The <path> element can create any shape. It's powerful!

Commands
  • M / m: Move to (x, y)
  • L / l: Line to (x, y)
  • H / h: Horizontal line to (x)
  • V / v: Vertical line to (y)
  • Z / z: Close path
Curves
  • C / c: Cubic Bezier
  • Q / q: Quadratic Bezier
  • A / a: Arc
  • S / s: Smooth Cubic
  • T / t: Smooth Quadratic
Complex Paths: Heart
A heart shape created using cubic bezier curves (C). Hover to make it beat!
<svg width="400" height="400" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <path d="M50 30 C 40 10, 10 10, 10 40 C 10 70, 50 90, 50 90 C 50 90, 90 70, 90 40 C 90 10, 60 10, 50 30 Z" 
        fill="#ec4899" 
        stroke="#be185d" 
        stroke-width="2"
        class="transition-transform duration-300 hover:scale-110 origin-center cursor-pointer"
        style="transform-origin: 50px 50px;"
  />
</svg>
Quadratic Curves
Visualizing how control points pull the curve.
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Quadratic Curve -->
  <path d="M 20 80 Q 100 10 180 80" fill="none" stroke="#14b8a6" stroke-width="4" stroke-linecap="round" />
  
  <!-- Control Point Visualization -->
  <line x1="20" y1="80" x2="100" y2="10" stroke="gray" stroke-width="1" stroke-dasharray="4" opacity="0.5" />
  <line x1="180" y1="80" x2="100" y2="10" stroke="gray" stroke-width="1" stroke-dasharray="4" opacity="0.5" />
  <circle cx="100" cy="10" r="4" fill="#ef4444" class="cursor-help">
    <title>Control Point</title>
  </circle>
  <text x="100" y="25" text-anchor="middle" font-size="10" fill="gray">Control Point</text>
</svg>
Control Point Control Point

Styling & Transforms

Grouping & Transformations

Solar System (Groups & Transforms)
Using transforms to rotate planets around a center.
<svg width="400" height="400" viewBox="-100 -100 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- Sun -->
  <circle r="20" fill="#fbbf24" />
  
  <!-- Orbit Path -->
  <circle r="70" fill="none" stroke="gray" opacity="0.3" />
  
  <!-- Planet Group: Rotated 45 degrees -->
  <g transform="rotate(45)">
    <!-- Planet moved out to orbit radius -->
    <circle cx="70" cy="0" r="10" fill="#3b82f6">
       <animateTransform attributeName="transform" type="rotate" from="0 -70 0" to="360 -70 0" dur="4s" repeatCount="indefinite" /> 
    </circle>
  </g>
  
  <!-- Another Planet -->
  <g>
     <circle cx="40" cy="0" r="6" fill="#10b981">
       <animateTransform attributeName="transform" type="rotate" from="0 0 0" to="360 0 0" dur="3s" repeatCount="indefinite" />
     </circle>
  </g>
</svg>

Advanced

Defs & Gradients

Reusable Defs & Gradients
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="sunset" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:#fbbf24;stop-opacity:1" />
      <stop offset="50%" style="stop-color:#f59e0b;stop-opacity:1" />
      <stop offset="100%" style="stop-color:#ea580c;stop-opacity:1" />
    </linearGradient>
    
    <filter id="glow">
      <feGaussianBlur stdDeviation="2.5" result="coloredBlur"/>
      <feMerge>
        <feMergeNode in="coloredBlur"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
    
    <circle id="orb" r="15" />
  </defs>
  
  <rect width="200" height="100" fill="#1e293b" rx="8" />
  
  <use href="#orb" x="50" y="50" fill="url(#sunset)" filter="url(#glow)" />
  <use href="#orb" x="100" y="50" fill="url(#sunset)" filter="url(#glow)" style="opacity: 0.7" />
  <use href="#orb" x="150" y="50" fill="url(#sunset)" filter="url(#glow)" style="opacity: 0.4" />
</svg>

Text Paths

Text on a Wave
Text following a custom path definition.
<svg width="400" height="200" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <path id="wave" d="M 10 50 Q 55 10 100 50 T 190 50" fill="none" stroke="#cbd5e1" stroke-dasharray="4" />
  
  <text font-family="monospace" font-size="14" fill="#475569">
    <textPath href="#wave" startOffset="50%" text-anchor="middle">
      Riding the SVG wave 🌊
    </textPath>
  </text>
</svg>
Riding the SVG wave 🌊