๐จ Tailwind Advanced 1์ฅ: ์๊ฐ ํจ๊ณผ ๋ง์คํฐ โ ํํฐ, Backdrop, ๊ทธ๋ผ๋์ธํธ
๐ ๊ฐ์
CSS filter, backdrop-filter, gradient ์ ํธ๋ฆฌํฐ๋ฅผ ์์ ํ ์ดํดํ๊ณ glassmorphism ๋ค๋น๊ฒ์ด์ ๋ฐ์ gradient hero ์น์ ์ ๊ตฌํํฉ๋๋ค.
๐ ๋ชฉ์ฐจ
- ๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
- ๐ค ์ ์์์ผ ํ๋๊ฐ
- ๐๏ธ ๋น์ ๋ก ๋จผ์ ์ดํดํ๊ธฐ
- ๐ฌ 1๋จ๊ณ: CSS filter โ ์์ ์์ ์๊ฒ ๊ฑฐ๋ ๋ง๋ฒ
- ๐ช 2๋จ๊ณ: Backdrop Filter โ ๋ฐฐ๊ฒฝ์ ํต๊ณผํ๋ ์ ๋ฆฌ
- ๐ 3๋จ๊ณ: Gradient โ ์์์ ํ๋ฆ์ ์ค๊ณํ๋ค
- โ๏ธ 4๋จ๊ณ: Gradient Text โ ํ ์คํธ์ ๊ทธ๋ผ๋์ธํธ ์ ํ๊ธฐ
- ๐ญ 5๋จ๊ณ: Mix Blend Mode โ ๋ ์ด์ด์ ์ฐ๊ธ์
- ๐ ์ค์ : ์์๋ค ์ปค๋ฎค๋ํฐ Glassmorphism ๊ตฌํ
- ๐ ์ด๋ฒ์ ๋ฐฐ์ด ๋ด์ฉ ์ด์ ๋ฆฌ
- ๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
- ๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
- ๐ ๋ ์์๋ณด๊ธฐ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 25๋ถ (์ ์ฒด) / ํต์ฌ ํํธ๋ง: 12๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ์์(๋์์ด๋): "์์ฒ ๋, ์์ฆ ์ ํํ๋ ๊ธ๋์ค๋ชจํผ์ฆ(Glassmorphism) ๋๋์ผ๋ก ๋ค๋น๊ฒ์ด์ ๋ฐ ๋ง๋ค์ด ๋ด์! ๋ค์ ๋ฐฐ๊ฒฝ์ด ํ๋ฆฟํ๊ฒ ๋น์น๋ ๊ทธ ๋ฐํฌ๋ช ์ ๋ฆฌ ๋๋์ด์. ์์ฆ Apple ์ฑ์ด๋ Linear ๊ฐ์ ๋ฐ์ ๋ค ์จ์~"
- ์์ฒ (์ ์ ): "์ ๊ทธ๊ฑฐ์? ์ ๊ฐ JavaScript๋ก canvas API ์จ์ ๋ค ๋ฐฐ๊ฒฝ ํฝ์ ํ๋ํ๋ ์ฝ์ด๋ค๊ฐ blur ์ฒ๋ฆฌํ๋ฉด ๋๊ฒ ๋ค์! ์ข ๋ณต์กํ๊ธด ํ๋ฐ ํ ์ ์์ด์..."
- ์ํธ(๋ฆฌ๋): "...์์ฒ ๋. ์ ๊น๋ง์. ๊ทธ๊ฑฐ CSS ๋ ์ค์ด๋ฉด ๋ฉ๋๋ค.
backdrop-blur-md๋bg-white/10์ฐ๋ฉด ๋์ด์์."
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
-
blur-*,brightness-*,contrast-*,grayscale-*,drop-shadow-*๋ฑ CSS filter ์ ํธ๋ฆฌํฐ๋ฅผ ์์ ์์ฌ๋ก ์ฌ์ฉํ ์ ์๋ค. -
backdrop-blur-*๋ฅผ ์ฌ์ฉํด Glassmorphism ํจ๊ณผ๋ฅผ CSS๋ง์ผ๋ก ๊ตฌํํ ์ ์๋ค. -
bg-linear-to-*,from-*,via-*,to-*๋ก ๋ค๋ฐฉํฅ ๊ทธ๋ผ๋์ธํธ๋ฅผ ์ค๊ณํ ์ ์๋ค. - Gradient Text ํจ๊ณผ์ Mix Blend Mode์ ์๋ฆฌ๋ฅผ ์ค๋ช ํ ์ ์๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
์์์ด์ ์ ๋ฆฌ ํจ๊ณผ ์์ฒญ โ filter vs backdrop-filter ๊ตฌ๋ถ โ gradient ๋ง์คํฐ โ ์์๋ค ์ปค๋ฎค๋ํฐ ์ค์ ๊ตฌํ
๐ค ์ ์์์ผ ํ๋๊ฐ
2021๋ , ์น ๋์์ธ์ ํจ๋ฌ๋ค์์ด ๋ฐ๋์์ด. iOS 15์ ์ถ์์ ํจ๊ป Glassmorphism(๊ธ๋์ค๋ชจํผ์ฆ) ์ด๋ผ๋ ๋์์ธ ํธ๋ ๋๊ฐ ํญ๋ฐ์ ์ผ๋ก ์ ํํ๊ธฐ ์์ํ๊ฑฐ๋ . ๋ค์ ์๋ ๋ฐฐ๊ฒฝ์ด ๋ฐํฌ๋ช ํ๊ฒ ํ๋ฆฟํ๊ฒ ๋ณด์ด๋ "์ ๋ฆฌ ํจ๋" ์คํ์ผ.
๊ณผ๊ฑฐ์๋ ์ด๊ฑธ ๊ตฌํํ๋ ค๋ฉด ์ง์ง๋ก ๋ณต์กํ JavaScript ์ฝ๋๊ฐ ํ์ํ์ด. Canvas API๋ก ๋ฐฐ๊ฒฝ ํฝ์ ์ ์ค์๊ฐ์ผ๋ก ์ฝ๊ณ , ๋ธ๋ฌ ์ฒ๋ฆฌํ๊ณ , ๋ค์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์์ผ๋ก. ์ฑ๋ฅ์ ๋น์ฐํ ์ฒ์ฐธํ๊ณ .
๊ทธ๋ฐ๋ฐ CSS backdrop-filter ์์ฑ์ด ๋ฑ์ฅํ๋ฉด์ ๊ฒ์์ด ์์ ํ ๋ฐ๋์์ด. ๋ธ๋ผ์ฐ์ ๊ฐ GPU ๊ฐ์์ผ๋ก ์ด ๋ชจ๋ ๊ฑธ ์ฒ๋ฆฌํด์ค. Tailwind๋ backdrop-blur-* ์ ํธ๋ฆฌํฐ๋ก ์ด๋ฅผ ํ ๋จ์ด๋ก ์ถ์ํํ๊ณ .
์ด๊ฑธ ๋ชจ๋ฅด๋ฉด ์์ฒ ์ด์ฒ๋ผ Canvas API ํฌํจ 300์ค์ง๋ฆฌ JavaScript๋ฅผ ์ง๊ณ , ์ํธ์๊ฒ ๋ ์ค CSS๋ก ๋์ฒด๋นํ๋ ์ด๋ช ์ด ๊ธฐ๋ค๋ฆฌ๊ณ ์์ด.
๐๏ธ ๋น์ ๋ก ๋จผ์ ์ดํดํ๊ธฐ
๐ฎ filter vs backdrop-filter, ๋ญ๊ฐ ๋ค๋ฅธ๊ฐ?
์นดํ์ ์๋ ๋ ์ข ๋ฅ์ ์ ๊ธ๋ผ์ค๋ฅผ ์์ํด๋ด:
filter(์์ ํํฐ): ๋ด๊ฐ ์ง์ ์ฐ๋ ์๊น ์ ๊ธ๋ผ์ค. ์ ๊ธ๋ผ์ค ์์ฒด๊ฐ ํ๋์์ด๋ฉด ๋๋ ํ๋๊ฒ ๋ณด์ฌ. ๋ด ์ผ๊ตด์ด ๋ณํ๋ ๊ฑฐ์ผ.backdrop-filter(๋ท๋ฐฐ๊ฒฝ ํํฐ): ์์ชฝ์ ํฌ๋ช ํ๊ณ ๋ฐ๊นฅ์ชฝ ๋ ์ฆ๊ฐ ์ฐ๊ธฐ ์ฒ๋ฆฌ๋ ํน์ ์๊ฒฝ. ์๊ฒฝ์ ์ด ์ฌ๋์ด ์๋๋ผ, ๊ทธ ์ฌ๋์ด ๋ฐ๋ผ๋ณด๋ ํ๊ฒฝ(๋ฐฐ๊ฒฝ) ์ด ํ๋ฆฟํ๊ฒ ๋ณด์ฌ.
filter๋ ์์ ์์ ์ ๋ณํํ๊ณ ,backdrop-filter๋ ์์ ๋ค์ ์๋ ๊ฒ๋ค์ ๋ณํํด.
๐ฌ 1๋จ๊ณ: CSS filter โ ์์ ์์ ์๊ฒ ๊ฑฐ๋ ๋ง๋ฒ
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
blur-*,brightness-*,grayscale-*๋ฑ ๋ค์ํ filter ์ ํธ๋ฆฌํฐ์ ์ฐจ์ด๋ฅผ ์ ์ ์๋ค.drop-shadow-*๊ฐshadow-*์ ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ์ด์ ๋ฅผ ์ค๋ช ํ ์ ์๋ค.
filter ์์ฑ์ ์์ ์์ฒด์ ์๊ฐ์ ํจ๊ณผ๋ฅผ ๊ฑฐ๋ CSS ๊ธฐ๋ฅ์ด์ผ. Tailwind๋ ์ด๋ฅผ ์ง๊ด์ ์ธ ์ ํธ๋ฆฌํฐ ํด๋์ค ์ธํธ๋ก ์ ๊ณตํด.
blur โ ํ๋ฆผ ํจ๊ณผ
blur-* ์ ํธ๋ฆฌํฐ๋ ์์์ Gaussian blur๋ฅผ ์ ์ฉํด. ํฌ๊ธฐ๋ xs(4px)๋ถํฐ 3xl(64px)๊น์ง ๋จ๊ณ๊ฐ ์์ด.
<!-- ์์๋ค ์ปค๋ฎค๋ํฐ ์คํฐ๋ ๋ชฉ๋ก - ํธ๋ฒ ์ ๋นํ์ฑ ์นด๋ ํ๋ฆฌ๊ฒ ์ฒ๋ฆฌ -->
<!-- โ ์์ฒ ์ด์ ์์งํ ์ฝ๋: CSS ์ง์ ์์ฑ -->
<div style="filter: blur(12px);">ํ๋ฆฟํ ์นด๋</div>
<!-- โ
์ํธ์ Tailwind ๋ฐฉ์ -->
<div class="blur-md">ํ๋ฆฟํ ์นด๋</div>
<!-- blur-xs: 4px | blur-sm: 8px | blur-md: 12px -->
<!-- blur-lg: 16px | blur-xl: 24px | blur-2xl: 40px | blur-3xl: 64px -->์ค์ ํจํด: ํธ๋ฒ ์ํ๊ฐ ์๋ ์นด๋๋ฅผ ์ด์ง ํ๋ฆฌ๊ฒ ์ฒ๋ฆฌํด์ ํฌ์ปค์ค ํจ๊ณผ๋ฅผ ์ค ์ ์์ด.
<!-- ์คํฐ๋ ์นด๋ ๋ชฉ๋ก - ์ ํ๋ ์นด๋๋ง ์ ๋ช
ํ๊ฒ -->
<div class="group flex gap-4">
<!-- ๐ฃ ์์ฒ : "์ด ์นด๋๊ฐ ์ ํ๋์ ๋ ๋๋จธ์ง๋ฅผ ํ๋ฆฌ๊ฒ ๋ง๋ค๊ณ ์ถ์ด์!" -->
<div class="transition-all duration-300 group-hover:blur-none blur-sm">
<!-- ๋นํ์ฑ ์นด๋: ํ์์๋ ์ฝ๊ฐ ํ๋ฆผ -->
</div>
</div>brightness โ ๋ฐ๊ธฐ ์กฐ์
brightness-* ์ ํธ๋ฆฌํฐ๋ ์์์ ๋ฐ๊ธฐ๋ฅผ ์กฐ์ ํด. brightness-0์ ์์ ์ด๋ , brightness-100์ ์๋ณธ, brightness-200์ 2๋ฐฐ ๋ฐ๊ธฐ์ผ.
<!-- โ ์์ฒ ์ด์ ์ฝ๋: ํธ๋ฒ ๋คํฌ ํจ๊ณผ๋ฅผ JavaScript๋ก ์ฒ๋ฆฌ -->
<div onmouseover="this.style.filter='brightness(0.75)'"
onmouseout="this.style.filter='none'">
์นด๋
</div>
<!-- โ
์ํธ์ Tailwind ๋ฐฉ์: CSS hover ๋ณํ -->
<div class="transition-all duration-200 hover:brightness-75">
<!-- brightness-75 = brightness(0.75) = 25% ์ด๋ก๊ฒ -->
์นด๋ ์ด๋ฏธ์ง ์ค๋ฒ๋ ์ด ํจ๊ณผ
</div>์ค๋ฌด์์ brightness-* ๋ ์ด๋ฏธ์ง ์นด๋์ ๋ง์ฐ์ค ์ค๋ฒ ์ ์ด์ง ์ด๋ก๊ฒ ๋ง๋๋ "์ค๋ฒ๋ ์ด ์์ด ์ค๋ฒ๋ ์ด ํจ๊ณผ"์ ์์ฃผ ์ฐ์ฌ.
contrast โ ๋๋น ์กฐ์
<!-- ์คํฐ๋ ๋ฉค๋ฒ ํ๋กํ ์ด๋ฏธ์ง - ๋คํฌ ๋ชจ๋ ๋๋น ํฅ์ -->
<img
class="dark:contrast-125 dark:brightness-90 transition-all"
src="/profile.jpg"
alt="์์ฒ ํ๋กํ"
/>
<!-- contrast-125: 25% ๋๋น ์ฆ๊ฐ (๋คํฌ ๋ชจ๋์์ ์ด๋ฏธ์ง๊ฐ ๋ ์ ๋ช
ํ๊ฒ) -->grayscale โ ํ๋ฐฑ ์ฒ๋ฆฌ
grayscale ์ ์์ ํ๋ฐฑ, grayscale-0 ์ ์์ ์ ์ง์ผ.
<!-- ์คํฐ๋ ๋ชจ์ง ๋ง๊ฐ๋ ์นด๋๋ฅผ ํ๋ฐฑ์ผ๋ก ํ์ -->
<!-- โ ์์ฒ ์ด์ ์ฝ๋: ๋ง๊ฐ ์ฌ๋ถ๋ฅผ JavaScript๋ก ์ฒดํฌํด์ ํด๋์ค ํ๋์ฝ๋ฉ -->
<div class={isClosed ? 'grayscale-filter-custom' : ''}>
<!-- โ
์ํธ์ ํจํด: ๋ฐ์ดํฐ ์์ฑ + Tailwind ์กฐ๊ฑด ํด๋์ค -->
<div class="transition-all duration-500"
data-closed="true"
class="data-[closed=true]:grayscale data-[closed=true]:opacity-60">
<img src="/study-thumbnail.jpg" alt="์คํฐ๋ ์ธ๋ค์ผ" />
<span>React ์คํฐ๋ (๋ชจ์ง ๋ง๊ฐ)</span>
</div>drop-shadow โ box-shadow ์์ ๊ฒฐ์ ์ ์ฐจ์ด
์ด๊ฒ์ด ๊ฐ์ฅ ์ค์ํ ํฌ์ธํธ์ผ. shadow-* (box-shadow)์ drop-shadow-* (filter: drop-shadow)๋ ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅด๊ฒ ์๋ํด.
<!-- ๐ฆ ์ํธ: "์์ฒ ๋, PNG ๋ก๊ณ ์ box-shadow ์ฐ๋ฉด ์ ๋๋ ์ด์ ์์์?" -->
<!-- โ box-shadow: ์์์ "์ฌ๊ฐํ ๋ฐ์ค" ์ ๊ทธ๋ฆผ์๋ฅผ ์ ์ฉ -->
<!-- ํฌ๋ช
PNG๋ผ๋ ์ฌ๊ฐํ ํํ๋ก ๊ทธ๋ฆผ์๊ฐ ์๊น -->
<img src="/logo-transparent.png" class="shadow-xl" />
<!-- ๊ฒฐ๊ณผ: ๋ก๊ณ ํํ๊ฐ ์๋ ์ฌ๊ฐํ ๊ทธ๋ฆผ์๊ฐ ์๊ฒจ๋ฒ๋ฆผ ๐ฑ -->
<!-- โ
drop-shadow: ์์์ "์ค์ ํฝ์
ํํ" ์ ๊ทธ๋ฆผ์๋ฅผ ์ ์ฉ -->
<!-- SVG, ํฌ๋ช
PNG ๋ฑ์ ์ค์ ๋ชจ์๋๋ก ๊ทธ๋ฆผ์๊ฐ ์๊น -->
<img src="/logo-transparent.png" class="drop-shadow-xl" />
<!-- ๊ฒฐ๊ณผ: ๋ก๊ณ ์ ์ค์ ํํ๋ฅผ ๋ฐ๋ผ ๊ทธ๋ฆผ์๊ฐ ์๊น โจ -->
<!-- ์ปฌ๋ฌ drop-shadow๋ ๊ฐ๋ฅ -->
<img src="/logo.svg" class="drop-shadow-xl drop-shadow-indigo-500/50" />
<!-- drop-shadow-[color]: ๊ทธ๋ฆผ์ ์์ ์ค์ -->
<!-- /50: ๊ทธ๋ฆผ์ ํฌ๋ช
๋ 50% -->drop-shadow์ ๋ ํผ๋ฐ์ค ๊ฐ๋ค:
| ์ ํธ๋ฆฌํฐ | CSS ๊ฐ |
|---|---|
drop-shadow-xs | 0 1px 1px rgb(0 0 0 / 0.05) |
drop-shadow-sm | 0 1px 2px rgb(0 0 0 / 0.15) |
drop-shadow-md | 0 3px 3px rgb(0 0 0 / 0.12) |
drop-shadow-lg | 0 4px 4px rgb(0 0 0 / 0.15) |
drop-shadow-xl | 0 9px 7px rgb(0 0 0 / 0.1) |
drop-shadow-2xl | 0 25px 25px rgb(0 0 0 / 0.15) |
๐ช 2๋จ๊ณ: Backdrop Filter โ ๋ฐฐ๊ฒฝ์ ํต๊ณผํ๋ ์ ๋ฆฌ
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
backdrop-blur-*์ ํธ๋ฆฌํฐ์ ๋์ ์๋ฆฌ์ ํ์ ์ ์ ์กฐ๊ฑด์ ์ดํดํ๋ค.- Glassmorphism ํจ๊ณผ ๊ตฌํ์ 3๊ฐ์ง ํ์ ์ฌ๋ฃ๋ฅผ ์กฐํฉํ ์ ์๋ค.
backdrop-filter ๋ ์์ ๋ค์ ์๋ ์์ญ์ ํํฐ๋ฅผ ์ ์ฉํด. ์์ ์์ฒด๊ฐ ๋ณํ๋ ๊ฒ ์๋๋ผ, ๊ทธ ์์๋ฅผ ํตํด์ ๋ฐ๋ผ๋ณด๋ ๋ฐฐ๊ฒฝ์ด ๋ณํ๋ ๊ฑฐ์ผ.
๋์ ์๋ฆฌ: 3๊ฐ์ง ํ์ ์ฌ๋ฃ
Glassmorphism์ ๋ง๋ค๋ ค๋ฉด ์ ํํ 3๊ฐ์ง ์กฐ๊ฑด์ด ๋์์ ์ถฉ์กฑ๋์ด์ผ ํด. ํ๋๋ผ๋ ๋น ์ง๋ฉด ํจ๊ณผ๊ฐ ์์ด.
Glassmorphism = ๋ฐํฌ๋ช
๋ฐฐ๊ฒฝ์ + backdrop-blur + ๋ค์ ์๋ ๋ฐฐ๊ฒฝ ์์
<!-- ๐ฃ ์์ฒ : "backdrop-blur-md ์ผ๋๋ฐ ์ ์๋ฌด๊ฒ๋ ์ ๋ณด์ฌ์?" -->
<!-- ํํ ์ค์: ๋ฐฐ๊ฒฝ์์ด ๋ถํฌ๋ช
ํ๋ฉด backdrop-filter๊ฐ ๊ฐ๋ ค์ ธ์ ์ ๋ณด์ -->
<!-- โ ์ค์ 1: ๋ฐฐ๊ฒฝ์์ด ์์ ๋ถํฌ๋ช
-->
<nav class="bg-white backdrop-blur-md">
<!-- backdrop-blur๊ฐ ์์ด๋ bg-white๊ฐ ์์ ํ ๋ฎ์ด๋ฒ๋ ค์ ํจ๊ณผ ์์ -->
</nav>
<!-- โ ์ค์ 2: ๋ค์ ๋ฐฐ๊ฒฝ์ด ์์ -->
<div class="absolute bg-white/30 backdrop-blur-md">
<!-- ๋ถ๋ชจ์ ๋ฐฐ๊ฒฝ์ด ์์ผ๋ฉด ํ๋ฆด ๊ฒ๋ ์์ด์ ํจ๊ณผ ์์ -->
</div>
<!-- โ
์ฌ๋ฐ๋ฅธ Glassmorphism ๋ ์ํผ -->
<!-- 1๏ธโฃ ๋ค์ ์๋ ๋ฐฐ๊ฒฝ -->
<div class="relative h-screen bg-[url(/hero-bg.jpg)] bg-cover">
<!-- 2๏ธโฃ ๋ฐํฌ๋ช
๋ฐฐ๊ฒฝ์ (bg-white/10, bg-white/20 ๋ฑ) -->
<!-- 3๏ธโฃ backdrop-blur ์ ์ฉ -->
<nav class="
absolute inset-x-0 top-0
bg-white/10 /* 10% ๋ถํฌ๋ช
ํฐ์ - ํต์ฌ! */
backdrop-blur-md /* ๋ค ๋ฐฐ๊ฒฝ 12px ๋ธ๋ฌ */
border-b border-white/20
px-6 py-4
">
๋ค๋น๊ฒ์ด์
๋ฉ๋ด
</nav>
</div>backdrop-filter ์ ์ฒด ์ ํธ๋ฆฌํฐ
backdrop-blur-* ์ธ์๋ ๋ฐฐ๊ฒฝ์ ์ ์ฉ ๊ฐ๋ฅํ ํํฐ๋ค์ด ์์ด:
<!-- ๋ฐฐ๊ฒฝ ๋ธ๋ฌ -->
<div class="backdrop-blur-sm">...</div> <!-- 8px -->
<div class="backdrop-blur-md">...</div> <!-- 12px -->
<div class="backdrop-blur-lg">...</div> <!-- 16px -->
<div class="backdrop-blur-xl">...</div> <!-- 24px -->
<!-- ๋ฐฐ๊ฒฝ ๋ฐ๊ธฐ -->
<div class="backdrop-brightness-75">...</div> <!-- ์ด๋ก๊ฒ -->
<div class="backdrop-brightness-125">...</div> <!-- ๋ฐ๊ฒ -->
<!-- ๋ฐฐ๊ฒฝ ๋๋น -->
<div class="backdrop-contrast-125">...</div>
<!-- ๋ฐฐ๊ฒฝ ํ๋ฐฑ -->
<div class="backdrop-grayscale">...</div>
<!-- ๋ฐฐ๊ฒฝ ๋ถํฌํ -->
<div class="backdrop-saturate-150">...</div>์๋์ด๊ฐ ์กฐํฉํ๋ ์ค์ ๋ ์ํผ
<!-- ๐ฆ ์ํธ์ ํ๋ฆฌ๋ฏธ์ Glass ์นด๋ ๋ ์ํผ -->
<div class="
relative
bg-white/10 /* ๋ฐํฌ๋ช
ํฐ์ */
backdrop-blur-md /* ๋ฐฐ๊ฒฝ ๋ธ๋ฌ */
backdrop-brightness-90 /* ๋ฐฐ๊ฒฝ ์ด์ง ์ด๋ก๊ฒ = ๊น์ด๊ฐ */
backdrop-saturate-150 /* ๋ฐฐ๊ฒฝ ์ฑ๋ ๋์ฌ์ ์ ๋ช
ํ๊ฒ */
border border-white/25 /* ์ ๋ฆฌ ํ
๋๋ฆฌ */
rounded-2xl
shadow-xl
">
<!-- ์ ๋ฆฌ ํจ๋ ๋ด๋ถ ์ฝํ
์ธ -->
</div>๐ 3๋จ๊ณ: Gradient โ ์์์ ํ๋ฆ์ ์ค๊ณํ๋ค
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
- linear, radial, conic ์ธ ๊ฐ์ง gradient์ ์ฐจ์ด์ ๊ฐ๊ฐ์ ์ฌ์ฉ ์์ ์ ์ ์ ์๋ค.
from-*,via-*,to-*์์ ์ ์ง์ ์ ์กฐํฉํด ๋ณต์กํ ๊ทธ๋ผ๋์ธํธ๋ฅผ ์ค๊ณํ ์ ์๋ค.
Linear Gradient (์ ํ ๊ทธ๋ผ๋์ธํธ)
Tailwind v4์์ gradient ์ ํธ๋ฆฌํฐ๊ฐ ํฌ๊ฒ ์ ๋ฐ์ดํธ๋์ด. ๋ฐฉํฅ ์ง์ ๋ฐฉ์์ด ๊ธฐ์กด๋ณด๋ค ํจ์ฌ ์ ์ฐํด์ก์ด.
<!-- ๋ฐฉํฅ ์ง์ : bg-linear-to-{๋ฐฉํฅ} -->
<div class="bg-linear-to-r from-indigo-500 to-purple-500">์ผ์ชฝโ์ค๋ฅธ์ชฝ</div>
<div class="bg-linear-to-br from-cyan-500 to-blue-500">์ผ์ชฝ์โ์ค๋ฅธ์ชฝ์๋</div>
<div class="bg-linear-to-t from-emerald-500 to-teal-300">์๋โ์</div>
<!-- ๊ฐ๋ ์ง์ (Tailwind v4): bg-linear-{angle} -->
<div class="bg-linear-45 from-pink-500 to-rose-500">45๋ ๋ฐฉํฅ</div>
<div class="bg-linear-135 from-violet-500 to-purple-500">135๋ ๋ฐฉํฅ</div>๋ฐฉํฅ ์ฝ์ด ์ฐธ์กฐํ:
| ์ ํธ๋ฆฌํฐ | ๋ฐฉํฅ |
|---|---|
bg-linear-to-t | ์๋ โ ์ (โ) |
bg-linear-to-tr | ์ผ์ชฝ์๋ โ ์ค๋ฅธ์ชฝ์ (โ) |
bg-linear-to-r | ์ผ์ชฝ โ ์ค๋ฅธ์ชฝ (โ) |
bg-linear-to-br | ์ผ์ชฝ์ โ ์ค๋ฅธ์ชฝ์๋ (โ) |
bg-linear-to-b | ์ โ ์๋ (โ) |
bg-linear-to-bl | ์ค๋ฅธ์ชฝ์ โ ์ผ์ชฝ์๋ (โ) |
bg-linear-to-l | ์ค๋ฅธ์ชฝ โ ์ผ์ชฝ (โ) |
bg-linear-to-tl | ์ค๋ฅธ์ชฝ์๋ โ ์ผ์ชฝ์ (โ) |
์์ ์ ์ง์ : from, via, to
<!-- ๊ธฐ๋ณธ: ์์์ โ ๋์ -->
<div class="bg-linear-to-r from-cyan-500 to-blue-500">
cyan์์ blue๋ก
</div>
<!-- ๊ฒฝ์ ์ ์ถ๊ฐ: from โ via โ to -->
<div class="bg-linear-to-r from-indigo-500 via-purple-500 to-pink-500">
์ธ๋๊ณ โ ๋ณด๋ผ โ ๋ถํ (Instagram ์คํ์ผ)
</div>
<!-- ์ ์ง์ ์์น ์ง์ -->
<div class="bg-linear-to-r from-indigo-500 from-10% via-sky-500 via-30% to-emerald-500 to-90%">
<!-- from-10%: ์์์ ์ 10% ์์น์์ ์์ -->
<!-- via-30%: ๊ฒฝ์ ์ ์ด 30% ์์น -->
<!-- to-90%: ๋์ ์ 90% ์์น์์ ์ข
๋ฃ -->
์ ๊ตํ๊ฒ ์กฐ์ ๋ ๊ทธ๋ผ๋์ธํธ
</div>Radial Gradient (๋ฐฉ์ฌํ ๊ทธ๋ผ๋์ธํธ)
<!-- ๊ธฐ๋ณธ ๋ฐฉ์ฌํ: ์ค์์์ ํผ์ ธ๋๊ฐ๋ -->
<div class="bg-radial from-pink-400 to-fuchsia-700">
<!-- ์์ชฝ pink โ ๋ฐ๊นฅ์ชฝ fuchsia -->
</div>
<!-- ์์์ ์ปค์คํฐ๋ง์ด์ฆ -->
<div class="bg-radial-[at_50%_75%] from-sky-200 via-blue-400 to-indigo-900 to-90%">
<!-- 75% ์ง์ (์๋์ชฝ)์์ ๋ฐฉ์ฌ ์์ - ์กฐ๋ช
ํจ๊ณผ์ฒ๋ผ ๋ณด์ -->
</div>
<div class="bg-radial-[at_25%_25%] from-white to-zinc-900 to-75%">
<!-- ์ผ์ชฝ ์ 25% ์ง์ ์์ ๋ฐฉ์ฌ - ์ฝ๋ ์กฐ๋ช
ํจ๊ณผ -->
</div>Conic Gradient (์๋ฟํ ๊ทธ๋ผ๋์ธํธ)
ํ์ด ์ฐจํธ, ๋ก๋ฉ ์คํผ๋, ํ๋ก๊ทธ๋ํฝ ํจ๊ณผ์ ํ์ฉ๋ผ.
<!-- ์๋ฟํ ๊ทธ๋ผ๋์ธํธ -->
<div class="size-24 rounded-full bg-conic from-blue-600 to-sky-400 to-50%">
<!-- ๋ฐ์๋ง ์ฑ์ฐ๋ ํ์ด ์ฐจํธ ํจ๊ณผ -->
</div>
<div class="size-24 rounded-full bg-conic/decreasing from-violet-700 via-lime-300 to-violet-700">
<!-- decreasing: ์์ ๋ณด๊ฐ ๋ฐฉํฅ ์ญ์ - ํ๋ก๊ทธ๋ํฝ ํจ๊ณผ -->
</div>์์ ๋ณด๊ฐ ๋ชจ๋ (Tailwind v4 ์ ๊ธฐ๋ฅ)
<!-- Tailwind v4: ๊ทธ๋ผ๋์ธํธ ๋ณด๊ฐ ์๊ณต๊ฐ ์ ํ ๊ฐ๋ฅ -->
<div class="bg-linear-to-r/srgb from-indigo-500 to-teal-400">sRGB ๋ณด๊ฐ</div>
<div class="bg-linear-to-r/oklch from-indigo-500 to-teal-400">oklch ๋ณด๊ฐ (๋ ์์ํ ์)</div>
<div class="bg-linear-to-r/hsl from-indigo-500 to-teal-400">HSL ๋ณด๊ฐ</div>
<!-- ๐ก ํ: ๊ธฐ๋ณธ๊ฐ์ oklab. oklch๊ฐ ๊ฐ์ฅ ์ง๊ฐ์ ์ผ๋ก ๊ท ์ผํ ์์ ์ ํ์ ๋ณด์ฌ์ค -->โ๏ธ 4๋จ๊ณ: Gradient Text โ ํ ์คํธ์ ๊ทธ๋ผ๋์ธํธ ์ ํ๊ธฐ
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
- Gradient Text๊ฐ ์๋ํ๊ธฐ ์ํ 3๊ฐ์ง CSS ์์ฑ์ ์ดํดํ๋ค.
- ์
text-transparent๊ฐ ํ์์ธ์ง ์ค๋ช ํ ์ ์๋ค.
์์๋ค ์ปค๋ฎค๋ํฐ ๋๋ฉ ํ์ด์ง์ ํ์ด๋ก ํ์ดํ์ฒ๋ผ ํ ์คํธ์ ๊ทธ๋ผ๋์ธํธ๋ฅผ ์ ํ๋ ๊ธฐ๋ฒ์ด์ผ.
<!-- ๐ฃ ์์ฒ : "๊ทธ๋ผ๋์ธํธ ํ
์คํธ๋ฅผ span์ background ์ฃผ๋ฉด ๋๋์?" -->
<!-- ์๋์ผ. ์ด๊ฑด ํน๋ณํ 3๋จ๊ณ ํธ๋ฆญ์ด ์์ด. -->
<!-- Gradient Text ๋ง๋ฒ์ 3๊ฐ์ง ์ฌ๋ฃ -->
<h1 class="
bg-linear-to-r from-violet-600 to-indigo-600 /* 1๏ธโฃ gradient ๋ฐฐ๊ฒฝ */
bg-clip-text /* 2๏ธโฃ ๋ฐฐ๊ฒฝ์ ํ
์คํธ ๋ชจ์์ผ๋ก ์๋ผ๋ */
text-transparent /* 3๏ธโฃ ํ
์คํธ ์์์ ํฌ๋ช
ํ๊ฒ โ ๋ฐฐ๊ฒฝ์ด ๋น์นจ */
">
๊ฐ๋ฐ์ ์คํฐ๋ ๋งค์นญ ์ปค๋ฎค๋ํฐ
</h1>์ ์ด 3๊ฐ๊ฐ ๋์์ ํ์ํ๊ฐ?
bg-linear-to-r from-violet-600 to-indigo-600: ์์์ ๊ทธ๋ผ๋์ธํธ ๋ฐฐ๊ฒฝ ์์ฑbg-clip-text: ๋ฐฐ๊ฒฝ์ ํ ์คํธ ๊ธ์ ๋ชจ์์ผ๋ก๋ง ์๋ผ๋ (clip)text-transparent: ํ ์คํธ ๊ธ์ ์์ฒด์ ์์์ ํฌ๋ช ํ๊ฒ ๋ง๋ฆ
์ด ์ธ ๊ฐ๊ฐ ํ๋ ฅํด์ผ๋ง "๋ฐฐ๊ฒฝ ๊ทธ๋ผ๋์ธํธ๊ฐ ํ ์คํธ ๋ชจ์์ผ๋ก ๋ณด์ด๋" ์ฐฉ์๊ฐ ์์ฑ๋ผ.
<!-- ์ค์ ์์: ๋ค์ํ gradient text -->
<h1 class="bg-linear-to-r from-pink-500 via-purple-500 to-indigo-500 bg-clip-text text-transparent text-5xl font-bold">
์คํฐ๋ ๋งค์นญ ํ๋ซํผ
</h1>
<!-- dark mode ๋์ -->
<h2 class="bg-linear-to-r from-teal-400 to-cyan-300 dark:from-teal-300 dark:to-cyan-200 bg-clip-text text-transparent">
์์๋ค ์ปค๋ฎค๋ํฐ
</h2>
<!-- ๐จ ์๋์ด ์ฃผ์์ฌํญ: print ๋ชจ๋์์๋ ํ
์คํธ๊ฐ ์ ๋ณด์ผ ์ ์์ -->
<!-- print:text-gray-900 ์ฒ๋ผ ์ธ์ ๋์์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์ -->
<h1 class="bg-linear-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent print:text-gray-900">
์ธ์ ๋์๋ ๊ทธ๋ผ๋์ธํธ ํ
์คํธ
</h1>๐ญ 5๋จ๊ณ: Mix Blend Mode โ ๋ ์ด์ด์ ์ฐ๊ธ์
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
mix-blend-*์ ํธ๋ฆฌํฐ๊ฐ Photoshop ๋ ์ด์ด ํผํฉ ๋ชจ๋์ ๋์ผํ ์๋ฆฌ์์ ์ดํดํ๋ค.- ์ค๋ฌด์์ ์์ฃผ ์ฐ์ด๋
mix-blend-multiply,mix-blend-screen์ ์ฐจ์ด๋ฅผ ์ ์ ์๋ค.
ํฌํ ์ต์ ๋ ์ด์ด ํจ๋์์ "๊ณฑํ๊ธฐ(Multiply)", "์คํฌ๋ฆฐ(Screen)" ๊ฐ์ ๊ฑธ ์จ๋ณธ ์ ์์ด? CSS์ mix-blend-mode ๊ฐ ๋ฐ๋ก ๊ทธ๊ฑฐ์ผ.
<!-- mix-blend-multiply: ์์์ ๊ณฑํด์ ์ด๋์์ง (ํฐ ๋ฐฐ๊ฒฝ = ํฌ๋ช
ํด์ง) -->
<!-- ํฐ์ ๋ฐฐ๊ฒฝ ์์ ์ด๋ฏธ์ง์์ ํฐ ์์ญ์ ๋ ๋ ค๋ฒ๋ฆฌ๋ ํจ๊ณผ -->
<div class="relative bg-indigo-100">
<img src="/logo-white-bg.png" class="mix-blend-multiply" />
<!-- ๋ก๊ณ ์ ํฐ ๋ฐฐ๊ฒฝ์ด ์ฌ๋ผ์ง๊ณ ๋ก๊ณ ๋ง ๋ณด์ -->
</div>
<!-- mix-blend-screen: ์์์ ์คํฌ๋ฆฐ ์ฒ๋ฆฌํด์ ๋ฐ์์ง (๊ฒ์ ๋ฐฐ๊ฒฝ = ํฌ๋ช
ํด์ง) -->
<div class="relative bg-gray-900">
<img src="/light-flare.png" class="mix-blend-screen" />
<!-- ๋น ํจ๊ณผ ์ด๋ฏธ์ง์ ๊ฒ์ ๋ฐฐ๊ฒฝ์ ๋ ๋ ค๋ฒ๋ฆผ -->
</div>
<!-- mix-blend-overlay: ๋ฐ์ ๋ถ๋ถ์ ๋ ๋ฐ๊ฒ, ์ด๋์ด ๋ถ๋ถ์ ๋ ์ด๋ก๊ฒ -->
<div class="relative">
<img src="/photo.jpg" />
<div class="absolute inset-0 bg-indigo-500 mix-blend-overlay opacity-40">
<!-- ์ฌ์ง ์์ ์๊ฐ ์ค๋ฒ๋ ์ด ํจ๊ณผ -->
</div>
</div>์์ฃผ ์ฐ์ด๋ blend mode ์ ๋ฆฌ:
| ์ ํธ๋ฆฌํฐ | ํจ๊ณผ | ์ฉ๋ |
|---|---|---|
mix-blend-multiply | ์ ๊ณฑํ๊ธฐ (์ด๋์์ง) | ํฐ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ์ค๋ฒ๋ ์ด |
mix-blend-screen | ์ ์คํฌ๋ฆฐ (๋ฐ์์ง) | ์ด๋์ด ๋ฐฐ๊ฒฝ์ ๋น ํจ๊ณผ |
mix-blend-overlay | ๊ณฑํ๊ธฐ + ์คํฌ๋ฆฐ ํฉ์ฑ | ์๊ฐ ํํฐ ํจ๊ณผ |
mix-blend-difference | ์์ ์ฐจ์ด๊ฐ | ๋ฐ์ ๋ง์คํฌ ํจ๊ณผ |
mix-blend-luminosity | ๋ช ๋๋ง ํฉ์ฑ | ์์ ์ ์งํ๋ฉฐ ๋ช ๋ ๋ณ๊ฒฝ |
๐ ์ค์ : ์์๋ค ์ปค๋ฎค๋ํฐ Glassmorphism ๊ตฌํ
์ด์ ๋ฐฐ์ด ๋ชจ๋ ๊ฒ์ ํฉ์ณ์ ์ค์ ์์๋ค ์ปค๋ฎค๋ํฐ์ ๋๋ฉ ํ์ด์ง๋ฅผ ๊ตฌํํด๋ณด์.
Glassmorphism ๋ค๋น๊ฒ์ด์ ๋ฐ
// components/GlassNavbar.tsx
// ๐ฆ ์ํธ: "์คํฌ๋กค ๋ด๋ ค๋ ๋ฐฐ๊ฒฝ์ด ์์๊ฒ ๋ณด์ด๋ ๋ค๋น๋ฐ์ผ, ์์ฒ ๋"
export default function GlassNavbar() {
return (
// ์ ์ฒด ํ์ด์ง ๋ํผ - ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง๊ฐ ๋ค์ ์์ด์ผ backdrop-blur ํจ๊ณผ๊ฐ ๋ณด์
<div className="relative min-h-screen">
{/* 1๏ธโฃ ๋ค์ ์๋ ๋ฐฐ๊ฒฝ */}
<div className="absolute inset-0 bg-linear-to-br from-violet-900 via-indigo-900 to-purple-900" />
{/* ๋ฐฐ๊ฒฝ ์ฅ์ ์์๋ค (blur๋ก ๋ณด์ผ ํจ๊ณผ) */}
<div className="absolute top-20 left-10 size-72 bg-purple-500/30 rounded-full blur-3xl" />
<div className="absolute top-40 right-20 size-56 bg-indigo-500/20 rounded-full blur-2xl" />
{/* 2๏ธโฃ Glassmorphism ๋ค๋น๊ฒ์ด์
*/}
<nav className="
sticky top-0 z-50
bg-white/10 /* ๋ฐํฌ๋ช
ํฐ์ ๋ฐฐ๊ฒฝ - ํต์ฌ! */
backdrop-blur-md /* ๋ค ๋ฐฐ๊ฒฝ ๋ธ๋ฌ */
backdrop-saturate-150 /* ๋ฐฐ๊ฒฝ ์ฑ๋ ๋์ฌ์ ์ ๋ฆฌ๊ฐ ์ฆ๊ฐ */
border-b border-white/20 /* ์ ๋ฆฌ ํ
๋๋ฆฌ */
px-6 py-4
">
<div className="max-w-7xl mx-auto flex items-center justify-between">
{/* ๋ก๊ณ - gradient text */}
<span className="
text-xl font-bold
bg-linear-to-r from-violet-300 to-indigo-300
bg-clip-text text-transparent
">
์์๋ค ์ปค๋ฎค๋ํฐ
</span>
{/* ๋ฉ๋ด ๋งํฌ */}
<div className="flex gap-6 text-white/80">
<a href="/studies" className="hover:text-white transition-colors">์คํฐ๋ ์ฐพ๊ธฐ</a>
<a href="/create" className="hover:text-white transition-colors">์คํฐ๋ ๋ง๋ค๊ธฐ</a>
<a href="/profile" className="hover:text-white transition-colors">ํ๋กํ</a>
</div>
{/* CTA ๋ฒํผ - Glass ์คํ์ผ */}
<button className="
px-4 py-2 rounded-lg
bg-white/20 /* ์ฝ๊ฐ ๋ ์งํ glass */
backdrop-blur-sm
border border-white/30
text-white text-sm font-medium
hover:bg-white/30
transition-all duration-200
">
์์ํ๊ธฐ
</button>
</div>
</nav>
{/* 3๏ธโฃ Hero ์น์
- Gradient ๋ฐฐ๊ฒฝ + Gradient Text */}
<main className="relative z-10 flex flex-col items-center justify-center min-h-screen text-center px-4">
<div className="
bg-white/5 /* ๋งค์ฐ ์ฐํ glass ํจ๋ */
backdrop-blur-sm
border border-white/10
rounded-3xl
px-12 py-16
max-w-3xl
">
{/* Gradient Text ํ์ด๋ก ํ์ดํ */}
<h1 className="
text-5xl md:text-7xl font-black
bg-linear-to-r from-violet-300 via-pink-300 to-indigo-300
bg-clip-text text-transparent
mb-6 leading-tight
">
๊ฐ๋ฐ์๋ค์ ์คํฐ๋ ๋งค์นญ
</h1>
<p className="text-white/70 text-xl mb-10 leading-relaxed">
์์๋ค ์ปค๋ฎค๋ํฐ์์ ํจ๊ป ์ฑ์ฅํ ์คํฐ๋ ํํธ๋๋ฅผ ์ฐพ์๋ณด์ธ์.
React, TypeScript, ์๊ณ ๋ฆฌ์ฆ - ์ํ๋ ์ฃผ์ ๋ก ๋ฐ๋ก ์์!
</p>
<div className="flex gap-4 justify-center flex-wrap">
{/* Primary ๋ฒํผ - solid gradient */}
<button className="
px-8 py-3.5 rounded-xl
bg-linear-to-r from-violet-500 to-indigo-500
text-white font-semibold text-lg
hover:from-violet-400 hover:to-indigo-400
transition-all duration-200
shadow-lg shadow-indigo-500/25
drop-shadow-lg
">
์คํฐ๋ ์ฐพ๊ธฐ
</button>
{/* Secondary ๋ฒํผ - glass */}
<button className="
px-8 py-3.5 rounded-xl
bg-white/10
backdrop-blur-sm
border border-white/30
text-white font-semibold text-lg
hover:bg-white/20
transition-all duration-200
">
์คํฐ๋ ๋ง๋ค๊ธฐ
</button>
</div>
</div>
</main>
</div>
);
}์คํฐ๋ ์นด๋ - ์ด๋ฏธ์ง ํํฐ ํจ๊ณผ
// components/StudyCard.tsx
// ๐ฃ ์์ฒ : "๋ง๊ฐ๋ ์คํฐ๋ ์นด๋๋ฅผ ์๊ฐ์ ์ผ๋ก ๊ตฌ๋ถํ๊ณ ์ถ์ด์"
// ๐ฆ ์ํธ: "grayscale + brightness ์กฐํฉ์ด๋ฉด ๋ผ์"
interface StudyCardProps {
title: string;
thumbnail: string;
isClosed: boolean;
memberCount: number;
}
export default function StudyCard({ title, thumbnail, isClosed, memberCount }: StudyCardProps) {
return (
<div className="group relative rounded-2xl overflow-hidden bg-white shadow-md hover:shadow-xl transition-all duration-300">
{/* ์ธ๋ค์ผ ์ด๋ฏธ์ง */}
<div className="relative h-48">
<img
src={thumbnail}
alt={title}
className={`
w-full h-full object-cover
transition-all duration-500
group-hover:scale-105 /* hover ์ ์ด๋ฏธ์ง ํ๋ */
${isClosed ? 'grayscale brightness-75' : 'grayscale-0 brightness-100'}
`}
/>
{/* ๋ง๊ฐ ๋ฐฐ์ง - drop-shadow ํ์ฉ */}
{isClosed && (
<div className="
absolute top-3 right-3
bg-red-500/90 backdrop-blur-sm
text-white text-xs font-bold
px-2.5 py-1 rounded-full
drop-shadow-md
">
๋ชจ์ง ๋ง๊ฐ
</div>
)}
{/* ์ด๋ฏธ์ง ํ๋จ ๊ทธ๋ผ๋์ธํธ ์ค๋ฒ๋ ์ด */}
<div className="
absolute inset-x-0 bottom-0 h-20
bg-linear-to-t from-black/60 to-transparent
" />
</div>
{/* ์นด๋ ๋ด์ฉ */}
<div className="p-4">
<h3 className="font-semibold text-gray-900">{title}</h3>
<p className="text-sm text-gray-500 mt-1">๋ฉค๋ฒ {memberCount}๋ช
</p>
</div>
</div>
);
}๐ ์ด๋ฒ์ ๋ฐฐ์ด ๋ด์ฉ ์ด์ ๋ฆฌ
| ๋ถ๋ฅ | ์ ํธ๋ฆฌํฐ | ์๋ ๋์ | ์ฃผ์ ์ฉ๋ |
|---|---|---|---|
| ์์ ๋ธ๋ฌ | blur-sm ~ blur-3xl | ์์ ์์ | ํฌ์ปค์ค ํจ๊ณผ, ๋ฐฐ๊ฒฝ ์์ฌ |
| ์์ ๋ฐ๊ธฐ | brightness-0 ~ brightness-200 | ์์ ์์ | ํธ๋ฒ ๋คํฌ ํจ๊ณผ |
| ์์ ํ๋ฐฑ | grayscale, grayscale-0 | ์์ ์์ | ๋นํ์ฑ/๋ง๊ฐ ํ์ |
| ์์ ๊ทธ๋ฆผ์ | drop-shadow-sm ~ drop-shadow-2xl | ์์์ ์ค์ ํํ | PNG/SVG ์ ํ ๊ทธ๋ฆผ์ |
| ๋ฐฐ๊ฒฝ ๋ธ๋ฌ | backdrop-blur-sm ~ backdrop-blur-3xl | ์์ ๋ค ๋ฐฐ๊ฒฝ | Glassmorphism |
| ๋ฐฐ๊ฒฝ ๋ฐ๊ธฐ | backdrop-brightness-* | ์์ ๋ค ๋ฐฐ๊ฒฝ | ์ค๋ฒ๋ ์ด ๊น์ด๊ฐ |
| ์ ํ ๊ทธ๋ผ๋์ธํธ | bg-linear-to-* + from/via/to | ๋ฐฐ๊ฒฝ ์์ | Hero ์น์ , ๋ฒํผ |
| ๋ฐฉ์ฌํ ๊ทธ๋ผ๋์ธํธ | bg-radial | ๋ฐฐ๊ฒฝ ์์ | ์กฐ๋ช ํจ๊ณผ, ์์ด์ฝ |
| ๊ทธ๋ผ๋์ธํธ ํ ์คํธ | bg-clip-text + text-transparent | ํ ์คํธ | ํ์ด๋ก ํ์ดํ |
| ๋ธ๋ ๋ ๋ชจ๋ | mix-blend-* | ๋ ์ด์ด ํฉ์ฑ | ์ด๋ฏธ์ง ์ค๋ฒ๋ ์ด |
๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. ์์๋ค ์ปค๋ฎค๋ํฐ Hero ์น์ ์์ ์์์ด๊ฐ "๋ค๋น๊ฒ์ด์ ๋ฐ์ backdrop-blur-xl์ ์คฌ๋๋ฐ ํจ๊ณผ๊ฐ ์ ํ ์ ๋ณด์ฌ์!"๋ผ๊ณ ํ๋ค. ์์ธ์ผ๋ก ๊ฐ์ฅ ๊ฐ๋ฅ์ฑ ๋์ ๊ฒ์?
โ
์ ๋ต: ๋ค๋น๊ฒ์ด์
๋ฐ์ ๋ฐฐ๊ฒฝ์์ด ์์ ๋ถํฌ๋ช
(bg-white ๋ฑ)์ด๊ฑฐ๋, ๋ค์ ์ค์ ๋ฐฐ๊ฒฝ์ด ์์ด์
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช
:
backdrop-filter: blur()๋ ์์ ๋ค์ ์๋ ๋ด์ฉ์ ๋ธ๋ฌ ์ฒ๋ฆฌํด. ๋ง์ฝ ์์์ ๋ฐฐ๊ฒฝ์ด ์์ ๋ถํฌ๋ช (bg-white)์ด๋ผ๋ฉด, ๋ค์ ๋ด์ฉ์ด ์์ ํ ๊ฐ๋ ค์ง๊ธฐ ๋๋ฌธ์ ๋ธ๋ฌํ ๊ฒ ์์ฒด๊ฐ ์์ด. Glassmorphism์ ๋ฐ๋์bg-white/10์ฒ๋ผ ๋ฐํฌ๋ช (alpha < 1) ๋ฐฐ๊ฒฝ๊ณผ ํจ๊ป ์จ์ผ ํด. - ์ค๋ต ํผ๋๋ฐฑ: "backdrop-blur ๊ฐ์ด ๋๋ฌด ์์์"๊ฐ ์๋์ผ.
backdrop-blur-sm๋ 8px์ด๋ผ ์ถฉ๋ถํ ๋ณด์ฌ. ํต์ฌ์ ๋ฐํฌ๋ช ๋ฐฐ๊ฒฝ ์ฌ๋ถ์ผ. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: Glassmorphism = ๋ฐํฌ๋ช
๋ฐฐ๊ฒฝ(
bg-white/10) +backdrop-blur-*+ ๋ค์ ๋ฐฐ๊ฒฝ ์กด์ฌ. ์ด 3๋ฐ์๊ฐ ๋ง์์ผ ํด.
Q2. ์์ฒ ์ด๊ฐ ํฌ๋ช
PNG ๋ก๊ณ ์ด๋ฏธ์ง์ ๊ทธ๋ฆผ์๋ฅผ ๋ถ์ด๋ ค๊ณ shadow-xl์ ์ ์ฉํ๋๋ฐ, ๋ก๊ณ ํํ๊ฐ ์๋ ์ฌ๊ฐํ ๊ทธ๋ฆผ์๊ฐ ์๊ฒผ๋ค. ์ด๋ค ์ ํธ๋ฆฌํฐ๋ฅผ ์จ์ผ ํ๋๊ฐ?
โ
์ ๋ต: drop-shadow-xl
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช
:
shadow-*(box-shadow)๋ CSS์box-shadow์์ฑ์ผ๋ก, ์์์ ๋ฐ์ค ๋ชจ๋ธ(์ฌ๊ฐํ ๊ฒฝ๊ณ) ์ ๊ทธ๋ฆผ์๋ฅผ ์ ์ฉํด. ์ด๋ฏธ์ง ๋ด๋ถ๊ฐ ํฌ๋ช ํด๋ ๊ทธ๋ฆผ์๋ ์ฌ๊ฐํ์ผ๋ก ๋์. ๋ฐ๋ฉดdrop-shadow-*๋filter: drop-shadow()๋ฅผ ์ฌ์ฉํด ์์์ ์ค์ ๋ถํฌ๋ช ํฝ์ ํํ๋ฅผ ๋ฐ๋ผ ๊ทธ๋ฆผ์๋ฅผ ์์ฑํด. - ์ค๋ต ํผ๋๋ฐฑ: "๋ ํฐ shadow ๊ฐ์ ์ฐ๋ฉด ๋๋ค" - ์ ๋ ํด๊ฒฐ ์ ๋จ. ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ CSS ์์ฑ์ด์ผ.
- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: box-shadow = ๋ฐ์ค ํํ ๊ทธ๋ฆผ์ / drop-shadow = ํฝ์ ํํ ๊ทธ๋ฆผ์. PNG/SVG โ drop-shadow, div/button โ shadow ๊ฐ ๊ธฐ๋ณธ ์์น.
Q3. ์์์ด๊ฐ "๋ก๊ณ ํ ์คํธ์ ๋ณด๋ผ์์์ ํ๋์์ผ๋ก ํ๋ฅด๋ ๊ทธ๋ผ๋์ธํธ ์์์ ๋ฃ๊ณ ์ถ์ด์"๋ผ๊ณ ํ๋ค. ์ํธ๊ฐ ์์ฑํ ์ฌ๋ฐ๋ฅธ ์ฝ๋๋?
โ ์ ๋ต:
<span class="bg-linear-to-r from-violet-500 to-blue-500 bg-clip-text text-transparent">
์์๋ค ์ปค๋ฎค๋ํฐ
</span>๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช
: Gradient Text๋ 3๋จ๊ณ ์กฐํฉ์ด ํ์์ผ. โ
bg-linear-to-r from-violet-500 to-blue-500์ผ๋ก ๊ทธ๋ผ๋์ธํธ ๋ฐฐ๊ฒฝ์ ๋ง๋ค๊ณ , โกbg-clip-text๋ก ๊ทธ ๋ฐฐ๊ฒฝ์ ํ ์คํธ ๋ชจ์์ผ๋ก ์๋ฅด๊ณ , โขtext-transparent๋ก ํ ์คํธ ์์ฒด์ ์์ ํฌ๋ช ํ๊ฒ ๋ง๋ค์ด ๋ฐฐ๊ฒฝ ๊ทธ๋ผ๋์ธํธ๊ฐ ๋น์น๊ฒ ํด. - ์ค๋ต ํผ๋๋ฐฑ:
text-violet-500์ฒ๋ผ ๋จ์text-*์ปฌ๋ฌ ์ ํธ๋ฆฌํฐ๋ ๋จ์๋ง ์ง์ํด. ๊ทธ๋ผ๋์ธํธ ํ ์คํธ๋ ๋ฐฐ๊ฒฝ ํธ๋ฆญ์ ์จ์ผ ํด. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: Gradient Text = ๋ฐฐ๊ฒฝ์ ๋ง๋ค๊ณ + ํ ์คํธ ๋ชจ์์ผ๋ก ์๋ฅด๊ณ + ํ ์คํธ๋ฅผ ํฌ๋ช ํ๊ฒ. ์ด ์์๊ฐ ํ ์ธํธ์ผ.
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
์ค๋ ์์ ๋๋๊ฐ ์์ฒญํ "์ ๋ฆฌ ํจ๊ณผ ๋ค๋น๋ฐ" ๋๋ฌธ์ ์ฒ์์ Canvas API ๊ณต๋ถ๋ฅผ ์์ํ๋ค.
๋ฐฐ๊ฒฝ ํฝ์ ์ ํ๋ํ๋ ์ฝ์ด์ blur ์ฒ๋ฆฌํ๊ณ ๋ค์ ๊ทธ๋ฆฐ๋ค๋ ๊ฒ ๋ญ๊ฐ ์์ฒญ ํ๋ค ๊ฒ ๊ฐ์์ ๋ฌด์์ ๋๋ฐ...์ํธ ํ์ด
backdrop-blur-md bg-white/10์ด๋ผ๋ ๋จ ๋ ํด๋์ค๋ฅผ ๋ณด์ฌ์คฌ์ ๋ ๋ง์น๋ก ๋จธ๋ฆฌ๋ฅผ ์ป์ด๋ง์ ๊ฒ ๊ฐ์๋ค."ํ... ์ด๊ฒ ๋ค์์?"
"์ด๊ฒ ๋ค์์."๋ธ๋ผ์ฐ์ ๊ฐ GPU๋ก ์ด๊ฑธ ์ฒ๋ฆฌํ๋ค๋ ๊ฒ๋, ๋ด๊ฐ ์ง๋ ค๋ Canvas ์ฝ๋์ 1000๋ถ์ 1์ ์ฑ๋ฅ์ผ๋ก.
์ค๋ ๋ฐฐ์ด ๊ฒ: CSS๋ ๋ด๊ฐ ์๊ฐํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๊ฐ๋ ฅํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ํธ ํ์ ๋ฌด์ญ๋ค.