HTMLInline SVG Basics (<svg>)

SVG Basics

SVG (Scalable Vector Graphics) is an XML-based image format that you can write directly inline as HTML markup. Unlike a canvas bitmap, every shape in an SVG is a real DOM element—inspectable, stylable with CSS, and scriptable with JavaScript, just like <div> or <button>.
Inline SVG in HTML

inline-svg.html

HTML
<svg width="200" height="100" viewBox="0 0 200 100">
  <rect x="10" y="10" width="80" height="60" fill="#3b82f6" />
  <circle cx="150" cy="40" r="30" fill="#ef4444" />
</svg>
Because this is inline markup rather than a referenced image file, the browser parses it as part of the page DOM—you can select circle with document.querySelector, or style rect with a CSS rule, exactly like any other element.
Basic Shapes

Element

Draws

<rect>

A rectangle — x, y, width, height (and optional rx for rounded corners)

<circle>

A circle — cx, cy (center), r (radius)

<ellipse>

An ellipse — cx, cy, rx, ry

<line>

A straight line — x1, y1, x2, y2

<polygon>

A closed shape from a list of points

<path>

Any shape, via a compact drawing-command syntax (d attribute)

basic-shapes.html

HTML
<svg width="220" height="100" viewBox="0 0 220 100">
  <rect x="0" y="10" width="60" height="60" rx="8" fill="#22c55e" />
  <circle cx="110" cy="40" r="30" fill="#3b82f6" />
  <line x1="150" y1="10" x2="210" y2="70" stroke="#111827" stroke-width="4" />
</svg>
<path> — Drawing Anything
<path> uses a compact command language in its d attribute: M moves the pen, L draws a line, C draws a curve, and Z closes the shape. Design tools like Figma or Illustrator export shapes as <path> data automatically—you rarely write complex paths by hand.

path-example.html

HTML
<svg width="100" height="100" viewBox="0 0 100 100">
  <!-- Move to (10,80), line to (50,10), line to (90,80), close -->
  <path d="M10 80 L50 10 L90 80 Z" fill="#f59e0b" />
</svg>
viewBox — SVG's Coordinate System
viewBox="min-x min-y width height" defines the internal coordinate system your shapes are drawn in, independent of the element's rendered size (set by the width/height attributes or CSS). This is what makes SVG truly scalable: the browser stretches the internal coordinate grid to fit whatever box you render it in, with no pixelation.

viewbox.html

HTML
<!-- Internal coordinates go from (0,0) to (100,100),
     but it renders at 400x400 CSS pixels, crisp at any size -->
<svg viewBox="0 0 100 100" style="width: 400px; height: 400px;">
  <circle cx="50" cy="50" r="40" fill="#8b5cf6" />
</svg>
Styling SVG With CSS
Presentation attributes like fill and stroke can also be set (and overridden) from an external or embedded stylesheet, including with hover states.

svg-css.html

HTML
<style>
  .icon-star {
    fill: #9ca3af;
    transition: fill 0.15s ease;
  }
  .icon-star:hover {
    fill: #f59e0b;
  }
</style>

<svg width="40" height="40" viewBox="0 0 24 24" class="icon-star">
  <path d="M12 2l3 7h7l-5.5 4.5L18 21l-6-4-6 4 1.5-7.5L2 9h7z" />
</svg>
Accessibility: title, desc, and aria-hidden
A meaningful, standalone SVG (a chart, a diagram, a logo used as content) should describe itself to assistive technology using <title> and optionally <desc> as its first children. A purely decorative SVG (an icon next to text that already says the same thing) should be hidden from assistive technology instead.

svg-accessible.html

HTML
<!-- Meaningful SVG: describe it -->
<svg viewBox="0 0 100 100" role="img" aria-labelledby="chart-title">
  <title id="chart-title">Quarterly revenue, trending upward</title>
  <path d="M10 80 L40 50 L70 60 L90 20" stroke="#3b82f6" fill="none" stroke-width="3" />
</svg>

<!-- Decorative SVG next to a text label: hide it -->
<button>
  <svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24">
    <path d="M5 12h14M12 5l7 7-7 7" stroke="currentColor" fill="none" stroke-width="2" />
  </svg>
  Next
</button>
If removing the icon wouldn’t remove information, hide it
A "Next" button with an arrow icon and the word "Next" doesn't lose meaning if the arrow disappears—mark it aria-hidden="true". A standalone chart with no adjacent text summary does lose meaning, so it needs a real <title>.
SVG can be interactive, just like HTML
Because SVG shapes are DOM elements, you can attach onclick/event listeners, animate attributes with CSS transitions, or update them with JavaScript—all without a canvas redraw.
Referencing an External SVG File
SVG doesn't have to be inline—it can also be referenced like any other image, or embedded via <object> when you need it to keep its own scripting context (see the embed lesson for details on that trade-off).

external-svg.html

HTML
<!-- As a plain image: simplest, but no CSS styling or scripting from the host page -->
<img src="/icons/logo.svg" alt="Company logo" width="120" height="120" />

<!-- As a CSS background: same limitation, purely decorative use -->
<style>
  .hero {
    background-image: url('/images/pattern.svg');
  }
</style>

Method

Can style with page CSS?

Can script per shape?

Inline <svg>

Yes

Yes

<img src="file.svg">

No (only via the SVG’s own internal CSS)

No

CSS background-image

No

No

<object data="file.svg">

No, from the host page

Yes, inside the SVG's own scripts

Grouping Shapes With <g>
<g> groups multiple shapes so they can be transformed, styled, or labeled together—handy for composite icons or diagram components.

svg-group.html

HTML
<svg viewBox="0 0 100 100">
  <g transform="translate(20, 20)" fill="#3b82f6">
    <rect width="20" height="20" />
    <circle cx="40" cy="10" r="10" />
  </g>
</svg>
  • Inline SVG becomes part of the page DOM: inspectable, CSS-stylable, and scriptable per shape.

  • rect, circle, ellipse, line, and polygon cover common shapes; path draws anything else via its d attribute.

  • viewBox defines the internal coordinate system, decoupled from the rendered width/height — this is what makes SVG scale crisply.

  • Style SVG presentation attributes with ordinary CSS, including :hover and other pseudo-classes.

  • Give meaningful SVGs a <title> (and role="img"); hide purely decorative SVGs with aria-hidden="true".