Chapter 16: SVG Fill
SVG Fill — one of the most important things when you’re coloring shapes in SVG!
Imagine we’re sitting together with the code editor open, and I’m your patient teacher who’s going to explain everything step by step, like we’re building colorful drawings from scratch. We’ll go slow, with many copy-paste examples.
What does “fill” actually mean in SVG?
fill = the color (or pattern/gradient) that paints the inside of a shape.
- Applies to: closed shapes like <rect>, <circle>, <ellipse>, <polygon>, <path> (when closed with Z), and also to text (<text>, <tspan>, <textPath>)
- Does not apply to: open paths like <line>, <polyline> (they have no “inside” — only stroke)
- Default value: black (#000000)
You set it in two main ways:
-
As an attribute directly on the element (most common when learning):
HTML0123456<circle cx="100" cy="100" r="60" fill="orange" /> -
As a CSS property (very powerful for styling many elements at once):
CSS0123456.my-shape { fill: #2196F3; }HTML0123456<rect class="my-shape" x="20" y="20" width="160" height="100" />
Basic fill values (colors)
SVG accepts almost all the same color formats as CSS:
| Type | Example value | Code snippet |
|---|---|---|
| Named color | red, lime, teal | fill=”tomato” |
| Hex | #f44336, #4CAF50 | fill=”#673AB7″ |
| RGB | rgb(255, 99, 71) | fill=”rgb(100, 200, 50)” |
| RGBA (with opacity) | rgba(255, 0, 0, 0.6) | fill=”rgba(0, 128, 255, 0.7)” |
| HSL | hsl(120, 100%, 50%) | fill=”hsl(45, 100%, 50%)” |
| currentColor | currentColor | fill=”currentColor” (inherits from CSS color) |
Super useful trick — currentColor This makes SVG icons change color automatically when you style the parent element.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<style> .icon { color: #FF5722; } .icon:hover { color: #4CAF50; } </style> <svg class="icon" width="80" height="80"> <circle cx="40" cy="40" r="35" fill="currentColor"/> </svg> |
Hover → color changes magically!
Fill opacity (separate control)
You can control transparency of only the fill (without affecting stroke) using:
- fill-opacity=”0.5″ (attribute)
- fill-opacity: 0.7; (CSS)
Example:
|
0 1 2 3 4 5 6 7 8 9 |
<svg width="300" height="180"> <rect x="40" y="40" width="220" height="100" fill="#2196F3" fill-opacity="0.4"/> <rect x="100" y="80" width="140" height="80" fill="#F44336" fill-opacity="0.7"/> </svg> |
Advanced fills: Gradients & Patterns
The real power starts here — fill can reference paint servers (special definitions in <defs>).
- Linear Gradient (straight color transition)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<svg width="400" height="200"> <defs> <linearGradient id="myGrad" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" stop-color="#FFEB3B"/> <stop offset="50%" stop-color="#FF9800"/> <stop offset="100%" stop-color="#F44336"/> </linearGradient> </defs> <rect x="50" y="50" width="300" height="100" fill="url(#myGrad)" rx="12"/> </svg> |
- Radial Gradient (circular/spreading from center)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<svg width="220" height="220"> <defs> <radialGradient id="glow" cx="50%" cy="50%" r="70%"> <stop offset="0%" stop-color="white"/> <stop offset="100%" stop-color="#673AB7"/> </radialGradient> </defs> <circle cx="110" cy="110" r="90" fill="url(#glow)"/> </svg> |
- Pattern (repeating tiles — like dots, stripes, checkerboard)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<svg width="300" height="200"> <defs> <pattern id="dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"> <circle cx="5" cy="5" r="3" fill="#009688"/> </pattern> </defs> <rect x="30" y="30" width="240" height="140" fill="url(#dots)" stroke="#009688" stroke-width="2"/> </svg> |
fill-rule — The “which parts are inside?” rule (very important!)
For complex paths (especially ones that cross themselves or have holes), fill-rule decides what counts as “inside”.
Two main values:
| Value | How it works | Best for | Default? |
|---|---|---|---|
| nonzero | Counts direction of path crossings (clockwise/counterclockwise matters) | Most simple shapes, solid icons | Yes |
| evenodd | Counts crossings — odd = inside, even = outside (ignores direction) | Holes, stars, overlapping shapes | No |
Classic example — star with hole:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<svg width="220" height="220"> <path d="M110,10 L135,80 210,80 150,130 175,200 110,160 45,200 70,130 10,80 85,80 Z" fill="#F44336" fill-rule="evenodd" /> <!-- Try changing to "nonzero" → center fills differently --> </svg> |
With evenodd → center hole stays empty. With nonzero → center fills (depending on path direction).
Here are visual comparisons of fill-rule behavior (imagine seeing these side by side):
- Left: star with evenodd (hole visible)
- Right: same path with nonzero (center filled)
Quick Cheat Sheet
| Goal | Use this… |
|---|---|
| Solid color | fill=”purple” or fill=”#673AB7″ |
| Semi-transparent fill | fill-opacity=”0.6″ |
| Color changes with parent | fill=”currentColor” |
| Rainbow/striped effect | <linearGradient> or <pattern> |
| Shape with hole / cut-out | fill-rule=”evenodd” |
| No fill (only stroke) | fill=”none” |
Common beginner mistakes
- Forget fill → defaults to black (not transparent!)
- Set fill=”none” but want background → use <rect> behind or CSS background
- Use fill on <line> or <polyline> → does nothing (they’re open)
- Gradient/pattern not showing → forgot id or wrong url(#id)
- Complex path fills wrong → try switching fill-rule
Mini practice for you
- Make a rectangle with a horizontal rainbow gradient
- Create a circle with radial gradient (white center → dark edge)
- Draw a star <polygon> or <path> and use evenodd vs nonzero to see the difference
Paste your code here if you want feedback — I’ll check it like we’re debugging together 😊
Any part still confusing? Gradients? Patterns? currentColor? fill-rule weirdness? Just tell me — we’ll zoom in with more examples until it’s crystal clear! 🚀
