SVG Sprite ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด ๋‚˜๋งŒ์˜ ํŠน๋ณ„ํ•œ Icon ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ

SVG(Scalable Vector Graphics)๋Š” ์›น์—์„œ ๋ฒกํ„ฐ ๊ธฐ๋ฐ˜์˜ ๊ทธ๋ž˜ํ”ฝ์„ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” XML ๊ธฐ๋ฐ˜์˜ ๋งˆํฌ์—… ์–ธ์–ด์ž…๋‹ˆ๋‹ค.

Profile Picture
adultlee
2023-11-20

์›๋ณธ

์ €ํฌํŒ€ NDD๋Š” ๊ณฐํ„ฐ๋ทฐ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœ์ค‘์ž…๋‹ˆ๋‹ค!

์™œ SVG ํŒŒ์ผ ๊ด€๋ฆฌ๋Š” ๋ถˆํŽธํ–ˆ์„๊นŒ?

SVG(Scalable Vector Graphics)๋Š” ์›น์—์„œ ๋ฒกํ„ฐ ๊ธฐ๋ฐ˜์˜ ๊ทธ๋ž˜ํ”ฝ์„ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” XML ๊ธฐ๋ฐ˜์˜ ๋งˆํฌ์—… ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ๊นŒ์ง€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ด์œ ๋กœ SVG ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๋Š”๊ฒƒ์€ ์ €์—๊ฒ ๋ฌ˜ํ•˜๊ฒŒ ๊ฝค๋‚˜ ๊ท€์ฐฎ์€ ์ผ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ท€์ฐฎ์Œ์„ ํ•ด๊ฒฐ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” SVG์˜ ๊ธฐ๋ณธ์ ์ธ ํŠน์„ฑ๊ณผ FE์ธก๋ฉด์—์„œ SVG ํŒŒ์ผ์˜ ๊ธฐ๋ณธ์ ์ธ ์–ด๋ ค์›€์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์ˆ˜์˜ ํŒŒ์ผ ๊ด€๋ฆฌ ๊ธฐ์กด์˜ SVG ๊ด€๋ฆฌ ๋ฐฉ์‹์—์„œ๋Š” ๊ฐ๊ฐ์˜ SVG ์ด๋ฏธ์ง€๊ฐ€ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์›น์‚ฌ์ดํŠธ์— ๋‹ค์ˆ˜์˜ ์•„์ด์ฝ˜ ๋˜๋Š” ๊ทธ๋ž˜ํ”ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋“ค ๊ฐ๊ฐ์„ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ํŒŒ์ผ ์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๊ณ , ์ด๋“ค์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

  2. ๋„คํŠธ์›Œํฌ ์˜ค๋ฒ„ํ—ค๋“œ ์›น ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๋งˆ๋‹ค, ๊ฐ๊ฐ์˜ SVG ํŒŒ์ผ์— ๋Œ€ํ•œ ๋ณ„๋„์˜ HTTP ์š”์ฒญ์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ๋งŽ์€ ์ˆ˜์˜ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๊ฐ€ ์žˆ๋Š” ํŽ˜์ด์ง€์—์„œ ๋„คํŠธ์›Œํฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ ์›น์‚ฌ์ดํŠธ์˜ ๋กœ๋”ฉ ์‹œ๊ฐ„์— ์˜ํ–ฅ์„ ๋ฏธ์ณค์Šต๋‹ˆ๋‹ค.

  3. ์บ์‹ฑ์˜ ๋ณต์žก์„ฑ ๊ฐ๊ฐ์˜ SVG ํŒŒ์ผ์€ ๋…๋ฆฝ์ ์œผ๋กœ ์บ์‹œ๋˜์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์›น์‚ฌ์ดํŠธ์˜ ์บ์‹ฑ ์ „๋žต์„ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ํšจ์œจ์ ์ธ ์บ์‹œ ๊ด€๋ฆฌ๋ฅผ ์–ด๋ ต๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  4. ํ™•์žฅ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์˜ ๋ฌธ์ œ (ํŠนํžˆ๋‚˜ ์ค‘์š”ํ•œ...) ํ”„๋กœ์ ํŠธ๊ฐ€ ์„ฑ์žฅํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ๊ธฐ์กด์˜ ๊ฒƒ๋“ค์ด ๋ณ€๊ฒฝ๋  ๋•Œ, ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ์†Œ์š”๋˜๋Š” ์ž‘์—…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๊ฐ๊ฐ์˜ ํŒŒ์ผ์„ ์ถ”์ ํ•˜๊ณ  ๊ด€๋ฆฌํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜์˜ ๋ถ€๋‹ด์ด ์ปธ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด์˜ ๋ฐฉ์‹์€ ์–ด๋• ์ง€?

์ €ํฌ ํ”„๋กœ์ ํŠธ๋Š” webpack ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘์„ ํ•˜๊ณ  ์žˆ์—ˆ๊ณ , ์ˆ˜๋ฏผ๋‹˜์˜ ํ•ด๋‹น์ปค๋ฐ‹์—์„œ svgr์„ ์ถ”๊ฐ€ํ•œ๋•์— react์ฒ˜๋Ÿผ ์†์‰ฝ๊ฒŒ import ๋ฐ›์•„์„œ svg ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์ด์—ˆ์Šต๋‹ˆ๋‹ค. แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-11-15 แ„‹แ…ฉแ„’แ…ฎ 4 37 59 ๋‹ค์Œ์ฒ˜๋Ÿผ ์ƒ๋‹จ์—์„œ import ๋ฐ›์€ ํ›„ แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-11-15 แ„‹แ…ฉแ„’แ…ฎ 4 38 05

๋‹ค์Œ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์†์‰ฝ๊ฒŒ react ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋‹จ์ ์„ ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค..

1. ๋งŽ์•„์ง€๋Š” svg ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-11-15 แ„‹แ…ฉแ„’แ…ฎ 4 37 42 ํ”„๋กœ์ ํŠธ์˜ ์ดˆ๊ธฐ ๋‹จ๊ณ„์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  assets ๋‚ด๋ถ€์— svg๊ฐ€ ๋งŽ์ด ์ถ”๊ฐ€๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ํ”„๋กœ์ ํŠธ์˜ ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ฌ ๋ฟ ์•„๋‹ˆ๋ผ ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ• ๋•Œ๋งˆ๋‹ค ๊ฐ๊ธฐ๋‹ค๋ฅธ svgํŒŒ์ผ์„ load ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

2. ํ•œ ํŒŒ์ผ์—์„œ loadํ•ด์•ผํ•  ์ปดํฌ๋„ŒํŠธ์˜ ์ฆ๊ฐ€

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-11-15 แ„‹แ…ฉแ„’แ…ฎ 4 38 19

๋‹ค์Œ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ํ•œ ํŒŒ์ผ์—์„œ load ํ•ด์•ผํ•  svg ํŒŒ์ผ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ํŒŒ์ผ์˜ ์ƒ๋‹จ์—์„œ import ๋ฐ›๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

3. svg ํŒŒ์ผ์˜ ์ •๋ ฌ๋ฌธ์ œ...

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-11-15 แ„‹แ…ฉแ„’แ…ฎ 5 24 58 ๋ฌผ๋ก  ์ด๋ถ€๋ถ„์€ prettier ์„ค์ •์„ ํ†ตํ•ด์„œ ํ•ด์†Œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ํŠน๋ณ„ํ•˜๊ฒŒ ๋” ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ์ด๋ฏธ ์žˆ๋˜ ๊ทœ์น™ ๋‚ด๋ถ€์—์„œ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ €ํฌ๋Š” ๋” ์‰ฝ๊ฒŒ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๊ฐ€๋Šฅํ•œ Icon ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„์ž…ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€๋กœ ์š”์ฆ˜ preact ์˜ ๊ฐœ๋ฐœ์ž๋กœ ์œ ๋ช…ํ•˜์‹  "Jason Miller"๋‹˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ง์”€ํ•˜์…จ์Šต๋‹ˆ๋‹ค!

SVG๋ฅผ JSX๋กœ ๊ฐ€์ ธ์˜ค์ง€ ๋งˆ์„ธ์š”. ์ด ๋ฐฉ๋ฒ•์€ ์Šคํ”„๋ผ์ดํŠธ ์‹œํŠธ ์ค‘์—์„œ ๊ฐ€์žฅ ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค: ๋‹ค๋ฅธ ๊ธฐ๋ฒ•๋“ค๋ณด๋‹ค ์ตœ์†Œ 3๋ฐฐ ์ด์ƒ์˜ ๋น„์šฉ์ด ๋“ค๊ณ , ์‹คํ–‰ ์‹œ๊ฐ„(๋ Œ๋”๋ง) ์„ฑ๋Šฅ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์—๋„ ์•…์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ํ•œ ์œ ๋ช…ํ•œ ์‚ฌ์ดํŠธ์˜ ๋ฒˆ๋“ค์—์„œ SVG ์•„์ด์ฝ˜์ด ๊ฑฐ์˜ 50% (250kb)๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค." from Jason Miller X

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

  1. svg ํŒŒ์ผ์„ ํ•œ ํŒŒ์ผ์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ,
  2. svg ํŒŒ์ผ์„ ๋งค๋ฒˆ ์ถ”๊ฐ€ํ•˜๋ฉฐ asset ๋‚ด๋ถ€์—์„œ ๋Š˜๋ฆฌ์ง€ ๋ง๊ฒƒ!
  3. svg๋ฅผ ํ•œ๋ฒˆ์— ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๋Š” Icon ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๊ฒƒ
  4. Icon ์ปดํฌ๋„ŒํŠธ๋Š” ๊ธฐ์กด์˜ svg๋“ค์„ ๋ชจ๋‘ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•  ๊ฒƒ

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, ๊ฐ€์žฅ ๋ˆˆ์—ฌ๊ฒจ ๋ณธ ๋ถ€๋ถ„์€ SVG ํƒœ๊ทธ์˜ use ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•ด SVG Sprite ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ SVG Sprite ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ์ „ MDN์—์„œ ์ œ๊ณตํ•˜๋Š” use์™€ symbol์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•˜๋ฉด ๋”์šฑ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์•„๋ž˜๋Š” ํ•ด๋‹น MDN ๋ฌธ์„œ์— ๋Œ€ํ•œ ๋งํฌ ์ž…๋‹ˆ๋‹ค!

Mdn svg use ๋ถ€๋ถ„ Mdn svg symbol ๋ถ€๋ถ„

image ๋‹ค์Œ ์‚ฌ์ง„์„ ๋ณด๋ฉด svg ํƒœ๊ทธ ๋‚ด์šฐ๋ฒต์„œ myCircle์ด๋ผ๊ณ  ๋ช…์‹œํ•œ ํƒœ๊ทธ๋ฅผ use href๋ฅผ ํ†ตํ•ด์„œ ์žฌ์‚ฌ์šฉํ•˜๋ฉฐ, svg ํƒœ๊ทธ์˜ ์ผ๋ถ€๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. image ์ด๋Š” ์ข€ ๋” ๋ฉฑํ™•ํ•˜๊ฒŒ circle ๋ฟ์•„๋‹ˆ๋ผ symbol์ด๋ผ ๋ช…์‹œํ•œ ์ข€ ๋” ๋ฒ”์šฉ์ ์ธ ๋ชฉ์ ์„ ๊ฐ€์ง„ ํƒœ๊ทธ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ฉฐ, ํ•˜๋‚˜๋กœ ๋ช…์‹œํ•œ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋ฐฉ์‹์˜ ํŠน์ง•์€ svg ํƒœ๊ทธ ๋‚ด๋ถ€์˜ ํŠน์ • ๋ถ€๋ถ„์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์‹์œผ๋กœ use๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š”๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์•„์ด๋””์–ด๋ฅผ ์–ป์–ด ๊ฑฐ๋Œ€ํ•œ svg ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด ๊ทธ ๋‚ด๋ถ€์˜ ํŠน์ • ๋ถ€๋ถ„(์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  icon์ด ๋ฉ๋‹ˆ๋‹ค) ์„ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฐฉ์‹์„ ์ ๊ทน ์‚ฌ์šฉํ•ด์„œ SVG Sprite ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Svg Sprite ๊ธฐ๋ฒ•์ด๋ž€?

ํ•ด๋‹น ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ๊ตฌํ˜„์€ Simple icon systems using SVG sprites ์„ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.

SVG ์Šคํ”„๋ผ์ดํŠธ ๊ธฐ๋ฒ•์€ ์›น ๊ฐœ๋ฐœ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ณ ๊ธ‰ ๊ทธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ํฐ SVG ํŒŒ์ผ ๋‚ด์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ(์˜ˆ: ์•„์ด์ฝ˜)๋ฅผ ํฌํ•จ์‹œํ‚ค๊ณ , ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ <use> ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๊ฐ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋Š” ๊ณ ์œ ํ•œ ID๋กœ ์‹๋ณ„๋˜๋ฉฐ, ์ด ID๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์š”์†Œ๋ฅผ ํŽ˜์ด์ง€์˜ ๋‹ค์–‘ํ•œ ์œ„์น˜์—์„œ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SVG ์Šคํ”„๋ผ์ดํŠธ์˜ ์ž‘๋™ ์›๋ฆฌ

SVG ์Šคํ”„๋ผ์ดํŠธ ๊ธฐ๋ฒ•์˜ ํ•ต์‹ฌ์€ ํ•˜๋‚˜์˜ ํฐ SVG ํŒŒ์ผ์— ๋‹ค์ˆ˜์˜ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋ฅผ ํฌํ•จ์‹œํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์›น ํŽ˜์ด์ง€์˜ ๋ณธ๋ฌธ์ด ์•„๋‹Œ, ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ์กด์žฌํ•˜๊ฑฐ๋‚˜ <head> ์„น์…˜์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ์š”์†Œ๋Š” <symbol> ํƒœ๊ทธ๋กœ ์ •์˜๋˜์–ด ๊ณ ์œ ํ•œ ID๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” ์›น ํŽ˜์ด์ง€ ๋‚ด์—์„œ ํ•„์š”ํ•œ SVG ์š”์†Œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ €๋Š” JS ๋‚ด๋ถ€์—์„œ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ์–ด GlobalSvgProvider๋ฅผ ๋”ฐ๋กœ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค!

์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ <use> ํƒœ๊ทธ์˜ ์—ญํ• 

์›น ํŽ˜์ด์ง€์—์„œ ํŠน์ • SVG ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด <use> ํƒœ๊ทธ๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํƒœ๊ทธ๋Š” xlink:href ์†์„ฑ์„ ํ†ตํ•ด ์Šคํ”„๋ผ์ดํŠธ ๋‚ด์˜ ํŠน์ • <symbol>์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, xlink:href="#icon1"์€ ID๊ฐ€ "icon1"์ธ <symbol>์„ ํŽ˜์ด์ง€์— ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์„ ํ†ตํ•ด, ํ•˜๋‚˜์˜ ํฐ SVG ํŒŒ์ผ ๋‚ด์—์„œ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ ์„ ํƒ์ ์œผ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

SVG ์Šคํ”„๋ผ์ดํŠธ์˜ ์ด์ 

  • ์„ฑ๋Šฅ ์ตœ์ ํ™”: ์—ฌ๋Ÿฌ ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ๊ฐœ๋ณ„์ ์ธ HTTP ์š”์ฒญ์„ ์ค„์ž„์œผ๋กœ์จ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ต๋‹ˆ๋‹ค.
  • ์œ ์ง€๋ณด์ˆ˜ ํŽธ์˜์„ฑ: ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๊ฐ€ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ๊ด€๋œ ์Šคํƒ€์ผ๋ง: CSS๋ฅผ ํ†ตํ•ด ์ „์ฒด ์•„์ด์ฝ˜ ์„ธํŠธ์— ์ผ๊ด€๋œ ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ™•์žฅ์„ฑ: ์ƒˆ๋กœ์šด ์•„์ด์ฝ˜์ด๋‚˜ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์—ฐํžˆ ๊ฐœ๋ณ„์ ์ธ ์ด๋ฏธ์ง€๋ฅผ ์ตœ์ดˆ์˜ ๋กœ๋”ฉ์— ํฌํ•จ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์—, ์ดˆ๊ธฐ ๋กœ๋”ฉ์†๋„๊ฐ€ "์ƒ๋Œ€์ " ์œผ๋กœ ๋” ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ์œ ์˜๋ฏธํ•œ ์ฐจ์ด๊ฐ€ ๋‚  ์ •๋„๋กœ ์ดˆ๊ธฐ ๋กœ๋”ฉ์†๋„๊ฐ€ ๋Š๋ ค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ ์šฉ ๋ฐฉ๋ฒ•

import { css } from "@emotion/react";
import { createPortal } from "react-dom";

const spliteSvgCode = (
	<svg
		xmlns="http://www.w3.org/2000/svg"
		css={css`
			display: none;
		`}
	>
		<symbol id="close-circle" viewBox="0 0 40 40">
			<path
				fillRule="evenodd"
				clipRule="evenodd"
				d="M20 40C31.0457 40 40 31.0457 40 20C40 8.9543 31.0457 0 20 0C8.9543 0 0 8.9543 0 20C0 31.0457 8.9543 40 20 40ZM13.0808 13.0642C14.2525 11.8928 16.152 11.893 17.3234 13.0647L19.9982 15.74L22.6696 13.0686C23.8412 11.897 25.7407 11.897 26.9122 13.0686C28.0838 14.2402 28.0838 16.1397 26.9122 17.3113L24.2404 19.9831L26.9154 22.6587C28.0869 23.8304 28.0867 25.7299 26.915 26.9013C25.7433 28.0728 23.8438 28.0726 22.6724 26.9009L19.9978 24.2257L17.3282 26.8953C16.1567 28.0668 14.2572 28.0668 13.0856 26.8953C11.914 25.7237 11.914 23.8242 13.0856 22.6526L15.7556 19.9826L13.0804 17.3069C11.9089 16.1352 11.9091 14.2357 13.0808 13.0642Z"
				fill="white"
			/>
		</symbol>
		<symbol id="close" viewBox="0 0 24 25">
			<g id="Frame" clipPath="url(#clip0_289_791)">
				<path
					id="Vector"
					d="M23.4772 3.35322C24.1798 2.62789 24.0679 1.55056 23.2223 0.947888C22.3767 0.345222 21.1208 0.441222 20.4182 1.16656L11.9995 9.83322L3.58085 1.16656C2.87826 0.441222 1.62231 0.345222 0.77671 0.947888C-0.0688857 1.55056 -0.180803 2.62789 0.521788 3.35322L9.40676 12.4999L0.521788 21.6466C-0.180803 22.3719 -0.0688857 23.4492 0.77671 24.0519C1.62231 24.6546 2.87826 24.5586 3.58085 23.8332L11.9995 15.1666L20.4182 23.8332C21.1208 24.5586 22.3767 24.6546 23.2223 24.0519C24.0679 23.4492 24.1798 22.3719 23.4772 21.6466L14.5923 12.4999L23.4772 3.35322Z"
					fill="white"
				/>
			</g>
			<defs>
				<clipPath id="clip0_289_791">
					<rect
						width="24"
						height="24"
						fill="white"
						transform="translate(0 0.5)"
					/>
				</clipPath>
			</defs>
		</symbol>
		// ๋‹ค๋ฅธ svg๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด symbol์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์— ๋‹ค๋ฅธ svg๋ฅผ ๋™์ผํ•œ
		๋ฐฉ์‹์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
	</svg>
);

// App ๋‚ด๋ถ€์—์„œ ์„ ์–ธ๋˜์–ด ์ตœ์ดˆ ์ƒ์„ฑ๋  dom์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค
export default function GlobalSVGProvider() {
	return createPortal(spliteSvgCode, document.body);
}

๊ทธ๋ฆฌ๊ณ  ์œ„์˜ ๋ฐฉ์‹์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” GlobalSvgProvider๋ฅผ App.tsx์—์„œ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

image

๊ทธ๋ฆฌ๊ณ  Icon ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// foundation ๋‚ด๋ถ€์—์„œ ์ •์˜ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
const Icon: React.FC<SvgIconProps> = ({
	id,
	width = "16",
	height = "16",
	...props
}) => {
	return (
		<svg width={width} height={height} {...props}>
			<use href={`#${id}`} />
		</svg>
	);
};

// ์‚ฌ์šฉ๋ฐฉ๋ฒ•

<Icon
	id="next" // symbol ์˜†์— ์ž‘์„ฑํ•œ id๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
	width="2rem"
	height="2rem"
	css={css`
		cursor: pointer;
	`}
	onClick={() => console.log("hihi")}
/>;

Result

image

image

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋กœ svg ํŒŒ์ผ์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด์„œ ๋‹ค๋ฅธ svg ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹จ์ˆœํžˆ Icon ์˜ props๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค!

ยฉ 2024 Adultlee. All rights reserved.Made with โค by ์ด์„ฑ์ธ