๐ฌ 10. CSS ์ ๋๋ฉ์ด์ : '์์ง์์ ๋ฏธํ, ์ฑ๋ฅ์ ํ์'
๐ ๊ฐ์
์น์ ์๋ช ๋ ฅ์ ๋ถ์ด๋ฃ๋ CSS ์ ๋๋ฉ์ด์ ์ ํต์ฌ ๊ธฐ๋ฒ๊ณผ, 60fps์ ๋ถ๋๋ฌ์์ ์ ์งํ๊ธฐ ์ํ ์ฑ๋ฅ ์ต์ ํ ์ ๋ต์ ์์ฒ ์ด์ ํจ๊ป ์์ฑํด ๋ด ๋๋ค.
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 11๋ถ(์ ์ฒด) / ํต์ฌ ํํธ๋ง: 6๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
[Transition vs Animation] โ [Keyframes์ ์ ๊ตํจ] โ [GPU ๊ฐ์๊ณผ ์ฑ๋ฅ ์ต์ ํ]
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- ๋จ์ํ ์ํ ๋ณํ๋
transition์ผ๋ก, ๋ณต์กํ ์ํ์ค๋animation์ผ๋ก ๊ตฌํํฉ๋๋ค. -
cubic-bezier๋ฅผ ํ์ฉํด ๊ธฐ๊ณ์ ์ด์ง ์์ ์์ฐ์ค๋ฌ์ด ์์ง์์ ๋ง๋ญ๋๋ค. - ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ํ์ดํ๋ผ์ธ์ ์ดํดํด ๋ ์๋ ์ ๋๋ฉ์ด์ ์ ์ค๊ณํฉ๋๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ๐ฃ ์์ฒ ( ์ ์ ): "์ํธ ๋! ๋ฒํผ์ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ฆด ๋ ์ฅ ์ปค์ง๋ ํจ๊ณผ๋ฅผ ๋ฃ์๋๋ฐ, ์ปดํฌ๋ํธ๊ฐ ๋ง์์ง๋๊น ํ๋ฉด์ด ๋๋ ๋๊ฒจ์. ์ ์ ๋ค์ด '์ด ์ฌ์ดํธ ์ ์ด๋ ๊ฒ ๋ฌด๊ฑฐ์?'๋ผ๊ณ ๋ฆฌ๋ทฐ๋ฅผ ๋จ๊ฒผ๋์. ์ ์ด๋กํ์ฃ ? ๐ญ"
- ๐ฆ ์ํธ ( ๋ฆฌ๋ ): "์์ฒ ๋, ์ ๋๋ฉ์ด์ ์ '์ฌ์น'๊ฐ ์๋๋ผ '๊ณผํ'์ ๋๋ค. ์๋ฆ๋ต๊ฒ ์์ง์ด๋ ๊ฒ๋งํผ ์ค์ํ ๊ฑด ์ฌ์ฉ์์ CPU/GPU์ ๋ฌด๋ฆฌ๋ฅผ ์ฃผ์ง ์๋ ์ ์ ์ฃ . ์, ๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ผ ์ข์ํ๋ ์ ๋๋ฉ์ด์ ์ด ๋ญ์ง ๊ฐ๋ฅด์ณ์ค๊ฒ์."
๐ค ์ ์์์ผ ํ๋๊ฐ
์ ๋๋ฉ์ด์ ์ ๋จ์ํ ์๊ฐ์ ํจ๊ณผ๋ฅผ ๋์ด, ์ ์ ์๊ฒ ํ์ฌ ์ด๋ค ๋์์ด ์ผ์ด๋๊ณ ์๋์ง ์๋ ค์ฃผ๋ ์ค์ํ ํผ๋๋ฐฑ ์๋จ(Micro-interaction)์ ๋๋ค. ํ์ง๋ง ์๋ชป ๊ตฌํ๋ ์ ๋๋ฉ์ด์ ์ ์ ์ฒด ์น์ฌ์ดํธ์ ์ฑ๋ฅ์ ๊ฐ์๋จน๊ณ , ์ต์ ์ ๊ฒฝ์ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ฉ์ถ๊ฒ ํ ์๋ ์์ต๋๋ค.
์ ์ ์ธ ์์ฒ ์ด๊ฐ ๊ฒช์ '๋ ' ํ์์ ๋๋ถ๋ถ Reflow(Layout) ๋ฅผ ์ ๋ฐํ๋ ์์ฑ์ ์ ๋๋ฉ์ด์ ์ ์ผ๊ธฐ ๋๋ฌธ์ ๋๋ค. 5๋ ์ฐจ ์ด์์ ์๋์ด๋ ๋ธ๋ผ์ฐ์ ์ Composite ๊ณ์ธต๋ง์ ํ์ฉํ๋ ๋๋ํ ์ ๋๋ฉ์ด์ ์ ๋ง๋ค์ด, ์ฌ์ ๋ฎ์ ์ค๋งํธํฐ์์๋ 60fps์ ๋ถ๋๋ฌ์์ ์ ์ฌํฉ๋๋ค.
๐๏ธ 1. Transition vs Animation
- Transition: A ์ํ์์ B ์ํ๋ก ๋ณํํ ๋ ์๋๋ค. (์: ํธ๋ฒ ์ ์์ ๋ณ๊ฒฝ)
- Animation: ๋ ๋ณต์กํ๊ณ ๋ฐ๋ณต์ ์ธ ์ผ๋ จ์ ์์ง์์ ๋ง๋ค ๋ ์๋๋ค. (
@keyframesํ์)
/* ๐ฆ ์ํธ: ํธ๋์ง์
์ '์๊ฐ'๊ณผ 'ํ์ด๋ฐ'์ด ํต์ฌ์
๋๋ค. */
.btn {
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn:hover {
transform: scale(1.1); /* 60fps ๋ณด์ฅ! */
}๐ Transition vs Animation ๋น๊ต
Transition (๋ง์ฐ์ค๋ฅผ ์ฌ๋ ค๋ณด์ธ์!)
A โ B ์ํ ๋ณํ (๋จ์)
Animation (์๋ ๋ฐ๋ณต!)
@keyframes๋ก ์ํ์ค ์ ์ (๋ณต์ก)
โ๏ธ 2. ์ฑ๋ฅ์ ๊ณจ๋ ํ์: Reflow๋ฅผ ํผํ๋ผ
์ ๋๋ฉ์ด์ ์ ์ค ๋ ์ ๋ ๊ฑด๋๋ฆฌ์ง ๋ง์์ผ ํ ์์ฑ๋ค์ด ์์ต๋๋ค.
- ๋์ ์ (Reflow ์ ๋ฐ):
width,height,top,left,margin,padding
๐ ๋ธ๋ผ์ฐ์ ๊ฐ ๋งค ํ๋ ์๋ง๋ค ๋ชจ๋ ์ฃผ๋ณ ์์์ ์์น๋ฅผ ๋ค์ ๊ณ์ฐํด์ผ ํฉ๋๋ค. (์ง์ฅ์ ๋ ๋ฐ์) - ์ข์ ์ (Composite๋ง ํ์ฑํ):
transform(scale, rotate, translate),opacity
๐ ๋ธ๋ผ์ฐ์ ์ '๋ ์ด์ด'๋ง ์์ง์ด๋ ๊ฑฐ๋ผ GPU๊ฐ ์์ฃผ ๊ฐ๋ณ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
๐ฃ ์์ฒ : "์! ๊ทธ๋์ ์ ๊ฐ top์ ๋ฐ๊ฟ์ ๋ฒํผ์ ์ฌ๋ ธ์ ๋ ๋ ์ด ๊ฑธ๋ ธ๋ ๊ฑฐ๊ตฐ์! ์์ผ๋ก translateY๋ก ๋ฐ๊ฟ์ผ๊ฒ ์ด์!"
๐ญ 3. ์์ฐ์ค๋ฌ์ด ์์ง์: easing์ ๋ฏธํ
๋ฌผ์ฒด๋ ํ์ค์์ ์ผ์ ํ ์๋๋ก ์์ง์ด์ง ์์ต๋๋ค. linear ๋์ ease-in-out์ด๋ ์ปค์คํ
cubic-bezier๋ฅผ ์ฐ๋ฉด ํจ์ฌ ์๋๊ฐ ์๋ ์ธํฐ๋์
์ด ์์ฑ๋ฉ๋๋ค.
๐ฆ ์ํธ์ ๋ํ ์ผ:
"์ ๋๋ฉ์ด์ ์ด ๋๋๊ณ ์๋๋๋ก ๋์์ฌ ๋ ๋ ๋๊ธฐ์ง ์๋๋กtransition์ ํธ๋ฒ๊ฐ ์๋ ์๋ ์ํ์ ์ ์ํ๋ ๊ฑธ ์์ง ๋ง์ธ์."
๐จ Easing ํจ์ ๋น๊ต: ์์ง์์ ๋๋์ด ๋ฌ๋ผ์!
linear
(๊ธฐ๊ณ์ )
ease-in-out
(์์ฐ์ค๋ฌ์)
cubic-bezier
(ํ์ฑ ํจ๊ณผ!)
๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. transform: rotate(45deg); ์ ๋๋ฉ์ด์
์ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ํ์ดํ๋ผ์ธ์ ์ด๋ค ๋จ๊ณ๋ง ๊ฑฐ์น๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ์ข์ ๊ฒ์ผ๊น์?
- Layout
- Paint
- Composite
- DOM Construction
โ
์ ๋ต: 3. Composite
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ:
transform๊ณผopacity๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋ ๋ ์ด์ด๋ฅผ ๋จ์ํ ์ฌ๋ฐฐ์น๋ง ํ๋ฉด ๋ฉ๋๋ค. ๋น์ผ ๊ณ์ฐ ๊ณผ์ ์ธ Layout์ด๋ Paint๋ฅผ ๊ฑด๋๋ฐ๊ณ GPU์์ ๋ฐ๋ก ์ฒ๋ฆฌ(Composite)ํ๋ฏ๋ก ๊ฐ์ฅ ๋ถ๋๋ฝ์ต๋๋ค. - ์ค๋ต ํผ๋๋ฐฑ: "์์ฒ ๋, ๋ธ๋ผ์ฐ์ ๊ฐ ๋ ํ๋ฆฌ์ง ์๊ฒ ํ๋ ๊ฒ ๊ณ ์์ ๋น๊ฒฐ์ด์์. Composite ๋จ๊ณ๋ฅผ ์ฌ๋ํด์ฃผ์ธ์!"
Q2. CSS ์ ๋๋ฉ์ด์ ์ ํ ์ฌ์ดํด(0%~100%)์ ์ ์ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํค์๋๋ ๋ฌด์์ธ๊ฐ์?
@animation-steps@keyframes@timeline@motion-path
โ
์ ๋ต: 2. @keyframes
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ:
@keyframes๋ ์ ๋๋ฉ์ด์ ์ด ์งํ๋๋ ๋์ ๊ฐ ์ง์ (Keyframes)์์ ์์๊ฐ ์ด๋ค ์คํ์ผ์ ๊ฐ์ ธ์ผ ํ๋์ง๋ฅผ ์ ์ํ๋ ์ค๊ณ๋์ ๋๋ค. - ์ค๋ต ํผ๋๋ฐฑ: "์์ฒ ๋, ์๋๋ฆฌ์ค ์๊ฐ๊ฐ ์ฅ๋ฉด์ ๋๋๋ฏ
@keyframes๋ก ์ ๋๋ฉ์ด์ ์ ์คํ ๋ฆฌ๋ฅผ ์ง๋ณด์ธ์."
Q3. [์์ฒ ์ด์ ํ
์คํธ ํ์: ์ค๋ฌด ๋๋ ๋ง]
์์ฒ ์ด๊ฐ ์ฌ์ด๋๋ฐ๋ฅผ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ์ฅ ๋ํ๋๊ฒ ํ๋ ค๊ณ ํฉ๋๋ค. ์ฒ์์๋ left: -300px์์ left: 0์ผ๋ก ์ฎ๊ฒผ๋๋ฐ ์ํธ ๋์ด "์ด๊ฑด ์ฑ๋ฅ ์ฐ๋ ๊ธฐ์ผ!"๋ผ๊ณ ํธํต์ ์น์
จ์ต๋๋ค. ์์ฒ ์ด๊ฐ ์ํธ ๋๊ป ์นญ์ฐฌ๋ฐ์ ์ ์๋ ๊ฐ์ฅ ์ฑ๋ฅ ์ข์ ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฌด์์ผ๊น์?
โ
์ ๋ต: transform: translateX(-100%)์์ transform: translateX(0)์ผ๋ก ๋ถ๋๋ฝ๊ฒ ์ด๋์ํจ๋ค.
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช
:
left๊ฐ์ ๋ฐ๊พธ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ๋ ์ด์์(Reflow) ๋จ๊ณ๋ฅผ ๋งค๋ฒ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. ํ์ง๋งtransform์ ์ด๋ฏธ ๊ทธ๋ ค์ง ๋ ์ด์ด๋ฅผ GPU๊ฐ ์์น๋ง ์ฎ๊ฒจ์ฃผ๋ ๊ฒ์ด๋ผ ํจ์ฌ ๋น ๋ฅด๊ณ ๋ถ๋๋ฝ์ต๋๋ค. - ์ค๋ต ํผ๋๋ฐฑ: "์์ฒ ๋, ํฝ์ ๋จ์๋ก ๋ช ๋ นํ์ง ๋ง๊ณ '๊ธฐํํ์ ๋ณํ'์ ์ํค์ธ์. ๊ทธ๊ฒ GPU๋ฅผ ๋ถ๋ ค๋จน๋ ๋ฐฉ๋ฒ์ ๋๋ค."
- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "์์น ์ด๋์ left๊ฐ ์๋๋ผ translate!"
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
์ค๋ ๋๋์ด CSS ๊ฐ์ด๋์ ์ค๋ฐ๋ถ์ธ 10์ฅ์ ๋ง์ณค๋ค.
์ ๋๋ฉ์ด์
์ด ๋จ์ํ ํ๋ คํ ๊ฒ ์๋๋ผ, ์ผ๋ง๋ ์ฒ ์ ํ๊ฒ ๋ธ๋ผ์ฐ์ ์ ์ฑ๋ฅ์ ๊ณ ๋ คํด์ผ ํ๋์ง ๊นจ๋ฌ์ ๊ฒ ๊ฐ์ฅ ํฐ ์๋์ด๋ค.
์ ์ ๊ฐ "์ด? ๋ถ๋๋ฝ๋ค"๋ผ๊ณ ๋๋ผ๋ 0.1์ด ๋ค์ ์ด๋ฐ ๋ณต์กํ ๋ ๋๋ง ํ์ดํ๋ผ์ธ์ด ์จ์ด ์์๋ค๋!
๐ก "์ข์ ์ ๋๋ฉ์ด์ ์ ๋์ ์ฆ๊ฒ๊ฒ ํ๊ณ , ์๋ํ ์ ๋๋ฉ์ด์ ์ CPU๋ฅผ ์ฌ๊ฒ ํ๋ค."
์ํธ ๋์ด "Reflow๋ ์ฃ์
์ด๋ค"๋ผ๊ณ ํ์
จ๋ ๋๋ด ๋ฐ ์ง๋ด ๋ฐ์ ๋ง์์ ๊ฐ์ด ๊น์ด ์๊ฒจ์ผ๊ฒ ๋ค.
๋ด์ผ๋ถํด ๋๋์ด 5๋
์ฐจ์ ์ ์์ธ '์ํคํ
์ฒ์ ์ฑ๋ฅ ์ต์ ํ' ์ฌํ ๊ณผ์ ์ผ๋ก ๋ค์ด๊ฐ๋ค.
์ด์ ์ฃผ๋์ด ์์ฒ ์ด๋ฅผ ๋์ด ์๋์ด ์ํธ ๋์ ์์ผ์ ํ ๊ฑธ์ ๋ ๋ค๊ฐ์ ๊ธฐ๋ถ์ด๋ค.
ํด๊ทผ๊ธธ ๋ฐค๋ฐ๋์ด ์ค๋๋ฐ๋ผ ease-out์ฒ๋ผ ๋ถ๋๋ฝ๊ฒ ๋๊ปด์ง๋ค. ๐ฌ