[๐ŸŒ™๋‹คํฌ ๋ชจ๋“œ - 1๋ถ€] ๋‹คํฌ ๋ชจ๋“œ ๋„์ž… ์‹คํŒจ ํšŒ๊ณ ๋ก

Administrator||์กฐํšŒ์ˆ˜ 75

alt text


๋‹คํฌ ๋ชจ๋“œ ๋„์ž… ์‹คํŒจ๊ธฐ : ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฑฐ๋Œ€ํ•œ ๋ฒฝ


๋„์ž…: ์ต์ˆ™ํ•จ์ด ์•ˆ๊ฒจ์ค€ ๋ฐฉ์‹ฌ

๋ธ”๋กœ๊ทธ์˜ ๋””์ž์ธ์  ๊ธฐ๋Šฅ ๊ฐœ์„ ์„ ์ง„ํ–‰ํ•˜๊ณ  ์‹ถ์–ด, '๋‹คํฌ ๋ชจ๋“œ'๋ฅผ ๋„์ž…ํ•˜๊ธฐ๋กœ ๋งˆ์Œ๋จน์—ˆ๋‹ค. ๋งŽ์€ ์–ด๋ ค์›€์„ ๊ฒช์—ˆ๋˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (ํŠนํžˆ ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง•..) ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๋‹ˆ, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋‹คํฌ๋ชจ๋“œ ๋„์ž…์€ ๊ทธ๋ฆฌ ์–ด๋ ค์šด ์ž‘์—…์€ ์•„๋‹ ๊ฑฐ๋ผ ์ƒ๊ฐํ–ˆ๋‹ค. ํŠนํžˆ ์ด์ „์— ์ง„ํ–‰ํ–ˆ๋˜ ๋‹จ์ˆœ HTML, CSS, JavaScript๋กœ ๋งŒ๋“ค์—ˆ๋˜ ๋‚ด ํฌํŠธํด๋ฆฌ์˜ค ์›น์‚ฌ์ดํŠธ RollerCoaster ์—์„œ๋Š” localStorage์™€ CSS ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด ์˜ˆ์ƒ์™ธ๋กœ ์‰ฝ๊ฒŒ ์ ์šฉํ•œ ๊ฒฝํ—˜์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋•Œ์˜ ๊ฒฝํ—˜์€ ๊ฐ„๋‹จํ–ˆ๋‹ค. CSS ๋ณ€์ˆ˜๋กœ ์ƒ‰์ƒ ์‹œ์Šคํ…œ์„ ์ •์˜ํ•˜๊ณ , JavaScript๋กœ <body> ํƒœ๊ทธ์— data-theme="dark" ์†์„ฑ ํ•˜๋‚˜๋งŒ ํ† ๊ธ€ํ•ด์ฃผ๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋ฐ”๋€Œ์—ˆ๋‹ค. ๊ทธ ์ต์ˆ™ํ•จ๊ณผ ์ž์‹ ๊ฐ์€, ๋‚ด๊ฐ€ ๋งˆ์ฃผํ•  ๊ฑฐ๋Œ€ํ•œ ๋ฒฝ์˜ ๋†’์ด๋ฅผ ๊ฐ€๋Š ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋งŒ๋“  ๊ฐ€์žฅ ํฐ ์›์ธ์ด์—ˆ๋‹ค.

๋‚ด ์ƒˆ๋กœ์šด ๋ธ”๋กœ๊ทธ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ์ˆ  ์Šคํƒ์€ ์ด์ „๊ณผ๋Š” ์ฐจ์›์ด ๋‹ฌ๋ž๋‹ค.

  • Next.js 15 (App Router)
  • React 19
  • Tailwind CSS v4
  • Toast UI Editor

ํ˜„๋Œ€์ ์ธ ์›น ๊ฐœ๋ฐœ์˜ ํŽธ๋ฆฌํ•จ์„ ๋ชจ๋‘ ๋ˆ„๋ฆฌ๊ณ  ์žˆ์—ˆ์ง€๋งŒ, ๋ฐ”๋กœ ๊ทธ 'ํŽธ๋ฆฌํ•จ'์„ ์ œ๊ณตํ•˜๋Š” ๊ฐ ์‹œ์Šคํ…œ์˜ ๋ณต์žกํ•œ ์ƒํ˜ธ์ž‘์šฉ์ด ์ด๋ฒˆ ๋‹คํฌ ๋ชจ๋“œ ๋„์ž…์— ๋ฐœ๋ชฉ์„ ์žกํžˆ๊ฒŒ ๋  ์ค„์€ ๊ฟˆ์—๋„ ๋ชฐ๋ž๋‹ค.

Phase 1: ๊ธฐ๋ณธ ์„ค์ •, ์ˆœ์กฐ๋กœ์šด ์ถœ๋ฐœ

์ฒ˜์Œ ์ง„ํ–‰์€ ์ˆœ์กฐ๋กœ์› ๋‹ค. next-themes ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ , ThemeProvider๋ฅผ ์•ฑ ์ „์ฒด์— ์ ์šฉํ–ˆ๋‹ค. tailwind.config.js์— darkMode: 'class'๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , globals.css์— ๋ผ์ดํŠธ/๋‹คํฌ ๋ชจ๋“œ์šฉ CSS ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ–ˆ๋‹ค.

/* globals.css */ :root { --bg-primary: #ffffff; --text-primary: #111827; /* ... */ } html.dark { --bg-primary: #111827; --text-primary: #f9fafb; /* ... */ }

Header, PostCard ๋“ฑ ๋‚ด๊ฐ€ ์ง์ ‘ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์€ dark: ์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์—ฌ์ฃผ์ž๋งˆ์ž ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋‹คํฌ ๋ชจ๋“œ์— ๋ฐ˜์‘ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์˜ˆ์ƒ๋Œ€๋กœ์˜€๋‹ค. ๋ฌธ์ œ๋Š” ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ, ๋ฐ”๋กœ Toast UI Editor์—์„œ ์‹œ์ž‘๋˜์—ˆ๋‹ค.

Phase 2: ์ฒซ ๋ฒˆ์งธ ์ถฉ๋Œ, Viewer์˜ ์ •์ „๊ณผ Editor์˜ ์นจ๋ฌต

  • ์ฒ˜์Œ ๋‹คํฌ๋ชจ๋“œ๋ฅผ ๋„์ž…ํ•˜๊ณ  ๋ฉ”์ธ ํŽ˜์ด์ง€๋Š” ์ž˜ ์ ์šฉ๋˜์—ˆ๋‹ค.

alt text

  • ํ•˜์ง€๋งŒ ์ƒ์„ธํŽ˜์ด์ง€๋กœ ๋“ค์–ด๊ฐ€์ž ๋Œ€์ฐธ์‚ฌ๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค. ์•”์ „๋œ ๊ฒŒ์‹œ๊ธ€์ด ๋ณด์ด๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

alt text

  • ํ…Œ๋งˆ ํ† ๊ธ€ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ <html> ํƒœ๊ทธ์— class="dark"๊ฐ€ ๋ถ™์–ด๋„, ์—๋””ํ„ฐ๋Š” ์š”์ง€๋ถ€๋™์ด์—ˆ๋‹ค. ํŽ˜์ด์ง€์˜ ๋ชจ๋“  ๊ฒƒ์ด ์–ด๋‘์›Œ์กŒ์ง€๋งŒ, ์—๋””ํ„ฐ๋งŒ์€ ์ƒˆํ•˜์–€ ๋ฐฐ๊ฒฝ์„ ๊ณ ์ง‘ํ•˜๋ฉฐ ํ™€๋กœ ๋น›๋‚˜๊ณ  ์žˆ์—ˆ๋‹ค.

alt text

์ด๋•Œ๋ถ€ํ„ฐ ๊ธฐ๋‚˜๊ธด ๋””๋ฒ„๊น… ์—ฌ์ •์ด ์‹œ์ž‘๋˜์—ˆ๋‹ค.

๊ฐ€์„ค 1: SSR ๋ฌธ์ œ์ผ ๊ฒƒ์ด๋‹ค. Toast UI Editor๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์— ์˜์กด์ ์ด๋‹ˆ, next/dynamic์œผ๋กœ SSR์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ํ•ด๊ฒฐ๋  ๊ฑฐ๋ผ ์ƒ๊ฐํ–ˆ๋‹ค.

// Editor.tsx const TuiEditor = dynamic( () => import('@toast-ui/react-editor').then((mod) => mod.Editor), { ssr: false } );

๊ฒฐ๊ณผ๋Š”? ์‹คํŒจ. SSR ์—๋Ÿฌ๋Š” ์‚ฌ๋ผ์กŒ์ง€๋งŒ, ์—๋””ํ„ฐ๋Š” ์—ฌ์ „ํžˆ ํ•˜์–—๋‹ค.

๊ฐ€์„ค 2: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ณต์‹ API๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค. ๋ฆฌ์„œ์น˜๋ฅผ ํ†ตํ•ด theme prop๊ณผ key๋ฅผ ์ด์šฉํ•œ ๊ฐ•์ œ ์žฌ๋งˆ์šดํŠธ ์ „๋žต์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. "์ด๊ฑฐ๋ฉด ๋˜๊ฒ ์ง€."

// Editor.tsx <TuiEditor key={theme} theme={theme === 'dark' ? 'dark' : 'default'} // ... />

๊ฒฐ๊ณผ๋Š”? ๋˜๋‹ค์‹œ ์‹คํŒจ. ์—๋””ํ„ฐ๋Š” ๊ผผ์ง๋„ ํ•˜์ง€ ์•Š์•˜๋‹ค.

Phase 3: ๋ณด์ด์ง€ ์•Š๋Š” ์ , CSS์™€์˜ ์ „์Ÿ

์ด์ œ ๋ฌธ์ œ๋Š” ์ฝ”๋“œ ๋กœ์ง์ด ์•„๋‹Œ, ๋ณด์ด์ง€ ์•Š๋Š” CSS์˜ ์„ธ๊ณ„์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ง๊ฐํ–ˆ๋‹ค.

๊ฐ€์„ค 3: ๋‹คํฌ ๋ชจ๋“œ CSS ํŒŒ์ผ์ด ๋กœ๋“œ๋˜์ง€ ์•Š์•˜๋‹ค. layout.tsx์—์„œ toastui-editor-dark.css๋ฅผ ์ง์ ‘ importํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ € Network ํƒญ์„ ํ™•์ธํ–ˆ๋‹ค. ํŒŒ์ผ์€ ๋กœ๋“œ๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ Next.js์˜ CSS ๋ฒˆ๋“ค๋ง ๋ฐฉ์‹์ด ์˜์‹ฌ์Šค๋Ÿฌ์›Œ, globals.css์—์„œ @importํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ๋„ ํ•ด๋ณด์•˜๋‹ค. ๊ฒฐ๊ณผ๋Š” ๊ฐ™์•˜๋‹ค. CSS ํŒŒ์ผ์€ ๋ถ„๋ช…ํžˆ ์กด์žฌํ–ˆ๋‹ค.

๊ฐ€์„ค 4: CSS ์šฐ์„ ์ˆœ์œ„(Specificity) ๋ฌธ์ œ๋‹ค. "Tailwind CSS์˜ ๋ง‰๊ฐ•ํ•œ ๊ธฐ๋ณธ ์Šคํƒ€์ผ์ด Toast UI์˜ ์Šคํƒ€์ผ์„ ๋ฎ์–ด์“ฐ๊ณ  ์žˆ๋Š” ๊ฒŒ ๋ถ„๋ช…ํ•ด." ๋‚˜๋Š” tailwind.config.js์— important: '#app-root'๋ฅผ ์„ค์ •ํ•˜์—ฌ Tailwind์˜ ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๊ณ , globals.css ์ตœํ•˜๋‹จ์— !important๋ฅผ ๋™์›ํ•œ ์˜ค๋ฒ„๋ผ์ด๋“œ ๊ทœ์น™๊นŒ์ง€ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

/* globals.css */ html.dark #app-root .toastui-editor-defaultUI { background-color: var(--bg-secondary) !important; /* ... */ }

๊ฒฐ๊ณผ๋Š”? ์ฒ˜์ฐธํ•œ ์‹คํŒจ. ๋‚ด ๋ชจ๋“  ๋…ธ๋ ฅ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์—๋””ํ„ฐ์˜ ๋ฐฐ๊ฒฝ์ƒ‰์€ ๋ณ€ํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Styles ํƒญ์€ ๋‚ด๊ฐ€ ์ถ”๊ฐ€ํ•œ !important ๊ทœ์น™์ด ์ ์šฉ์กฐ์ฐจ ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ๋ฌด์–ธ๊ฐ€์— ์˜ํ•ด ๋ฌด์‹œ๋˜๊ณ  ์žˆ์Œ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์—ˆ๋‹ค.

alt text

alt text

์ค‘๊ฐ„ ๊ฒฐ๋ก : ๋ฏธ๊ถ ์†์œผ๋กœ

๋ชจ๋“  ํ‘œ์ค€์ ์ธ ํ•ด๊ฒฐ์ฑ…์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ, ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค. CSS ํŒŒ์ผ์€ ๋กœ๋“œ๋˜์—ˆ๊ณ , <html> ํƒœ๊ทธ์˜ ํด๋ž˜์Šค๋Š” ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉฐ, ์—๋””ํ„ฐ ์ปดํฌ๋„ŒํŠธ๋Š” ์žฌ๋งˆ์šดํŠธ๊นŒ์ง€ ๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ ๋ชจ๋“  ์‹ ํ˜ธ๋ฅผ ์—๋””ํ„ฐ๋Š” ์ฒ ์ €ํžˆ ๋ฌด์‹œํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

๋งˆ์น˜ ๋ชจ๋“  ๋ถ€ํ’ˆ์ด ์ •์ƒ์ธ๋ฐ ์‹œ๋™์ด ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” ์ž๋™์ฐจ๋ฅผ ๋งˆ์ฃผํ•œ ๊ธฐ๋ถ„์ด์—ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋‚ด๊ฐ€ ์•„๋Š” ์˜์—ญ ๋„ˆ๋จธ, Next.js์˜ ๋นŒ๋“œ ์‹œ์Šคํ…œ๊ณผ Tailwind v4, ๊ทธ๋ฆฌ๊ณ  Toast UI Editor๋ผ๋Š” ์„ธ ๊ฐœ์˜ ๊ฑฐ๋Œ€ํ•œ ๋ธ”๋ž™๋ฐ•์Šค๊ฐ€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊นŠ์€ ๊ณณ์— ์ˆจ์–ด์žˆ๋Š” ๊ฒƒ ๊ฐ™์•˜๋‹ค.

๋‚˜๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋” ๊นŠ์€ ์‹ฌ์—ฐ์œผ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ๋กœ ๊ฒฐ์‹ฌํ–ˆ๋‹ค.


Phase 4: ๋งˆ์ง€๋ง‰ ์ง€ํ‘ธ๋ผ๊ธฐ, ์ง„๋‹จ๊ณผ ๊ฒ€์ฆ

1๋ถ€์—์„œ ๋ชจ๋“  ํ‘œ์ค€์ ์ธ ํ•ด๊ฒฐ์ฑ…์ด ์‹คํŒจ๋กœ ๋Œ์•„๊ฐ„ ํ›„, ๋‚˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋ฐ”๊พธ๊ธฐ๋กœ ํ–ˆ๋‹ค. ๋” ์ด์ƒ ์ƒˆ๋กœ์šด ํ•ด๊ฒฐ์ฑ…์„ '์‹œ๋„'ํ•˜๋Š” ๋Œ€์‹ , ๋ฌธ์ œ์˜ ๊ทผ๋ณธ ์›์ธ์„ '์ง„๋‹จ'ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ธฐ๋กœ ํ•œ ๊ฒƒ์ด๋‹ค. "์™œ ์•ˆ ๋˜์ง€?"๋ผ๋Š” ๋ง‰์—ฐํ•œ ์งˆ๋ฌธ ๋Œ€์‹ , "์ง€๊ธˆ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”๊ฐ€?"๋ผ๋Š” ๊ตฌ์ฒด์ ์ธ ์งˆ๋ฌธ์„ ๋˜์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ์ฝ˜์†”์— ๋ช‡ ๊ฐ€์ง€ ์ง„๋‹จ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ, ๋ˆˆ์— ๋ณด์ด์ง€ ์•Š๋Š” ๋‚ด๋ถ€ ๋™์ž‘์„ 'ํŒฉํŠธ'๋กœ ์ˆ˜์ง‘ํ–ˆ๋‹ค.

์ง„๋‹จ 1: CSS ๊ทœ์น™์€ ์ •๋ง ์กด์žฌํ•˜๋Š”๊ฐ€? document.styleSheets๋ฅผ ๋ชจ๋‘ ๋’ค์ ธ .toastui-editor-dark ๊ด€๋ จ ๊ทœ์น™์ด ์žˆ๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.

// ์ฝ˜์†” ์‹คํ–‰ ๊ฒฐ๊ณผ { ..., hasDark: true }

๊ฒฐ๋ก : ์กด์žฌํ–ˆ๋‹ค. CSS ํŒŒ์ผ์€ ์ •์ƒ์ ์œผ๋กœ ๋กœ๋“œ๋˜์—ˆ๊ณ , ๋‹คํฌ ๋ชจ๋“œ ๊ทœ์น™๋„ ๋ฒˆ๋“ค ์•ˆ์— ํฌํ•จ๋˜์–ด ์žˆ์—ˆ๋‹ค.

์ง„๋‹จ 2: ์—๋””ํ„ฐ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋Š” ์˜ˆ์ƒ๊ณผ ๊ฐ™์€๊ฐ€? <iframe>์ด๋‚˜ shadow DOM์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์™ธ๋ถ€ CSS๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ์—๋””ํ„ฐ์˜ DOM ๊ตฌ์กฐ๋ฅผ ํ™•์ธํ–ˆ๋‹ค.

// ์ฝ˜์†” ์‹คํ–‰ ๊ฒฐ๊ณผ Iframe Found: false ShadowRoot Present: false

๊ฒฐ๋ก : ์•„๋‹ˆ์—ˆ๋‹ค. ์—๋””ํ„ฐ๋Š” ํ‰๋ฒ”ํ•œ div๋กœ ๋ Œ๋”๋ง๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ์™ธ๋ถ€ ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜์ง€ ์•Š์„ ์ด์œ ๊ฐ€ ์—†์—ˆ๋‹ค.

์ง„๋‹จ 3: ๋‹คํฌ ๋ชจ๋“œ ํด๋ž˜์Šค๋Š” ์ œ๋Œ€๋กœ ์ฃผ์ž…๋˜๊ณ  ์žˆ๋Š”๊ฐ€? useLayoutEffect๋ฅผ ์‚ฌ์šฉํ•ด .toastui-editor-dark ํด๋ž˜์Šค๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋กœ์ง์ด ์ •๋ง ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.

// ์ฝ˜์†” ์‹คํ–‰ ๊ฒฐ๊ณผ (Elements ํƒญ ํ™•์ธ) <div class="toastui-editor-defaultUI toastui-editor-dark">...</div>

๊ฒฐ๋ก : ์„ฑ๊ณต์ ์œผ๋กœ ์ฃผ์ž…๋˜๊ณ  ์žˆ์—ˆ๋‹ค. <html> ํƒœ๊ทธ์˜ ํด๋ž˜์Šค๊ฐ€ dark๋กœ ๋ฐ”๋€Œ๋ฉด, ์—๋””ํ„ฐ์˜ ๋ฃจํŠธ div์—๋„ .toastui-editor-dark ํด๋ž˜์Šค๊ฐ€ ๋ถ„๋ช…ํžˆ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์‹ฌ์—ฐ์˜ ๋: ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ธ๋ฐ, ์•„๋ฌด๊ฒƒ๋„ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค

๋ชจ๋“  ์ง„๋‹จ ๊ฒฐ๊ณผ๋Š” ๋‚˜๋ฅผ ๋” ๊นŠ์€ ๋ฏธ๊ถ์œผ๋กœ ๋น ๋œจ๋ ธ๋‹ค.

  1. ๋‹คํฌ ๋ชจ๋“œ CSS ๊ทœ์น™์€ ์กด์žฌํ•œ๋‹ค.
  2. ์Šคํƒ€์ผ์„ ์ ์šฉํ•  DOM ์š”์†Œ๋„ ์กด์žฌํ•œ๋‹ค.
  3. ๋‘ ์š”์†Œ๋ฅผ ์—ฐ๊ฒฐํ•  ํด๋ž˜์Šค๋„ ์ •์ƒ์ ์œผ๋กœ ์ฃผ์ž…๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” ๋ณ€ํ•˜์ง€ ์•Š์•˜๋‹ค. ์—๋””ํ„ฐ๋Š” ์—ฌ์ „ํžˆ ์ƒˆํ•˜์–€ ๋ชจ์Šต ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ์ด ํ˜„์ƒ์€ CSS์˜ ๊ธฐ๋ณธ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ๊ฑฐ์Šค๋ฅด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€๋‹ค. ์ด๋Š” ๋‹จ์ˆœํžˆ ๋””๋ฒ„๊น…์œผ๋กœ ํ•ด๊ฒฐ๋  ์ˆ˜์ค€์„ ๋„˜์–ด์„ , ๋นŒ๋“œ ์‹œ์Šคํ…œ(Next.js, Turbopack, PostCSS)๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Tailwind CSS v4, Toast UI Editor) ๊ฐ„์˜ ๋ณต์žกํ•œ ์ƒํ˜ธ์ž‘์šฉ ํ˜น์€ ๋„์ž… ๋ฐฉ์‹์— ๋Œ€ํ•œ ๋ฆฌ์„œ์น˜์˜ ๋ถ€์ •ํ™•์„ฑ ๋ฌธ์ œ์ž„์„ ์ง๊ฐํ–ˆ๋‹ค.

๊ฒฐ๋ก : ์ „๋žต์  ํ›„ํ‡ด, ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ์„ ์œ„ํ•œ ์•ฝ์†

๋ชจ๋“  ๋ฌธ์ œ์—๋Š” ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋‹ค๊ณ  ๋ฏฟ์ง€๋งŒ, ๊ทธ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๋Š” ๋ฐ ๋“œ๋Š” '๋น„์šฉ'์„ ํ•ญ์ƒ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. ํ˜„์žฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Next.js๋‚˜ Tailwind์˜ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€๋ฅผ ํŒŒ๊ณ ๋“ค๊ฑฐ๋‚˜, Toast UI Editor์˜ CSS ์ „์ฒด๋ฅผ !important๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ์ž‘์„ฑํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ณ„์†ํ•ด์„œ ๊ทผ๋ณธ์ ์ธ ์›์ธ์„ ์ฐพ์ง€ ๋ชปํ•˜๊ณ  ๋””๋ฒ„๊น… ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๋‹คํฌ๋ชจ๋“œ ๋„์ž…์— ๋Œ€ํ•ด '์ž ์ • ์ค‘๋‹จ' ์ด๋ผ๋Š”, ์–ด์ฉŒ๋ฉด ๊ฐ€์žฅ ์–ด๋ ค์šด ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ธฐ๋กœ ํ–ˆ๋‹ค. ์ด๊ฒƒ์€ ํฌ๊ธฐ๊ฐ€ ์•„๋‹Œ, ๋” ์ค‘์š”ํ•œ ๋ชฉํ‘œ์— ์ง‘์ค‘ํ•˜๊ธฐ ์œ„ํ•œ ์ „๋žต์  ํ›„ํ‡ด๋‹ค.

๋‹ค๋งŒ, Toast UI Editor์™€ ๋‹ค์–‘ํ•œ Reactํ™˜๊ฒฝ์—์„œ ๋‹คํฌ๋ชจ๋“œ๋ฅผ ๋„์ž…ํ•œ ๋‹ค๋ฅธ ํ›Œ๋ฅญํ•˜์‹  ๋ถ„๋“ค์˜ ํฌ์ŠคํŒ…์„ ๋ณด๋ฉฐ ํ•™์Šตํ•˜๊ณ , ๊ฒ€์ฆํ•˜๊ณ  ๋‹ค์‹œ ๋„์ „ํ•ด๋ณผ ์˜ˆ์ •์ด๋‹ค.

๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ฐ˜๋“œ์‹œ ์ด ๋ฒฝ์„ ๋„˜์–ด, Deep Dive! ๋ธ”๋กœ๊ทธ์— ์™„๋ฒฝํ•œ ๋‹คํฌ ๋ชจ๋“œ๋ฅผ ์ ์šฉํ•  ๊ฒƒ์ด๋‹ค.

๋ฐ˜๋“œ์‹œ..๐Ÿ‘Š

Administrator
Written by

Administrator

์•ˆ๋…•ํ•˜์„ธ์š”! Deep Dive! ๋ธ”๋กœ๊ทธ ์ œ์ž‘์ž ์ž…๋‹ˆ๋‹ค.

๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...