SVG Diagrams for Documentation

notes

This note covers the practical use of SVG for technical diagrams in developer documentation. It walks through the advantages over raster formats, accessible SVG patterns, CSS styling, tooling options, and where SVG diagrams are not the right fit. If your docs have screenshots of Lucidchart exports that look blurry on retina screens, this is the fix.

Why SVG for Diagrams

Raster images (PNG, JPEG) have a fixed resolution. Export a diagram at 1x and it looks muddy on a 2x display. Export at 2x and you are shipping 400KB PNGs that slow down page loads. SVG sidesteps the entire problem — vector graphics render crisply at any resolution, any zoom level, any screen density.

Beyond resolution independence, SVG diagrams are:

  • Searchable and accessible: text inside SVGs is real text. Screen readers can parse it. Search engines can index it.
  • Styleable with CSS: you can change colors, fonts, and stroke widths with your site’s stylesheet. Dark mode support comes (almost) for free.
  • Small: a typical architecture diagram as SVG is 5–15KB. The equivalent PNG is 50–200KB.
  • Version-controllable: SVGs are XML text files. They diff cleanly in Git. You can review diagram changes in pull requests.

Basic SVG Structure for Diagrams

A well-structured SVG diagram looks like this:

<svg xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 800 400"
     role="img"
     aria-label="Architecture diagram showing client, API gateway, and database">
  <title>System Architecture Overview</title>
  <desc>Three boxes connected by arrows: Client on the left,
        API Gateway in the center, Database on the right.</desc>

  <!-- Client box -->
  <rect x="50" y="150" width="160" height="80"
        rx="4" fill="none" stroke="currentColor" stroke-width="2"/>
  <text x="130" y="195" text-anchor="middle"
        font-family="sans-serif" font-size="14">Client</text>

  <!-- Arrow -->
  <line x1="210" y1="190" x2="310" y2="190"
        stroke="currentColor" stroke-width="2"
        marker-end="url(#arrow)"/>

  <!-- ... more elements ... -->

  <defs>
    <marker id="arrow" viewBox="0 0 10 10"
            refX="10" refY="5" markerWidth="6" markerHeight="6"
            orient="auto-start-reverse">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor"/>
    </marker>
  </defs>
</svg>

The critical attributes: viewBox defines the coordinate system (so the SVG scales). role="img" tells assistive technology this is an image. The <title> and <desc> elements provide accessible text. Using currentColor means the diagram inherits your page’s text color.

You can find comprehensive documentation on SVG elements and attributes in the MDN SVG reference.

Accessibility Patterns

Making SVG diagrams accessible requires a few deliberate steps:

  1. Always include role="img" and aria-label on the root <svg> element
  2. Add <title> (short label) and <desc> (longer description) as the first children
  3. For complex diagrams, consider an aria-describedby pointing to a text description below the SVG
  4. Use sufficient contrast ratios for strokes and text
  5. Don’t rely solely on color to convey meaning — add labels or patterns
<svg role="img" aria-labelledby="diag-title diag-desc">
  <title id="diag-title">Request Flow</title>
  <desc id="diag-desc">Shows how a user request passes through
    the load balancer, application server, and cache layer.</desc>
  <!-- diagram content -->
</svg>

CSS Styling

Since SVGs can use currentColor and CSS custom properties, you can theme them with your site’s design system:

.diagram svg {
  max-width: 100%;
  height: auto;
}

.diagram rect {
  fill: var(--bg-surface);
  stroke: var(--text-primary);
}

.diagram text {
  fill: var(--text-primary);
  font-family: var(--font-mono);
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
  .diagram rect {
    fill: var(--bg-surface-dark);
    stroke: var(--text-primary-dark);
  }
}

This only works for inline SVGs or SVGs loaded via <object>. If you use <img src="diagram.svg">, the SVG cannot access the parent page’s CSS. For documentation sites where you want CSS theming, inline the SVGs or use the <object> tag.

Tooling

Several approaches to creating SVG diagrams for docs:

  • Hand-coded: for simple diagrams (3–6 boxes, a few arrows), writing SVG by hand is fast and gives you full control. It is also the most maintainable option for diagrams that rarely change.
  • Diagram-as-code tools: Mermaid, D2, Graphviz, and PlantUML let you define diagrams in text and generate SVG. Good for diagrams that change often (the text source is easier to maintain than XML).
  • Visual editors with SVG export: Figma, Excalidraw, and draw.io all export SVG. The output is usually verbose but functional. Run it through SVGO to clean it up.

For most documentation projects, a combination of hand-coded SVG (simple diagrams) and diagram-as-code (complex or frequently-updated diagrams) covers everything you need.

When Not to Use SVG

SVG is not the right choice for:

  • Photographs or screenshots: use JPEG or WebP
  • Highly complex diagrams with hundreds of elements: rendering performance degrades; consider a raster export with a separate accessible text description
  • Diagrams that must be pixel-identical across all browsers: SVG rendering has minor cross-browser differences in text metrics and anti-aliasing

For everything else — architecture diagrams, flowcharts, sequence diagrams, ER diagrams, network topologies — SVG is the format to use.