Basic Shapes
SVG gives you a small kit of primitive shapes. Each has its own tag with coordinates and dimensions as attributes. The viewBox sets the internal coordinate system — unrelated to the rendered pixel size.
<svg width="320" height="220" viewBox="0 0 320 220">
<!-- RECT: x/y = top-left, rx = corner radius -->
<rect x="20" y="20" width="80" height="80"
fill="#22d3ee" rx="10"/>
<!-- CIRCLE: cx/cy = center, r = radius -->
<circle cx="180" cy="60" r="40" fill="#d946ef"/>
<!-- ELLIPSE: rx/ry = horizontal / vertical radius -->
<ellipse cx="260" cy="60" rx="30" ry="50" fill="#fcd34d"/>
<!-- LINE: x1/y1 to x2/y2, stroke styles the line -->
<line x1="20" y1="160" x2="300" y2="160"
stroke="#ec4899" stroke-width="4" stroke-linecap="round"/>
<!-- stroke-dasharray creates a dashed line -->
<line x1="20" y1="190" x2="300" y2="190"
stroke="#10b981" stroke-width="4"
stroke-dasharray="8 6"/>
</svg>
Paths & Commands
The <path> element can draw any shape at all. It takes a single d attribute made of commands. The important ones: M move, L line, C cubic curve, Q quadratic curve, Z close. Uppercase = absolute coords, lowercase = relative.
<svg viewBox="0 0 320 220">
<!-- TRIANGLE: Move to (30,180), Line to two more points,
Z closes back to the start -->
<path d="M 30 180 L 80 30 L 130 180 Z"
fill="#22d3ee"/>
<!-- HEART via Cubic Bezier (C) curves -->
<path d="M 200 60
C 200 40, 230 40, 230 65
C 230 40, 260 40, 260 60
C 260 90, 230 110, 230 130
C 230 110, 200 90, 200 60
Z"
fill="#ec4899"/>
<!-- WAVE via Quadratic (Q) + shortcut T -->
<path d="M 30 200 Q 80 160, 130 200 T 230 200 T 290 200"
fill="none" stroke="#fcd34d" stroke-width="4"/>
</svg>
Polygon & Polyline
Easier siblings of <path>. Polygon connects a list of points and closes the shape automatically. Polyline does the same but leaves it open — great for charts and arrows.
<svg viewBox="0 0 320 200">
<!-- STAR: 10 points around the outline — polygon
connects them all AND closes the shape -->
<polygon
points="80,20 96,68 148,68 106,100 122,148
80,120 38,148 54,100 12,68 64,68"
fill="#fcd34d" stroke="#b45309" stroke-width="2"/>
<!-- ARROW: same idea, different points -->
<polygon points="180,100 240,60 240,90 290,90
290,110 240,110 240,140"
fill="#22d3ee"/>
<!-- POLYLINE: open line — good for line charts -->
<polyline
points="20,190 60,150 100,170 140,120 180,140 220,90"
fill="none" stroke="#ec4899" stroke-width="3"/>
</svg>
SVG Text
Text inside SVG can be filled, stroked, rotated, and even placed along a path. Useful for logos and playful headings where regular HTML text can't bend.
<svg viewBox="0 0 320 220">
<!-- Outlined text: fill="none" + stroke -->
<text x="160" y="50" text-anchor="middle"
font-family="DM Serif Display, serif" font-size="38"
fill="none" stroke="#22d3ee" stroke-width="1.5">
OUTLINED
</text>
<!-- Gradient-filled text -->
<defs>
<linearGradient id="txtGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#d946ef"/>
</linearGradient>
<path id="curvy" d="M 30 170 Q 160 120 290 170" fill="none"/>
</defs>
<text x="160" y="100" text-anchor="middle" font-size="34"
fill="url(#txtGrad)">GRADIENT</text>
<!-- TEXT on a PATH -->
<text font-size="22" fill="#fff">
<textPath href="#curvy" startOffset="50%" text-anchor="middle">
along a curve!
</textPath>
</text>
</svg>
Linear Gradient
Gradients in SVG live inside <defs> and get referenced by id. A gradient can be shared across any number of shapes — change the definition once, every shape using it updates.
<svg viewBox="0 0 320 200">
<defs>
<!-- Top to bottom: x1,y1 → x2,y2 define the direction.
(0,0) is top-left of each shape, (1,1) is bottom-right. -->
<linearGradient id="sunset" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fcd34d"/>
<stop offset="50%" stop-color="#f43f5e"/>
<stop offset="100%" stop-color="#7e22ce"/>
</linearGradient>
</defs>
<!-- Reuse the same gradient on any shape -->
<rect x="20" y="20" width="130" height="160"
rx="14" fill="url(#sunset)"/>
<circle cx="235" cy="100" r="70" fill="url(#sunset)"/>
</svg>
Radial Gradient
Great for spotlights, soft shadows, and planet/orb effects. The gradient radiates outward from a center point.
<svg viewBox="0 0 320 220">
<defs>
<!-- cx/cy = where the "light source" is inside the shape
(35% from left, 35% from top = upper-left highlight). -->
<radialGradient id="orb" cx="35%" cy="35%" r="65%">
<stop offset="0%" stop-color="#fff"/>
<stop offset="30%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#0e7490"/>
</radialGradient>
<!-- Flame fades to transparent at the edges -->
<radialGradient id="flame" cx="50%" cy="70%" r="55%">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="40%" stop-color="#f97316"/>
<stop offset="100%" stop-color="#7c2d12" stop-opacity="0"/>
</radialGradient>
</defs>
<circle cx="100" cy="110" r="70" fill="url(#orb)"/>
<circle cx="230" cy="110" r="70" fill="url(#flame)"/>
</svg>
CSS Styling & Hover
SVG responds to CSS just like HTML. Fills, strokes, opacity, and transforms can all be transitioned on :hover — ideal for interactive diagrams and playful logos.
hover the blob →
<svg viewBox="0 0 220 220">
<path class="blob"
d="M 110,10 C 160,10 200,50 210,100
C 220,160 180,210 120,210
C 60,210 10,170 10,110
C 10,60 60,10 110,10 Z"/>
</svg>
Basic Draw Animation
The core trick behind every SVG draw-in effect. Set stroke-dasharray to the length of the stroke. Set stroke-dashoffset to that same length — the dash now covers the stroke, hiding it. Animate the offset down to 0 and the stroke appears to draw itself.
<svg viewBox="0 0 280 180">
<path class="draw"
d="M 30 100 Q 90 30 150 100 T 250 100"
fill="none" stroke="#22d3ee" stroke-width="4"
stroke-linecap="round"/>
</svg>
Signature Draw
A multi-path signature that draws stroke-by-stroke. Each path has a staggered animation-delay, so they appear to be written one at a time.
<svg class="sig-draw" viewBox="0 0 320 160">
<path d="M 30 30 L 30 110 Q 30 130 50 130 Q 70 130 70 110"/>
<path d="M 90 95 Q 90 60 120 60 Q 150 60 150 90 L 150 130
M 150 105 Q 130 135 100 130"/>
<path d="M 175 70 L 215 70 L 180 125 L 220 125"/>
<path d="M 235 70 L 280 70 L 240 125 L 285 125"/>
</svg>
Icon Trio — Check, Heart, Star
Three icons that draw themselves in sequence — first the outer ring, then the inner shape. Everything on the page that's a single SVG path can get this treatment. Great for a "success" moment or a delightful loading state.
<div class="icon-trio">
<svg class="icon-check" viewBox="0 0 100 100">
<circle class="icon-ring" cx="50" cy="50" r="40"/>
<polyline class="icon-shape" points="30,52 45,68 72,38"/>
</svg>
<svg class="icon-heart" viewBox="0 0 100 100">
<circle class="icon-ring" cx="50" cy="50" r="40"/>
<path class="icon-shape" d="M 50 72 C 30 58 22 48 22 38 ..."/>
</svg>
<svg class="icon-star" viewBox="0 0 100 100">
<circle class="icon-ring" cx="50" cy="50" r="40"/>
<polygon class="icon-shape" points="50,25 58,45 ..."/>
</svg>
</div>
Hand Lettering — Letter by Letter
Same trick, one path per letter. Each letter starts hidden and draws in after its predecessor. The effect really feels like someone is writing in real time.
<svg class="hand-svg" viewBox="0 0 340 120"> <!-- One <path> per letter --> <path class="letter" d="M 25 25 L 25 95 M 25 60 L 60 60 M 60 25 L 60 95"/> <!-- H --> <path class="letter" d="..."/> <!-- e --> <path class="letter" d="..."/> <!-- l --> <path class="letter" d="..."/> <!-- l --> <path class="letter" d="..."/> <!-- o --> <path class="letter" d="..."/> <!-- ! --> </svg>
Looping Draw
Instead of drawing once and stopping, the offset is animated through a full cycle — in from the start, then out the other side. Combined with a soft opacity fade, it looks like an ambient pen tracing the path forever.
<svg class="loop-draw" viewBox="0 0 300 200">
<path d="M 20 100
C 60 20, 120 20, 150 100
C 180 180, 240 180, 280 100"/>
</svg>