Chapter 20: SVG Drop Shadow 1
Why “Drop Shadow 1”?
There are two main ways to make drop shadows in SVG in 2025–2026:
- Drop Shadow 1 (classic method) → Uses <feGaussianBlur> + <feOffset> + <feMerge> → More steps, but very explicit and works perfectly everywhere (even older browsers)
- Drop Shadow 2 (modern SVG 2 method) → Uses the single <feDropShadow> primitive → Shorter code, easier to read, but slightly less flexible in some edge cases
Today we’re mastering Drop Shadow 1 — the foundational technique.
Step-by-step logic of a classic drop shadow
A realistic drop shadow usually needs these layers:
- Take the shape’s silhouette (alpha channel only)
- Blur it softly (Gaussian blur) → this creates the soft edge of the shadow
- Offset (shift) the blurred silhouette down and to the right (or any direction)
- Color it (usually gray/black with some transparency)
- Merge the shadow layer behind the original graphic
The Classic Drop Shadow Recipe (most common pattern)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<svg width="320" height="220" style="border:1px solid #eee; background:#f9f9f9;"> <defs> <filter id="dropShadowClassic" x="-50%" y="-50%" width="200%" height="200%"> <!-- Step 1: Blur the alpha channel (shape outline) --> <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/> <!-- Step 2: Offset the blurred shadow --> <feOffset in="blur" dx="6" dy="6" result="offsetBlur"/> <!-- Step 3: Optional – color the shadow (flood + composite) --> <feFlood flood-color="#000" flood-opacity="0.4" result="shadowColor"/> <feComposite in="shadowColor" in2="offsetBlur" operator="in" result="coloredShadow"/> <!-- Step 4: Merge shadow behind original graphic --> <feMerge> <feMergeNode in="coloredShadow"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <rect x="60" y="60" width="200" height="100" rx="12" fill="#2196F3" filter="url(#dropShadowClassic)"/> <text x="160" y="110" font-size="38" text-anchor="middle" fill="white"> Classic Shadow </text> </svg> |
Breaking down each part
- x=”-50%” y=”-50%” width=”200%” height=”200%” on <filter> → Very important! Prevents the shadow from being clipped when it extends outside the original bounding box.
- <feGaussianBlur in=”SourceAlpha” stdDeviation=”4″ result=”blur”/> → Blurs only the shape (not colors inside) → perfect for shadow base → stdDeviation=”4″ ≈ soft shadow (try 2 = hard, 8 = very soft)
- <feOffset in=”blur” dx=”6″ dy=”6″ result=”offsetBlur”/> → Shifts shadow right 6 units, down 6 units → Change dx/dy to move shadow direction (negative = left/up)
- <feFlood flood-color=”#000″ flood-opacity=”0.4″/> + <feComposite … operator=”in”/> → Colors the shadow black with 40% opacity → You can skip this and use flood-color directly in some cases, but this pattern is very safe
- <feMerge> → Puts shadow first (behind), then original graphic on top → Order matters — shadow must come before SourceGraphic
Example 2 – Simpler version (no explicit color flood – still very popular)
Many people skip the <feFlood> + <feComposite> and just let the blur carry the opacity:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<svg width="280" height="180"> <defs> <filter id="simpleShadow" x="-40%" y="-40%" width="180%" height="180%"> <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/> <feOffset in="blur" dx="4" dy="4" result="offset"/> <feMerge> <feMergeNode in="offset"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <circle cx="140" cy="90" r="60" fill="#FF5722" filter="url(#simpleShadow)"/> </svg> |
→ Shadow is black by default (inherits from <feGaussianBlur> behavior on alpha)
Example 3 – Drop shadow on text (super common use case)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<svg width="420" height="160"> <defs> <filter id="textShadow"> <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/> <feOffset in="blur" dx="3" dy="3" result="offset"/> <feMerge> <feMergeNode in="offset"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <text x="210" y="100" font-size="68" font-weight="bold" text-anchor="middle" fill="#673AB7" filter="url(#textShadow)"> SVG Rocks </text> </svg> |
Quick tuning guide
| Shadow style | Suggested settings |
|---|---|
| Soft & distant | stdDeviation=”6–10″, dx/dy=”8 8″, opacity 0.3–0.5 |
| Hard / flat | stdDeviation=”1–2″, dx/dy=”3 3″, opacity 0.6–0.8 |
| Subtle modern UI | stdDeviation=”3″, dx/dy=”2 4″, opacity 0.25 |
| Colored shadow | Add <feFlood flood-color=”#ff4081″ flood-opacity=”0.35″/> |
Common beginner mistakes
- Forget to expand filter region → shadow cut off
- Use in=”SourceGraphic” instead of SourceAlpha → colors get blurred too (ugly)
- No <feMerge> → only shadow appears, original graphic disappears
- Small stdDeviation on huge shape → shadow looks too sharp
- No opacity control → shadow too dark/black
Mini practice tasks
- Give a rounded rectangle a soft purple-tinted shadow (use flood-color)
- Make text with a very subtle shadow (low opacity, small offset)
- Create two circles: one with hard shadow, one with very soft/distant shadow
Paste your code here if you want feedback — I’ll review it like we’re pair-coding together 😄
This is the classic Drop Shadow 1 method — rock-solid and still used everywhere in 2026. Next lesson we can compare it directly to the modern <feDropShadow> (Drop Shadow 2) and see when to choose which.
Any part confusing? The merge step? Why SourceAlpha? Opacity control? Just tell me — we’ll redraw examples bigger/slower until it’s crystal clear! 🚀
