SVG 101

A Gentle Introduction

I have no idea what I'm doing.


“Scalable Vector Graphics”

Since 2001 (Seriously!)


331 bytes (optimized)


103 bytes (optimized)

<img width="240" height="240"

<svg width="240" height="240" viewBox="0 0 24 24">
  <circle fill="#F26941" cx="12" cy="12" r="12"/>

SVGs are

Made up of scalable vector shapes and paths (not pixels).

Written as XML and optionally CSS.

Accessible to screen readers and assistive devices.

Embeddable as images, objects or directly into HTML.

Able to be manipulated by CSS and/or JavaScript.

SVGs are not

Supported earlier than IE9 and Android 3.

100% consistent in modern browsers.

A replacement for canvas.

Particularly intuitive to learn.*

* There are three ways of doing everything. 😅

Create in your favorite application…

…and/or “by hand”

(Even if you exported from one of the aforementioned apps!)

Anatomy of an SVG

Container with viewBox

The viewBox attribute defines the coordinate system.


Values are minimum x and y coordinates, then width and height.

viewBox examples

<!-- Normal:   --> 
<!-- Larger:   --> 
<!-- Smaller:  --> 
<!-- Negative: --> 
<!-- Mixed:    --> 

Further reading: Understanding SVG Coordinate Systems →

Optional: Dimensions

By default, SVGs will attempt to fill their container regardless of viewBox. You can specify dimensions to make the asset behave more like an img would.


Optional: preserveAspectRatio

Tells the browser how to handle dimensions that contradict viewBox.


More examples: preserveAspectRatio on MDN →

Basic Shapes

<svg viewBox="0 0 320 100">
  <rect fill="#5A7BDD" x="0" y="0" width="100" height="100"
    rx="12" ry="12"/>
  <circle fill="#F26941" cx="160" cy="50" r="50"/>
  <line x1="230" y1="90" x2="310" y2="10"
    stroke="#0F1C3F" stroke-width="10" stroke-linecap="round"/>

Complex Shapes

<svg viewBox="0 0 225 100">
  <polygon fill="#F26941" points="50,0 95,25 95,75 50,100 5,75 5,25"/>
  <path fill="none" d="M 120 90 c 0 -100 100 -100 100 0"
    stroke="#5A7BDD" stroke-width="10" stroke-linecap="round"/>


<svg viewBox="0 0 210 100">
  <style type="text/css">
    .demo-shape { fill: #5A7BDD; }
    .demo-shape:hover { fill: #F26941; }
  <rect class="demo-shape" x="0" y="0" width="100" height="100" rx="12" ry="12"/>
  <circle class="demo-shape" cx="160" cy="50" r="50"/>

If embedded in-page, you can style SVGs from that page’s stylesheet. SVGs can also link to external stylesheets just like webpages.


<svg viewBox="0 0 24 24">
  <style type="text/css">
    .logo { fill: #5A7BDD; }
  <g class="logo">

Re-usable elements

<svg viewBox="0 0 340 100">
  <circle id="orange-circle" fill="#F26941" cx="50" cy="50" r="50"/>
  <use xlink:href="#orange-circle" x="120"/>
  <use xlink:href="#orange-circle" x="240"/>

Defined elements for later use

<svg viewBox="0 0 340 100">
    <circle id="circle" cx="50" cy="50" r="50"/>
  <use xlink:href="#circle" fill="#0F1C3F" x="0" />
  <use xlink:href="#circle" fill="#5A7BDD" x="120"/>
  <use xlink:href="#circle" fill="#F26941" x="240"/>

Further reading: Structuring, Grouping, and Referencing in SVG →


Re-usable groups with their own viewBox and preserveAspectRatio attributes.

Welcome to Cloud Four

  <symbol id="cloud-four" viewBox="0 0 24 24">
    <!-- paths and stuff -->

<!-- Later on in the same document... -->
  <svg class="icon"> 
    <use xlink:href="#cloud-four"/>
  Welcome to Cloud Four

Further reading: SVG symbol a Good Choice for Icons →


  Orange circle
  A delightfully balanced apricot ellipse.


Further reading: Tips for Creating Accessible SVG →

Text, images and links


<svg viewbox="0 0 480 240">
  <style type="text/css"> /* text styles */ </style>
  <a xlink:href="" target="_blank">
    <image xlink:href="" x="0" y="0" height="240" width="480"/>
    <text x="240" y="120" text-anchor="middle" dominant-baseline="central" transform="rotate(-22 240 120)">Animals!</text>

…and a zillion other things!

Elements can be re-used, transformed, filtered, masked and animated as browser support allows.




Performant, familiar


Powerful, compatible, concise

Why don't we have both?

JavaScript Animation Libraries

Greensock logo

GSAP is by far the most powerful, and usually the most performant. It can handle tweening, sequencing, easing and a bunch more.

Snap.svg logo

Snap.svg is the most common choice for animating path data, but this feature is coming to GSAP soon.

Other alternatives include Velocity.js and Animate Plus.

Further reading: The State of SVG Animation →

Practical examples

Icon sprite

Icons inherit parent color except when color is explicitly defined.

Fancy download button

Animates with CSS and GSAP.

Familiar lock and sign

Uses masks and text paths, animates on click with GSAP.

Odds and ends

Embedding techniques

<svg> <object> <img> CSS
Inherit page CSS Yes No No No
JavaScript Yes Yes No No
Sprites Yes No No Sort of
Accessibility Excellent Limited Limited Poor
Cacheability Limited Excellent Excellent Excellent
Fallback <image> Inner content <picture> JavaScript


  <!-- Older browsers render as img: -->
  <image src="fallback.png" xlink:href="" width="100%">

<object type="image/svg+xml" data="example.svg">
  <!-- Fallback content -->

  <source type="image/svg+xml" srcset="example.svg">
  <img src="fallback.png">

.example {
  background-image: url("fallback.png");
.svg .example { /* Modernizr */
  background-image: url("example.svg");

Some browser inconsistencies

  • Firefox handles proportional transform-origin differently than other browsers, though a fix is coming.

  • IE does not support external content without a polyfill.

  • Prior to Android 4.4, the default Android browser does not support masking.

  • Opera Mini and Opera Mobile versions earlier than 12.1 pixelate SVG graphics that are scaled up.

Useful tools

  • svg-sprite: Assembles multiple files into SVG sprites.
  • IcoMoon: Web app for assembling SVG icons into sprites.
  • svgo: Popular and powerful optimizer.
  • SVGOMG: Browser-based GUI for SVGO.
  • svg4everybody: Polyfill for SVG external content.

Further reading

Thank you!