--- id: frontend-svg-patterns title: SVG — Scaling / Animation / Sprite / React category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [frontend, svg, vector, vibe-coding] tech_stack: { language: "SVG / CSS / TS", applicable_to: ["Frontend"] } applied_in: [] aliases: [SVG, vector graphics, SVG sprite, viewBox, lucide-react, animation] --- # SVG Patterns > Vector graphics. **Scalable, small, scriptable, themeable**. Icon / illustration / chart / animation. PNG 보다 거의 항상 좋음 (단순 graphic). ## 📖 핵심 개념 - viewBox: coordinate system. - preserveAspectRatio: scaling. - currentColor: 부모 색 따름. - Sprite: 여러 icon 한 file. ## 💻 코드 패턴 ### 기본 SVG ```html Hi ``` ### viewBox 가 핵심 ```html ``` → Scalable. CSS 로 size 제어. ### currentColor (theme 친화) ```html ``` ```css .icon { color: blue; } /* SVG fill 도 blue */ .icon:hover { color: red; } /* 자동 hover */ ``` → 부모 color 따름. Theme / dark mode 자동. ### Inline SVG (modern) ```tsx function CheckIcon() { return ( ); } ``` ### lucide-react (icon library) ```bash yarn add lucide-react ``` ```tsx import { Heart, Home, Settings, ChevronRight } from 'lucide-react'; ``` → Tree-shakable. 큰 set. ### Icon system (자체) ```tsx // icons/index.ts export { default as CheckIcon } from './check.svg'; export { default as CloseIcon } from './close.svg'; // ... // 사용 import { CheckIcon } from '@/icons'; ``` ```ts // vite.config.ts — SVG → React import svgr from 'vite-plugin-svgr'; plugins: [svgr()]; ``` → SVG file → React component 자동. ### SVG sprite (1 fetch, 많은 icon) ```html ``` → 한 fetch — cache. 100 icon 도 OK. ### Stroke-based icon ```html ``` → Lucide / Tabler / Phosphor 의 style. ### Filled icon ```html ``` → Solid icon (Material). ### CSS animation ```html ``` ```css .loader { stroke-dasharray: 60; stroke-dashoffset: 0; animation: loading 1s linear infinite; } @keyframes loading { to { stroke-dashoffset: 60; } } ``` → SVG path = stroke-dash. ### SMIL animation (built-in) ```html ``` → JS 없이 animation. Browser 지원 OK. ### Path morphing (SVGator / GSAP / Lottie) ```ts // Path A → Path B gsap.to('#shape', { attr: { d: 'M10,10 L90,90' }, duration: 1, }); ``` ### Logo / illustration ``` Vector design tools: - Figma → SVG export - Illustrator - Inkscape (OSS) → Path / shape 직접 export. ``` ### Optimization ```bash # SVGO npx svgo input.svg npx svgo *.svg # 또는 SVGOMG (web) ``` → 50% 작아지는 보통 — comments / metadata 제거. ### React + SVG ```tsx // Inline (small icons) // React component (vite-plugin-svgr) import Icon from './icon.svg?react'; // img tag (큰 / 변동 X) Logo // 또는 url import logoUrl from './logo.svg'; Logo ``` → Inline = themeable. img = cacheable. ### Charts (SVG-based) ```ts // d3 / visx — SVG 직접 const path = d3.line()(data.map(d => [d.x, d.y])); return ; ``` → SVG = chart 의 자연. ### Patterns / gradients ```html ``` ### Filters ```html Shadow ``` ### A11y ```html Heart icon ``` → Screen reader 친화. ### 1-line / Tailwind utility ```html ... ``` → Tailwind 가 SVG 자연. ### MathML / chart 기타 ``` SVG: 자유 형식 vector. Canvas: pixel — 큰 rendering. WebGL: 3D / GPU. → Static / scalable / theme-friendly = SVG. ``` ### Use cases ``` - Icon (Lucide / Heroicons) - Logo - Chart (D3 / Visx) - Illustration - Loading spinner - Diagram (Mermaid / draw.io) - Map / floor plan ``` ### Bundle size ``` Inline SVG icon: ~500 bytes PNG @1x / @2x / @3x: 5-50 KB → Icon = SVG 거의 항상. ``` ### Generate at build ```ts // 자동 component generation import { generateSvgComponents } from 'svg-to-jsx'; generateSvgComponents('./icons/', './src/components/icons/'); ``` ### Optimization (icon font 보다) ``` Icon font: + 1 file load - A11y 약함 - Fixed color 어려움 - CSS 만 styling SVG sprite / inline: + A11y OK + 색 / size 자유 + Animation 가능 + Better fallback → 2024+ = SVG 가 더 좋음. ``` ### Common 사이즈 ``` size-4 (16px): inline text icon size-5 (20px): button icon size-6 (24px): main icon size-8 (32px): large size-12 (48px): hero ``` ### Colored icons (multi-color) ```svg ``` → Theme 어려움. CSS variable 사용: ```svg ``` ## 🤔 의사결정 기준 | 사용 | 추천 | |---|---| | Icon system | Lucide / 자체 SVG sprite | | Logo | Inline SVG | | Chart | SVG (D3 / Visx) | | Illustration | SVG | | Photo | PNG / WebP / AVIF | | 3D | WebGL / Three.js | ## ❌ 안티패턴 - **viewBox 없음**: 안 scale. - **Hard-coded color**: theme X. currentColor. - **PNG icon (multi-resolution)**: 매 size 별 file. SVG 하나면. - **Inline SVG 큰 (100+ path)**: HTML bloat. external file. - **No optimization (raw export)**: 50% 큰. - **A11y 무시**: title / aria-label. ## 🤖 LLM 활용 힌트 - viewBox + currentColor + sprite. - Lucide / Heroicons / Tabler 가 modern. - SVGO 자동 optimize. - vite-plugin-svgr = React component. ## 🔗 관련 문서 - [[Frontend_Image_Optimization]] - [[React_Charts_Library_Comparison]] - [[Frontend_A11y_Testing]]