|$ curl https://forge-ai.dev/api/markdown?path=docs/html/svg
$cat docs/scalable-vector-graphics-(svg).md
updated Recently·30 min read·published

Scalable Vector Graphics (SVG)

HTMLSVGGraphicsIntermediate
Introduction

SVG (Scalable Vector Graphics) is an XML-based vector image format for two-dimensional graphics. Unlike raster formats (PNG, JPEG) or the HTML Canvas API, SVG maintains a DOM of all elements, making them scriptable, styleable with CSS, and resolution-independent.

SVG can be used three ways: inline in HTML (inlined SVG), as an external image via <img>, or embedded via <object>. Inline SVG is the most powerful as it allows CSS styling and JavaScript interaction.

Basic Shapes

SVG provides a set of basic shape elements. Each has attributes for position, size, and geometry.

ElementAttributesDescription
<rect>x, y, width, height, rx, ryRectangle with optional rounded corners
<circle>cx, cy, rCircle centered at (cx, cy)
<ellipse>cx, cy, rx, ryEllipse with separate x/y radii
<line>x1, y1, x2, y2Straight line between two points
<polyline>pointsConnected line segments (open)
<polygon>pointsClosed shape (last point connects to first)
shapes.svg
SVG
1<svg viewBox="0 0 500 200" xmlns="http://www.w3.org/2000/svg">
2 <!-- Rectangle -->
3 <rect x="20" y="20" width="80" height="60" rx="8" fill="#00FF41" />
4
5 <!-- Circle -->
6 <circle cx="180" cy="50" r="40" fill="#4FC3F7" />
7
8 <!-- Ellipse -->
9 <ellipse cx="300" cy="50" rx="50" ry="30" fill="#C084FC" />
10
11 <!-- Line -->
12 <line x1="400" y1="20" x2="480" y2="80" stroke="#FF6B6B" stroke-width="3" />
13
14 <!-- Polyline -->
15 <polyline points="20,130 60,100 100,130 140,100 180,130"
16 fill="none" stroke="#FFD93D" stroke-width="3" />
17
18 <!-- Polygon -->
19 <polygon points="240,130 280,90 320,130 280,170"
20 fill="#FB923C" stroke="#FFFFFF" stroke-width="2" />
21</svg>
preview
Paths

The <path> element is the most powerful SVG shape. Its d attribute contains a series of commands that define the geometry. Each command is a single letter followed by coordinates.

CommandNameParameters
MMove Tox y
LLine Tox y
HHorizontal Linex
VVertical Liney
CCubic Bezierx1 y1 x2 y2 x y
QQuadratic Bezierx1 y1 x y
AArcrx ry x-rot large-arc sweep x y
ZClose Path

Uppercase commands use absolute coordinates, lowercase use relative coordinates from the current point.

paths.svg
SVG
1<!-- Heart shape using cubic beziers -->
2<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
3 <path d="M50,85
4 C15,55 0,40 15,25
5 S35,5 50,25
6 C65,5 85,10 85,25
7 S85,55 50,85Z"
8 fill="#FF6B6B" />
9</svg>
10
11<!-- Arc example -->
12<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
13 <path d="M20,20 A80,80 0 0,1 180,20"
14 fill="none" stroke="#00FF41" stroke-width="4" />
15 <path d="M20,180 A80,80 0 0,0 180,180"
16 fill="none" stroke="#4FC3F7" stroke-width="4" />
17</svg>
preview
Styling

SVG elements can be styled with presentation attributes (inline), CSS properties, or stylesheets. The styling model is similar to HTML with cascading and inheritance.

PropertyValuesDescription
fillcolor | none | currentColorInterior color of shape
strokecolor | none | currentColorOutline color
stroke-widthnumberThickness of the outline
stroke-linecapbutt | round | squareShape of line ends
stroke-linejoinmiter | round | bevelShape of line corners
opacity0–1Overall transparency
fill-opacity0–1Fill transparency only
stroke-opacity0–1Stroke transparency only
fill-rulenonzero | evenoddDetermines inside vs outside for complex paths
stroke-dasharraynumbersDash pattern (e.g. "5,3")
styling.svg
SVG
1<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
2 <!-- CSS classes for styling -->
3 <style>
4 .dashed { stroke-dasharray: 8, 4; }
5 .glow { filter: drop-shadow(0 0 6px #00FF41); }
6 </style>
7
8 <!-- Inline styling -->
9 <circle cx="60" cy="60" r="40"
10 fill="none" stroke="#00FF41" stroke-width="4" />
11
12 <!-- stroke-linecap examples -->
13 <line x1="20" y1="140" x2="100" y2="140"
14 stroke="#FF6B6B" stroke-width="12" stroke-linecap="round" />
15 <line x1="20" y1="170" x2="100" y2="170"
16 stroke="#4FC3F7" stroke-width="12" stroke-linecap="square" />
17
18 <!-- Dashed stroke via CSS -->
19 <rect x="150" y="20" width="100" height="80" rx="10"
20 fill="none" stroke="#FFD93D" stroke-width="3" class="dashed" />
21
22 <!-- fill-rule example -->
23 <path d="M200,130 L220,170 L180,170Z M200,140 L210,160 L190,160Z"
24 fill="#C084FC" fill-rule="evenodd" opacity="0.8" />
25
26 <!-- Glow via filter -->
27 <circle cx="340" cy="60" r="40" fill="#00FF41" class="glow" />
28</svg>
preview
Gradients & Patterns

SVG gradients and patterns are defined in <defs> and referenced by ID. This keeps them reusable and keeps the markup clean.

gradients-patterns.svg
SVG
1<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
2 <defs>
3 <!-- Linear gradient -->
4 <linearGradient id="lg" x1="0%" y1="0%" x2="100%" y2="0%">
5 <stop offset="0%" stop-color="#00FF41" />
6 <stop offset="50%" stop-color="#4FC3F7" />
7 <stop offset="100%" stop-color="#C084FC" />
8 </linearGradient>
9
10 <!-- Radial gradient -->
11 <radialGradient id="rg" cx="50%" cy="50%" r="50%">
12 <stop offset="0%" stop-color="#FFD93D" />
13 <stop offset="100%" stop-color="#FF6B6B" />
14 </radialGradient>
15
16 <!-- Pattern -->
17 <pattern id="dots" patternUnits="userSpaceOnUse"
18 width="20" height="20">
19 <circle cx="10" cy="10" r="4" fill="#00FF41" />
20 </pattern>
21 </defs>
22
23 <!-- Apply gradients -->
24 <rect x="20" y="20" width="160" height="80" rx="10"
25 fill="url(#lg)" />
26 <circle cx="290" cy="60" r="50" fill="url(#rg)" />
27
28 <!-- Apply pattern -->
29 <rect x="20" y="120" width="360" height="60" rx="8"
30 fill="url(#dots)" />
31</svg>

info

The <stop> elements define color transitions. You can specify stop-opacity for partial transparency. Use gradientTransform to rotate or scale the gradient.
preview
Text

SVG text elements provide more layout control than HTML text, including the ability to position individual characters and render text along paths.

text.svg
SVG
1<svg viewBox="0 0 500 200" xmlns="http://www.w3.org/2000/svg">
2 <!-- Basic text -->
3 <text x="20" y="40" fill="#00FF41" font-size="24"
4 font-family="monospace" font-weight="bold">
5 SVG Text Rendering
6 </text>
7
8 <!-- Text with tspan for mixed styles -->
9 <text x="20" y="80" fill="#A0A0A0" font-size="14" font-family="monospace">
10 <tspan fill="#00FF41">SVG</tspan> supports
11 <tspan fill="#FFD93D" font-weight="bold">mixed</tspan>
12 <tspan fill="#4FC3F7" font-style="italic">styles</tspan>
13 <tspan dy="20" x="20" fill="#525252">and multi-line text.</tspan>
14 </text>
15
16 <!-- Text along a path -->
17 <defs>
18 <path id="curve" d="M20,150 Q250,50 480,150" fill="none" />
19 </defs>
20 <use href="#curve" stroke="#2A2A3E" stroke-dasharray="4,4" />
21 <text font-family="monospace" font-size="14" fill="#C084FC">
22 <textPath href="#curve">
23 Text follows any SVG path — including curves and arcs
24 </textPath>
25 </text>
26</svg>
🔥

pro tip

Use <tspan> for multi-line text positioning. The dy attribute shifts the baseline vertically, and x resets the horizontal position. The <textPath> element lets text follow any path shape.
preview
Grouping & Reuse

SVG provides powerful mechanisms for organizing and reusing graphics. <g> groups elements, <defs> defines reusable assets, <use> instantiates them, and <symbol> creates standalone icons.

grouping-reuse.svg
SVG
1<svg viewBox="0 0 500 200" xmlns="http://www.w3.org/2000/svg">
2 <defs>
3 <!-- Reusable icon definition -->
4 <g id="star">
5 <polygon points="0,-10 3,-3 10,-3 5,2 7,10 0,5 -7,10 -5,2 -10,-3 -3,-3"
6 fill="#FFD93D" />
7 </g>
8
9 <!-- Symbol with viewBox (for icon systems) -->
10 <symbol id="icon-heart" viewBox="0 0 24 24">
11 <path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5
12 C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08
13 C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5
14 C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
15 fill="#FF6B6B" />
16 </symbol>
17 </defs>
18
19 <!-- Group -->
20 <g stroke="#FFFFFF" stroke-width="1" opacity="0.9">
21 <circle cx="50" cy="50" r="20" fill="#4FC3F7" />
22 <rect x="90" y="30" width="40" height="40" rx="5" fill="#00FF41" />
23 </g>
24
25 <!-- Use instances of the star -->
26 <use href="#star" x="200" y="30" />
27 <use href="#star" x="250" y="50" transform="scale(1.5)" />
28 <use href="#star" x="320" y="30" opacity="0.5" />
29
30 <!-- Symbol usage -->
31 <use href="#icon-heart" x="400" y="20" width="30" height="30" />
32 <use href="#icon-heart" x="440" y="30" width="20" height="20" />
33</svg>

The difference between <symbol> and <g> inside <defs>:

Feature<symbol><g> in <defs>
Has own viewBox
Renders when used
Supports width/height on use
Best for icon systems
Hidden by default

best practice

For SVG icon systems, define each icon as a <symbol> with a viewBox. Reference them with <use href="#icon-name" />. This keeps the DOM clean and enables centralized styling.
preview
Transformations

SVG transformations modify the coordinate system of an element or group. The transform attribute accepts multiple transformation functions.

FunctionParametersDescription
translatetx, tyMoves element by offset
rotateangle [, cx, cy]Rotates around origin or given point
scalesx [, sy]Scales x and y axes
skewXangleShear along x-axis
skewYangleShear along y-axis
matrixa, b, c, d, e, fFull 2×3 affine transform matrix
transforms.svg
SVG
1<svg viewBox="0 0 500 200" xmlns="http://www.w3.org/2000/svg">
2 <!-- Original reference -->
3 <rect x="20" y="20" width="40" height="40" fill="#2A2A3E" />
4 <text x="20" y="75" fill="#525252" font-size="10" font-family="monospace">Original</text>
5
6 <!-- Translate -->
7 <g transform="translate(120, 20)">
8 <rect x="0" y="0" width="40" height="40" fill="#00FF41" />
9 <text x="0" y="55" fill="#A0A0A0" font-size="10" font-family="monospace">translate</text>
10 </g>
11
12 <!-- Rotate -->
13 <g transform="translate(220, 40) rotate(45)">
14 <rect x="-20" y="-20" width="40" height="40" fill="#4FC3F7" />
15 <text x="-20" y="-30" fill="#A0A0A0" font-size="10" font-family="monospace">rotate</text>
16 </g>
17
18 <!-- Scale -->
19 <g transform="translate(330, 10) scale(1.5)">
20 <rect x="0" y="0" width="30" height="30" fill="#FFD93D" />
21 <text x="0" y="45" fill="#A0A0A0" font-size="8" font-family="monospace">scale</text>
22 </g>
23
24 <!-- Matrix -->
25 <g transform="matrix(1, 0.3, 0.2, 1, 400, 20)">
26 <rect x="0" y="0" width="40" height="40" fill="#C084FC" />
27 <text x="0" y="55" fill="#A0A0A0" font-size="10" font-family="monospace">matrix</text>
28 </g>
29
30 <!-- Transform-origin (CSS) -->
31 <rect x="20" y="120" width="50" height="50" rx="5"
32 fill="#FF6B6B" style="transform-origin: 25px 25px; transform: rotate(15deg);"
33 />
34 <text x="20" y="185" fill="#A0A0A0" font-size="10" font-family="monospace">CSS transform-origin</text>
35</svg>

info

SVG transforms apply right-to-left. When you write transform="translate(x, y) rotate(a)", the rotation happens first in the local coordinate system, then the translation moves the result. This is the reverse of Canvas 2D transformations.
Animation

SVG supports animation via SMIL (Synchronized Multimedia Integration Language) and CSS animations. SMIL is native to SVG and works without JavaScript.

SMIL Animation
smil.svg
SVG
1<svg viewBox="0 0 400 150" xmlns="http://www.w3.org/2000/svg">
2 <!-- animate — interpolate attribute over time -->
3 <circle cx="50" cy="75" r="20" fill="#00FF41">
4 <animate
5 attributeName="cx"
6 from="50" to="350"
7 dur="3s" repeatCount="indefinite"
8 values="50; 350; 50"
9 keyTimes="0; 0.5; 1" />
10 </circle>
11
12 <!-- animateTransform — rotate continuously -->
13 <rect x="50" y="20" width="30" height="30" fill="#FFD93D">
14 <animateTransform
15 attributeName="transform"
16 type="rotate"
17 from="0 65 35" to="360 65 35"
18 dur="2s" repeatCount="indefinite" />
19 </rect>
20
21 <!-- animateTransform — pulsing scale -->
22 <circle cx="300" cy="75" r="15" fill="#FF6B6B">
23 <animateTransform
24 attributeName="transform"
25 type="scale"
26 values="1; 1.5; 1"
27 keyTimes="0; 0.5; 1"
28 dur="1s" repeatCount="indefinite" />
29 </circle>
30</svg>
CSS Animation

SVG elements can be animated with standard CSS animations and transitions, just like HTML elements. This is often more maintainable than SMIL for complex animations.

css-animation.svg
SVG
1<svg viewBox="0 0 400 150" xmlns="http://www.w3.org/2000/svg">
2 <style>
3 .pulse {
4 animation: pulse 2s ease-in-out infinite;
5 transform-origin: center;
6 }
7 .bounce {
8 animation: bounce 1.5s ease-in-out infinite;
9 }
10 .fade {
11 animation: fade 3s ease-in-out infinite;
12 }
13 .spin {
14 animation: spin 3s linear infinite;
15 transform-origin: 350px 75px;
16 }
17 @keyframes pulse {
18 0%, 100% { r: 15; opacity: 1; }
19 50% { r: 25; opacity: 0.5; }
20 }
21 @keyframes bounce {
22 0%, 100% { transform: translateY(0); }
23 50% { transform: translateY(-30px); }
24 }
25 @keyframes fade {
26 0%, 100% { opacity: 1; }
27 50% { opacity: 0.2; }
28 }
29 @keyframes spin {
30 from { transform: rotate(0deg); }
31 to { transform: rotate(360deg); }
32 }
33 </style>
34
35 <circle cx="60" cy="100" r="15" fill="#00FF41" class="pulse" />
36 <rect x="130" y="80" width="30" height="30" rx="4"
37 fill="#4FC3F7" class="bounce" />
38 <circle cx="230" cy="100" r="15" fill="#C084FC" class="fade" />
39 <rect x="330" y="60" width="30" height="30" rx="4"
40 fill="#FFD93D" class="spin" />
41</svg>

best practice

CSS animations on SVG are more performant than SMIL in modern browsers because they can be offloaded to the GPU compositor thread. Use CSS for simple transforms and opacity changes. Use SMIL when you need to animate SVG-specific attributes like d (path data).
preview
Responsive SVG

SVG scales infinitely without losing quality. The viewBox attribute defines a logical coordinate system, preserveAspectRatio controls how it fits the container, and omitting width/height makes SVG fluid.

responsive.svg
SVG
1<!-- Fluid SVG — scales to container width -->
2<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
3 <rect x="0" y="0" width="400" height="200" fill="#1A1A2E" rx="10" />
4 <circle cx="200" cy="100" r="60" fill="#00FF41" opacity="0.3" />
5 <text x="200" y="105" fill="#00FF41" font-size="24"
6 font-family="monospace" text-anchor="middle">
7 Responsive SVG
8 </text>
9</svg>
10
11<!-- Fixed size SVG -->
12<svg viewBox="0 0 100 100" width="50" height="50" xmlns="...">
13 <!-- Icon at fixed 50x50px -->
14</svg>
15
16<!-- preserveAspectRatio options -->
17<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"
18 style="width: 100%; height: auto;">
19 <!-- Fits within container, centered, maintaining aspect ratio -->
20</svg>

preserveAspectRatio combines alignment and meet/slice:

ValueBehavior
xMidYMid meetFit entirely, centered (default)
xMinYMin meetFit entirely, top-left aligned
xMidYMid sliceCover container, centered (crop excess)
noneIgnore aspect ratio, stretch to fill
🔥

pro tip

To make an SVG truly responsive, set width="100%" and height="auto" (or omit them entirely) and always define a viewBox. Without a viewBox, the SVG will not scale correctly.
Accessibility

SVG elements can be made accessible to screen readers through proper title, description, and ARIA attributes. This is critical for data visualizations, icons, and diagrams.

accessible.svg
SVG
1<!-- Accessible chart -->
2<svg viewBox="0 0 400 300" role="img"
3 aria-label="Bar chart showing Q1 sales: January $5k, February $7k, March $6k"
4 xmlns="http://www.w3.org/2000/svg">
5
6 <title>Q1 2026 Sales Report</title>
7 <desc>
8 Bar chart displaying monthly sales for the first quarter.
9 January: $5,000. February: $7,000. March: $6,000.
10 </desc>
11
12 <!-- Bars with descriptive labels -->
13 <rect x="50" y="200" width="60" height="100"
14 fill="#00FF41" role="img"
15 aria-label="January: $5,000" />
16 <rect x="150" y="140" width="60" height="160"
17 fill="#4FC3F7" role="img"
18 aria-label="February: $7,000" />
19 <rect x="250" y="160" width="60" height="140"
20 fill="#C084FC" role="img"
21 aria-label="March: $6,000" />
22</svg>
23
24<!-- Icons should be hidden from screen readers -->
25<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
26 <path d="..." />
27</svg>

info

Decorative icons should have aria-hidden="true" and focusable="false". Informative graphics (charts, diagrams) need role="img" with aria-label or nested <title> and <desc> elements.
Best Practices
Optimization
optimization.svg
SVG
1<!-- Before: bloated (from vector editor) -->
2<svg viewBox="0 0 100 100">
3 <g id="Layer_1">
4 <path d="M10,10 L90,10 L90,90 L10,90 Z"
5 fill="#00FF41" stroke="#000000" stroke-width="2"/>
6 </g>
7</svg>
8
9<!-- After: optimized -->
10<svg viewBox="0 0 100 100">
11 <rect x="10" y="10" width="80" height="80" fill="#00FF41" />
12</svg>
13
14<!-- Icon sprite system -->
15<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
16 <symbol id="icon-check" viewBox="0 0 24 24">
17 <path d="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41-1.41Z"/>
18 </symbol>
19 <symbol id="icon-close" viewBox="0 0 24 24">
20 <path d="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12Z"/>
21 </symbol>
22</svg>
23<svg viewBox="0 0 24 24" width="20" height="20"><use href="#icon-check"/></svg>

Key optimization strategies:

Run SVGO or similar tools to remove editor metadata and reduce file size
Use <symbol> sprites for icon systems — one HTTP request instead of many
Replace complex paths with simple shapes where possible
Group common styles with CSS classes instead of repeating attributes
Use viewBox-based sizing instead of fixed pixel dimensions for scalability
Avoid embedded raster images — they defeat SVG's purpose
Compress SVG with gzip/Brotli (SVG compresses extremely well)
Inline critical SVGs (hero images, logos) to avoid extra HTTP requests
Use vector editing tools that produce clean output (Figma, Illustrator)
Always define explicit dimensions or viewBox for layout stability

best practice

SVG and Canvas serve different purposes. Use SVG for resolution-independent graphics with DOM interaction (icons, logos, data viz annotations). Use Canvas for pixel-level control and high-performance rendering (games, image processing, particle effects). When in doubt, SVG is often the simpler and more accessible choice.
$Blueprint — Engineering Documentation·Section ID: HTML-SVG·Revision: 1.0