CSS์์ `grid-template-areas`๋ฅผ ์ ๋๋ฉ์ด์ ์ผ๋ก ๋ง๋๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์์๋ณด์ธ์. ์ด ์ข ํฉ ๊ฐ์ด๋๋ ์ค์ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ํตํด ๋ถ๋๋ฝ๊ณ ๋ฐ์ํ์ด๋ฉฐ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ๋ ์ด์์ ์ ํ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
CSS ๊ทธ๋ฆฌ๋ ์ด๋ฆ ์ง์ ์์ญ ์ ๋๋ฉ์ด์ : ๋ถ๋๋ฌ์ด ๋ ์ด์์ ์ ํ์ ์ํ ๊ฐ์ด๋
์๋ ๊ฐ ์น ๊ฐ๋ฐ์๋ค์ ๋ ์ด์์ ์ ๋๋ฉ์ด์ ์ ์ฑ๋ฐฐ, ์ฆ ์ ์ฒด ํ์ด์ง ๊ตฌ์กฐ๋ฅผ ํ ์ํ์์ ๋ค๋ฅธ ์ํ๋ก ๋ถ๋๋ฝ๊ฒ ์ ํํ๋ ๊ฐ๋จํ๊ณ ์ฑ๋ฅ์ด ์ข์ผ๋ฉฐ CSS ๋ค์ดํฐ๋ธ ๋ฐฉ์์ ์ฐพ์์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์์น ์ง์ ์ ์ด์ฉํ ๊ธฐ๋ฐํ ํต(hack), Flexbox๋ฅผ ์ฌ์ฉํ ๋ณต์กํ ๊ณ์ฐ, ๊ฐ๋ ฅํ์ง๋ง ๋ฌด๊ฑฐ์ด ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์์ต๋๋ค. ์ด๋ฌํ ๋ฐฉ๋ฒ๋ค์ด ํจ๊ณผ๋ ์์ง๋ง, ์ข ์ข ๋ณต์ก์ฑ, ์ ์ง๋ณด์์ฑ ๋๋ ์ฑ๋ฅ ๋ฉด์์ ๋๊ฐ๋ฅผ ์น๋ฌ์ผ ํ์ต๋๋ค.
CSS ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ ํ๋์ ์ธ ์ด๋ฅ๋ ฅ์ ์๊ฐํฉ๋๋ค: ๋ฐ๋ก grid-template-areas ์์ฑ์ ์ ๋๋ฉ์ด์ ํํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ์ด ์ ์ธ์ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ด๋ฆ์ด ์ง์ ๋ ์์ญ์ผ๋ก ์ ์ฒด ๋ ์ด์์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ ๋ค์ ๋จ ํ ์ค์ CSS๋ก ๊ทธ ์ฌ์ด๋ฅผ ์ ํํ ์ ์์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ ๋๋๋๋ก ๋ถ๋๋ฝ๊ณ ํ๋์จ์ด ๊ฐ์์ด ์ ์ฉ๋ ์ ๋๋ฉ์ด์ ์ผ๋ก, ์์ฑํ๊ธฐ ์ฝ๊ณ ์ ์ง๋ณด์๋ ๋งค์ฐ ๊ฐํธํฉ๋๋ค.
์ด ์ข ํฉ ๊ฐ์ด๋๋ CSS ๊ทธ๋ฆฌ๋ ์ด๋ฆ ์ง์ ์์ญ์ ๊ธฐ์ด๋ถํฐ ์ ๊ตํ๊ณ ์ํธ์์ฉ์ ์ด๋ฉฐ ์ ๊ทผ์ฑ ๋์ ๋ ์ด์์ ์ ํ์ ๋ง๋๋ ๊ณ ๊ธ ๊ธฐ์ ๊น์ง ์๋ดํ ๊ฒ์ ๋๋ค. ๋์ ์ธ ๋์๋ณด๋, ์ธํฐ๋ํฐ๋ธํ ๊ธฐ์ฌ, ๋๋ ๋ฐ์ํ ์ ์์๊ฑฐ๋ ์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ๋ , ์ด ๊ธฐ์ ์ ๋น์ ์ ํ๋ก ํธ์๋ ํดํท์์ ๊ท์คํ ๋๊ตฌ๊ฐ ๋ ๊ฒ์ ๋๋ค.
๊ฐ๋จํ ๋ณต์ต: CSS ๊ทธ๋ฆฌ๋์ ์ด๋ฆ ์ง์ ์์ญ
์ ๋๋ฉ์ด์ ์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ํํํ ๊ธฐ์ด๋ฅผ ๋ค์ ธ๋ด ์๋ค. ์ด๋ฏธ CSS ๊ทธ๋ฆฌ๋์ `grid-template-areas`์ ์ ๋ฌธ๊ฐ๋ผ๋ฉด ๋ค์ ์น์ ์ผ๋ก ๊ฑด๋๋ฐ์ด๋ ์ข์ต๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด, ์ด ๊ฐ๋จํ ๋ณต์ต์ ํตํด ๋น ๋ฅด๊ฒ ๊ฐ๋ ์ ์ตํ ์ ์์ต๋๋ค.
CSS ๊ทธ๋ฆฌ๋๋ ๋ฌด์์ธ๊ฐ?
CSS ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ ์น์ ์ํ 2์ฐจ์ ๋ ์ด์์ ์์คํ ์ ๋๋ค. ์ด๋ฅผ ํตํด ํ๊ณผ ์ด ๋ชจ๋์์ ํ์ด์ง ์์์ ํฌ๊ธฐ, ์์น, ๋ ์ด์ด๋ฅผ ๋์์ ์ ์ดํ ์ ์์ต๋๋ค. ์ฃผ๋ก 1์ฐจ์ ์์คํ (ํ ๋๋ ์ด)์ธ Flexbox์ ๋ฌ๋ฆฌ, ๊ทธ๋ฆฌ๋๋ ์ ์ฒด ํ์ด์ง๋ ์ปดํฌ๋ํธ ๊ตฌ์กฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋ฐ์ด๋ฉ๋๋ค.
`grid-template-areas`์ ํ
CSS ๊ทธ๋ฆฌ๋์ ๊ฐ์ฅ ์ง๊ด์ ์ธ ๊ธฐ๋ฅ ์ค ํ๋๋ `grid-template-areas` ์์ฑ์ ๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฆ์ด ์ง์ ๋ ๋ฌธ์์ด์ ์ฌ์ฉํ์ฌ CSS์์ ์ง์ ๋ ์ด์์์ ์๊ฐ์ ํํ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ๋ ์ด์์ ์ฝ๋๋ฅผ ๋งค์ฐ ์ฝ๊ธฐ ์ฝ๊ณ ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
์๋ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๊ทธ๋ฆฌ๋ ์ปจํ ์ด๋ ์ ์: ๋ถ๋ชจ ์์์ `display: grid;`๋ฅผ ์ ์ฉํฉ๋๋ค.
- ์์ ์์์ ์ด๋ฆ ์ง์ : `grid-area` ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฐ ์์ ์์์ ์ด๋ฆ์ ํ ๋นํฉ๋๋ค(์: `grid-area: header;`).
- ๋ ์ด์์ ๊ทธ๋ฆฌ๊ธฐ: ๊ทธ๋ฆฌ๋ ์ปจํ ์ด๋์์ `grid-template-areas` ์์ฑ์ ์ฌ์ฉํ์ฌ ์ด๋ฆ์ด ์ง์ ๋ ์์ญ์ ๋ฐฐ์ดํฉ๋๋ค. ๊ฐ ๋ฌธ์์ด์ ํ์ ๋ํ๋ด๊ณ , ๋ฌธ์์ด ๋ด์ ์ด๋ฆ์ ์ด์ ์ ์ํฉ๋๋ค. ๋ง์นจํ(`.`)๋ ๋น ๊ทธ๋ฆฌ๋ ์ ์ ์๋ฏธํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ณ ์ ์ ์ธ ์นํ์ด์ง ๋ ์ด์์์ ๊ฐ๋จํ ์ ์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
HTML ๊ตฌ์กฐ:
<div class="app-layout">
<header class="app-header">Header</header>
<nav class="app-sidebar">Sidebar</nav>
<main class="app-main">Main Content</main>
<footer class="app-footer">Footer</footer>
</div>
CSS ๊ตฌํ:
/* 1. ๊ทธ๋ฆฌ๋ ์์ดํ
์ ์ด๋ฆ ํ ๋น */
.app-header { grid-area: header; }
.app-sidebar { grid-area: sidebar; }
.app-main { grid-area: main; }
.app-footer { grid-area: footer; }
/* 2. ๊ทธ๋ฆฌ๋ ์ปจํ
์ด๋ ์ ์ ๋ฐ ๋ ์ด์์ ๊ทธ๋ฆฌ๊ธฐ */
.app-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
height: 100vh;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
์ด ์์ ์์ `grid-template-areas` ์์ฑ์ ์ฐ๋ฆฌ ๋ ์ด์์์ ์ฆ๊ฐ์ ์ด๊ณ ์๊ฐ์ ์ธ ์ง๋๋ฅผ ์ ๊ณตํฉ๋๋ค. ํค๋์ ํธํฐ๋ ๋ ์ด์ ๊ฑธ์ณ ์๊ณ , ์ฌ์ด๋๋ฐ์ ๋ฉ์ธ ์ฝํ ์ธ ๋ ์ค๊ฐ ํ์ ๊ณต์ ํฉ๋๋ค. ์ด๋ ๊น๋ํ๊ณ ์ ์ธ์ ์ด๋ฉฐ, ๋ณต์กํ float์ด๋ flexbox ๊ตฌ์ฑ๋ณด๋ค ํจ์ฌ ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค.
ํต์ฌ ๊ฐ๋ : `grid-template-areas` ์ ๋๋ฉ์ด์ ํ๊ธฐ
์ด์ ํฅ๋ฏธ๋ก์ด ๋ถ๋ถ์ ๋๋ค. ์ค๋ซ๋์ `grid-template-areas`์ ๊ฐ์ ๋ถ์ฐ์์ ์ธ ์์ฑ์ ์ ๋๋ฉ์ด์ ํํ ์ ์์์ต๋๋ค. ๋ ์ด์์์ ๋ณ๊ฒฝํ ์๋ ์์์ง๋ง, ํ ์ํ์์ ๋ค์ ์ํ๋ก ์ฆ์ ๋ฐ๋์์ต๋๋ค. ํ์ง๋ง ๋ชจ๋ ์ต์ ๋ธ๋ผ์ฐ์ ์์ ์ด๊ฒ์ด ๋ฐ๋๋ฉด์ ์๋ก์ด ๊ฐ๋ฅ์ฑ์ ์ธ๊ณ๊ฐ ์ด๋ ธ์ต๋๋ค.
`grid-template-areas`๋ ์ ๋ง ์ ๋๋ฉ์ด์ ์ด ๊ฐ๋ฅํ๊ฐ?
๋ค! Chrome, Firefox, Safari, Edge์ ๊ตฌํ์ ๊ธฐ์ค์ผ๋ก `grid-template-areas`๋ (`grid-template-columns` ๋ฐ `grid-template-rows`์ ํจ๊ป) ์ ๋๋ฉ์ด์ ์ด ๊ฐ๋ฅํ ์์ฑ์ ๋๋ค. ์ด์ ๋ธ๋ผ์ฐ์ ๋ ๋ ๊ฐ์ ๋ค๋ฅธ ๊ทธ๋ฆฌ๋ ๊ตฌ์กฐ ์ฌ์ด๋ฅผ ๋ณด๊ฐํ์ฌ ์ง์ ๋ ์๊ฐ ๋์ ๊ทธ๋ฆฌ๋ ์์ญ์ ๋ถ๋๋ฝ๊ฒ ์ด๋ํ๊ณ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค.
๊ธฐ์ตํด์ผ ํ ์ค์ํ ๊ท์น์ด ํ๋ ์์ต๋๋ค: ์ด๋ฆ์ด ์ง์ ๋ ์์ญ์ ์งํฉ์ ์์ ์ํ์ ๋ ์ํ ๊ฐ์ ๋์ผํด์ผ ํฉ๋๋ค. ์ ํ ์ค์ ์ด๋ฆ์ด ์ง์ ๋ ์์ญ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์์ญ `A`, `B`, `C`๊ฐ ์๋ ๋ ์ด์์์์ `A`์ `B`๋ง ์๋ ๋ ์ด์์์ผ๋ก ์ ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ `A`, `B`, `C`๋ฅผ ์ํ๋ ๋๋ก ์ฌ๋ฐฐ์ดํ๊ณ , ๋ค๋ฅธ ์์ ํ๊ณผ ์ด์ ๊ฑธ์น๊ฒ ํ ์๋ ์์ต๋๋ค.
ํธ๋์ง์ ์ค์ ํ๊ธฐ
๋ง๋ฒ์ ํ์ค CSS `transition` ์์ฑ์์ ์ผ์ด๋ฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์๊ฒ `grid-template-areas`์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์ํ๊ณ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ผ ํด๋น ๋ณ๊ฒฝ ์ฌํญ์ ์ ๋๋ฉ์ด์ ์ผ๋ก ๋ง๋ค๋ผ๊ณ ๊ฐ๋จํ ์ง์ํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๋ ์ปจํ ์ด๋์ ๋ค์์ ์ถ๊ฐํฉ๋๋ค:
CSS:
.grid-container {
/* ... ๋ค๋ฅธ ๊ทธ๋ฆฌ๋ ์์ฑ๋ค ... */
transition: grid-template-areas 0.5s ease-in-out;
}
์ด๊ฒ์ ๋ถ์ํด ๋ณด๊ฒ ์ต๋๋ค:
- `grid-template-areas`: ์ ๋๋ฉ์ด์ ์ ์ ์ฉํ๋ ค๋ ํน์ ์์ฑ์ ๋๋ค.
- `0.5s`: ์ ๋๋ฉ์ด์ ์ ์ง์ ์๊ฐ(0.5์ด)์ ๋๋ค.
- `ease-in-out`: ์ ๋๋ฉ์ด์ ์ ๊ฐ์ ๋ฐ ๊ฐ์์ ์ ์ดํ์ฌ ๋ ์์ฐ์ค๋ฝ๊ฒ ๋๊ปด์ง๊ฒ ํ๋ ํ์ด๋ฐ ํจ์์ ๋๋ค.
์ด ํ ์ค์ ์ฝ๋๋ก, ์ด ์์์ `grid-template-areas` ์์ฑ์ ๋ํ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ(์: ํด๋์ค ์ถ๊ฐ ๋๋ `:hover` ์ํ๋ฅผ ํตํด)์ ์ด์ ๋ถ๋๋ฌ์ด ์ ๋๋ฉ์ด์ ์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์ : ๋ ์ด์์์ ์๋ช ๋ถ์ด๋ฃ๊ธฐ
์ด๋ก ๋ ์ข์ง๋ง, ์ด ๊ธฐ์ ์ด ์ค์ ๋ก ์ด๋ป๊ฒ ์๋ํ๋์ง ๋ด ์๋ค. ๋ค์์ ์ด๋ฆ ์ง์ ๊ทธ๋ฆฌ๋ ์์ญ ์ ๋๋ฉ์ด์ ์ ํ๊ณผ ๋ค์ฌ๋ค๋ฅํจ์ ๋ณด์ฌ์ฃผ๋ ๋ช ๊ฐ์ง ์ค์ฉ์ ์ธ ์์ ์ ๋๋ค.
์์ 1: "ํฌ์ปค์ค ๋ชจ๋" ๋์๋ณด๋
์ฌ๋ฌ ํจ๋์ด ์๋ ๋์๋ณด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํด ๋ณด์ธ์. ๋ฉ์ธ ์ฝํ ์ธ ์์ญ์ด ํ๋ฉด ๋๋ถ๋ถ์ ์ฐจ์งํ๋๋ก ํ์ฅ๋๊ณ , ์ฌ์ด๋๋ฐ์ ์ถ๊ฐ ํจ๋์ ์ถ์๋๊ฑฐ๋ ์์ผ๋ก ์ด๋ํ๋ "ํฌ์ปค์ค ๋ชจ๋"๋ฅผ ๊ตฌํํ๊ณ ์ถ์ต๋๋ค.
HTML ๊ตฌ์กฐ:
<div class="dashboard">
<div class="panel-header">Header</div>
<div class="panel-nav">Nav</div>
<div class="panel-main">
Main Content
<button id="toggle-focus">Toggle Focus Mode</button>
</div>
<div class="panel-extra">Extra Info</div>
</div>
CSS ๊ตฌํ:
/* ๊ทธ๋ฆฌ๋ ์์ดํ
์ ์ด๋ฆ ์ง์ */
.panel-header { grid-area: header; }
.panel-nav { grid-area: nav; }
.panel-main { grid-area: main; }
.panel-extra { grid-area: extra; }
/* ์ปจํ
์ด๋์ ํธ๋์ง์
์ ์ */
.dashboard {
display: grid;
height: 100vh;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr;
transition: grid-template-areas 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55),
grid-template-columns 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55);
/* ๊ธฐ๋ณธ ๋ ์ด์์ ์ํ */
grid-template-areas:
"header header header"
"nav main extra";
}
/* ํฌ์ปค์ค ๋ชจ๋ ๋ ์ด์์ ์ํ (ํด๋์ค๋ก ํธ๋ฆฌ๊ฑฐ) */
.dashboard.focus-mode {
grid-template-columns: 60px 1fr 60px; /* ์ด ํฌ๊ธฐ๋ ์ ๋๋ฉ์ด์
ํ! */
grid-template-areas:
"header header header"
"nav main main"; /* ์ด์ ๋ฉ์ธ ์ฝํ
์ธ ๊ฐ extra ์ด์ ๊ณต๊ฐ๊น์ง ์ฐจ์ง */
}
์ด ์์ ์์, `.dashboard` ์ปจํ ์ด๋์ `.focus-mode` ํด๋์ค๊ฐ ์ถ๊ฐ๋๋ฉด(๋ฒํผ ํด๋ฆญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฝ๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฌ์ฉ), ๋ ๊ฐ์ง ์ผ์ด ๋์์ ๋ฐ์ํฉ๋๋ค: `grid-template-columns`๊ฐ ๋ณ๊ฒฝ๋์ด ์ฌ์ด๋ ํจ๋์ด ์ถ์๋๊ณ , `grid-template-areas`๊ฐ ๋ณ๊ฒฝ๋์ด `main` ์์ญ์ด ์ด์ ์ `extra` ํจ๋์ด ์ฐจ์งํ๋ ๊ณต๊ฐ์ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค. ๋ ์์ฑ ๋ชจ๋ `transition` ์ ์ธ์ ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ์, ์ ์ฒด ๋ ์ด์์์ด ์ ๋์ ์ผ๋ก ์๋ก์ด ์ํ๋ก ๋ณํ๋ฉ๋๋ค.
์์ 2: ๋ฐ์ํ ์คํ ๋ฆฌํ ๋ง ๋ ์ด์์
์ด ๊ธฐ์ ์ ๊ธฐ์ฌ๋ฅผ ์ํ ๋์ ์ธ ์ก์ง ์คํ์ผ์ ๋ ์ด์์์ ๋ง๋๋ ๋ฐ ์๋ฒฝํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์ํธ์์ฉํ๊ฑฐ๋ ๋ทฐํฌํธ๊ฐ ๋ณ๊ฒฝ๋ ๋ ํ ์คํธ์ ์ด๋ฏธ์ง ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
๋๋ํ ๋ณด๋ ๋ทฐ์ ์ ์ฒด ์ด๋ฏธ์ง ๋ทฐ ์ฌ์ด๋ฅผ ์ ํํ ์ ์๋ ๋ ์ด์์์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
HTML ๊ตฌ์กฐ:
<article class="story-layout">
<div class="story-text">...๊ธด ํ์์ ํ
์คํธ...</div>
<figure class="story-image">...์ด๋ฏธ์ง...</figure>
</article>
CSS ๊ตฌํ:
.story-text { grid-area: text; }
.story-image { grid-area: image; }
.story-layout {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
gap: 2rem;
transition: grid-template-areas 0.7s ease-out;
/* ๊ธฐ๋ณธ ์ํ: ๋๋ํ ๋ณด๊ธฐ */
grid-template-areas: "text image";
}
/* ์ ์ฒด ์ด๋ฏธ์ง ์ํ */
.story-layout.full-bleed {
grid-template-areas: "image image" "text text"; /* ์ด๋ฏธ์ง๊ฐ ์๋ก ์ด๋ํ์ฌ ์ ์ฒด ๋๋น๋ฅผ ์ฐจ์ง */
}
`.full-bleed` ํด๋์ค๋ฅผ ํ ๊ธํจ์ผ๋ก์จ, ์ด๋ฏธ์ง๋ ์์์ ์๋ก ์ฐ์ํ๊ฒ ์ด๋ํ์ฌ ์ ์ฒด ๋๋น๋ฅผ ์ฑ์ฐ๋๋ก ํ์ฅ๋๊ณ , ํ ์คํธ๋ ๊ทธ ์๋๋ก ๋ถ๋๋ฝ๊ฒ ์ฌ๋ฐฐ์น๋ฉ๋๋ค. ์ด๋ ๊ฐ๋ ฅํ ์์ฌ์ ํจ๊ณผ๋ฅผ ๋ง๋ค์ด๋ด์ด ๋์์ธ์ด ๋ค๋ฅธ ์์ ์ ๋ค๋ฅธ ์ฝํ ์ธ ๋ฅผ ๊ฐ์กฐํ ์ ์๋๋ก ํฉ๋๋ค.
์์ 3: ๋์ ์ ์์๊ฑฐ๋ ์ ํ ํ์ด์ง
์ ํ ํ์ด์ง์๋ ์ข ์ข ๋ฉ์ธ ์ด๋ฏธ์ง์ ์ธ๋ค์ผ ๊ฐค๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฆฌ๋ ์์ญ ์ ๋๋ฉ์ด์ ์ ์ฌ์ฉํ์ฌ ์ธ๋ค์ผ์ ํด๋ฆญํ๋ฉด ํด๋น ์ด๋ฏธ์ง๋ ๊ด๋ จ ์ฝํ ์ธ ๋ฅผ ํน์ง์ผ๋ก ํ๋๋ก ํ์ด์ง๋ฅผ ์ฌ๋ฐฐ์ดํ๋ ์ธ๋ จ๋ ์ํธ์์ฉ์ ๋ง๋ค ์ ์์ต๋๋ค.
์ ํ ์ด๋ฏธ์ง, ์ค๋ช , ๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ "ํน์ง" ์ฝ์์์ด ์๋ ๋ ์ด์์์ ์์ํด ๋ณด์ธ์. ๊ฐ ํน์ง์ ๊ฐ์กฐํ๊ธฐ ์ํด ๋ค๋ฅธ ๋ ์ด์์ ์ํ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
HTML ๊ตฌ์กฐ:
<div class="product-page default-view">
<div class="product-image">Image</div>
<div class="product-desc">Description</div>
<div class="product-feature1">Feature 1</div>
<div class="product-feature2">Feature 2</div>
</div>
CSS ๊ตฌํ:
.product-image { grid-area: image; }
.product-desc { grid-area: desc; }
.product-feature1 { grid-area: f1; }
.product-feature2 { grid-area: f2; }
.product-page {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto;
transition: grid-template-areas 0.4s ease;
}
/* ๊ธฐ๋ณธ ๋ทฐ */
.product-page.default-view {
grid-template-areas:
"image desc"
"f1 f2";
}
/* ํน์ง 1์ ์ด์ */
.product-page.feature1-view {
grid-template-areas:
"f1 f1"
"image desc";
}
/* ํน์ง 2์ ์ด์ */
.product-page.feature2-view {
grid-template-areas:
"f2 image"
"f2 desc";
}
์ปจํ ์ด๋์ ํด๋์ค(`default-view`, `feature1-view` ๋ฑ)๋ฅผ ์ ํํ๋ ๊ฐ๋จํ ์๋ฐ์คํฌ๋ฆฝํธ๋ก, ๋ ์ด์์ ์์ฒด๊ฐ ์ฌ์ฉ์์ ์ฃผ์๋ฅผ ์ ๋ํ๋๋ก ์ ์ํ๋ ์ ํ ํน์ง์ ๋ํ ์ธํฐ๋ํฐ๋ธ ํฌ์ด๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ์ ์ ์ธ ์บ๋ฌ์ ์ด๋ ๋จ์ํ ์ฝํ ์ธ ๊ต์ฒด๋ณด๋ค ํจ์ฌ ๋ ๋งค๋ ฅ์ ์ ๋๋ค.
๊ณ ๊ธ ๊ธฐ์ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
๊ธฐ๋ณธ์ ๋ง์คํฐํ๋ค๋ฉด, ์ด๋ฌํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ํตํฉํ์ฌ ๋ ์ด์์ ์ ๋๋ฉ์ด์ ์ ์์ค์ ๋์ผ ์ ์์ต๋๋ค.
๋ค๋ฅธ ํธ๋์ง์ ๊ณผ ๊ฒฐํฉํ๊ธฐ
๋ ์ด์์ ์ ํ์ ๋ค๋ฅธ ์ ๋๋ฉ์ด์ ๊ณผ ๊ฒฐํฉ๋ ๋ ๋์ฑ ํจ๊ณผ์ ์ ๋๋ค. ๋ถ๋ชจ ๊ทธ๋ฆฌ๋๊ฐ ๋ณ๊ฒฝ๋๋ ๋์์ ์์ ์์์ `background-color`, `opacity`, `transform`๊ณผ ๊ฐ์ ์์ฑ์ ์ ํํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋ ์ด์์์ด "ํฌ์ปค์ค ๋ชจ๋"๋ก ์ ํ๋๋ ๋์, ๋ ์ค์ํ ์์์ ํฌ๋ช ๋๋ฅผ ์ค์ฌ ํ์ด๋ ์์ ์ํฌ ์ ์์ต๋๋ค:
CSS:
.dashboard.focus-mode .panel-nav,
.dashboard.focus-mode .panel-extra {
opacity: 0.5;
}
.panel-nav, .panel-extra {
transition: opacity 0.6s ease;
}
์ด๊ฒ์ ์ฌ๋ฌ ์๊ฐ์ ๋จ์๊ฐ ํจ๊ป ์๋ํ์ฌ ๋ ํ๋ถํ๊ณ ๋ค์ธต์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋ญ๋๋ค.
์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
`grid-template-areas`์ ๊ฐ์ ๋ ์ด์์ ์์ฑ์ ์ ๋๋ฉ์ด์ ํํ๋ ๊ฒ์ ์ข ์ข GPU๋ก ์คํ๋ก๋๋ ์ ์๋ `transform`์ด๋ `opacity`๋ฅผ ์ ๋๋ฉ์ด์ ํํ๋ ๊ฒ๋ณด๋ค ๋ธ๋ผ์ฐ์ ์๊ฒ ๊ณ์ฐ ๋น์ฉ์ด ๋ ๋ง์ด ๋ญ๋๋ค. ์ต์ ๋ธ๋ผ์ฐ์ ๋ ๊ณ ๋๋ก ์ต์ ํ๋์ด ์์ง๋ง, ์ฑ๋ฅ์ ์ ์ํ๋ ๊ฒ์ด ํ๋ช ํฉ๋๋ค:
- ๋น ๋ฅด๊ฒ ์ ์งํ๊ธฐ: ์งง์ ์ ๋๋ฉ์ด์ ์ง์ ์๊ฐ(์ผ๋ฐ์ ์ผ๋ก 300ms์์ 700ms ์ฌ์ด)์ ๊ณ ์ํ์ธ์. ๊ธด ๋ ์ด์์ ์ ๋๋ฉ์ด์ ์ ๋๋ฆฌ๊ฒ ๋๊ปด์ง ์ ์์ต๋๋ค.
- ๋จ์ํ ์ด์ง(easing): ๋ณต์กํ `cubic-bezier` ํจ์๋ ์๋ฆ๋ค์ธ ์ ์์ง๋ง ๋ ๋ง์ ์ฒ๋ฆฌ๋ฅผ ์๊ตฌํ ์ ์์ต๋๋ค. `ease-out`๊ณผ ๊ฐ์ ํ์ค ์ด์ง ํจ์๋ ์ข ์ข ์ถฉ๋ถํ๋ฉฐ ์ฑ๋ฅ์ด ์ข์ต๋๋ค.
- ์ค์ ๊ธฐ๊ธฐ์์ ํ ์คํธํ๊ธฐ: ํญ์ ๋ค์ํ ๊ธฐ๊ธฐ, ํนํ ์ ์ฌ์ ๋ชจ๋ฐ์ผ ํฐ์์ ์ ๋๋ฉ์ด์ ์ ํ ์คํธํ์ฌ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๊ฒฝํ์ด ๋ถ๋๋ฝ๊ฒ ์ ์ง๋๋์ง ํ์ธํ์ธ์.
์ ๊ทผ์ฑ์ ํํ ๋ถ๊ฐ
์์ง์์ ์ ์ ์ฅ์ , ๋ฉ๋ฏธ ๋๋ ๊ธฐํ ์ธ์ง ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์์๊ฒ ์๋นํ ์ ๊ทผ์ฑ ์ฅ๋ฒฝ์ด ๋ ์ ์์ต๋๋ค. ์ฌ์ฉ์์ ๋์ ์ค์ด๊ธฐ ์ ํธ๋๋ฅผ ์กด์คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
`prefers-reduced-motion` ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด์ ์ฒด์ ์์ ์ด ์ค์ ์ ํ์ฑํํ ์ฌ์ฉ์๋ฅผ ์ํด ์ ๋๋ฉ์ด์ ์ ๋นํ์ฑํํ๊ฑฐ๋ ์ฝํ์ํฌ ์ ์์ต๋๋ค.
CSS:
@media (prefers-reduced-motion: reduce) {
.grid-container, .grid-container * {
transition: none !important;
animation: none !important;
}
}
์ด ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ก ํธ๋์ง์ ์ ์ธ์ ๊ฐ์ธ๊ฑฐ๋ ๋ฎ์ด์์ผ๋ก์จ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋ ์์ ํ๊ณ ํธ์ํ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๊ธฐ์ตํ์ธ์, ์ ๋๋ฉ์ด์ ์ ํ์ ์ฌํญ์ด ์๋ ํฅ์ ๊ธฐ๋ฅ์ด์ด์ผ ํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ์ง์ ๋ฐ ํด๋ฐฑ(Fallbacks)
`grid-template-areas` ์ ๋๋ฉ์ด์ ์ง์์ ๋ชจ๋ ์ต์ , ์๋ฒ๊ทธ๋ฆฐ ๋ธ๋ผ์ฐ์ ์์ ๊ฐ๋ ฅํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ต์ ํธํ์ฑ ์ ๋ณด๋ ํญ์ "Can I Use..."์ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ข์ ์์์ ํด๋ฐฑ ๋์์ด ํ๋ฅญํ๋ค๋ ๊ฒ์ ๋๋ค. ์ ๋๋ฉ์ด์ ์ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ์์๋ ๋ ์ด์์์ด ์์ ์ํ์์ ๋ ์ํ๋ก ์ฆ์ ๋ฐ๋๋๋ค. ๊ธฐ๋ฅ์ ์๋ฒฝํ๊ฒ ๋ณด์กด๋๋ฉฐ, ๋ฏธ์ ์ธ ์ฅ์๋ง ๋น ์ง๋๋ค. ์ด๊ฒ์ ์ ์ง์ ์ฑ๋ฅ ์ ํ(graceful degradation)์ ์๋ฒฝํ ์์ ๋๋ค.
์ ํ ์ฌํญ ๋ฐ ๋ค๋ฅธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํด์ผ ํ ๋
`grid-template-areas` ์ ๋๋ฉ์ด์ ์ ๊ฐ๋ ฅํ์ง๋ง ๋ง๋ณํต์น์ฝ์ ์๋๋๋ค. ๊ทธ ํ๊ณ๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ์ผ๊ด๋ ์ด๋ฆ ์ง์ ์์ญ: ์์ ์ธ๊ธํ๋ฏ์ด, ์ฃผ๋ ์ ํ์ `grid-area` ์ด๋ฆ ์งํฉ์ด ์์ ์ํ์ ๋ ์ํ ๋ชจ๋์์ ๋์ผํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๋ ์์ดํ ์ด ํ๋ฆ์ ์ถ๊ฐ๋๊ฑฐ๋ ์ ๊ฑฐ๋๋ ๊ฒ์ ์ ๋๋ฉ์ด์ ํํ ์ ์์ต๋๋ค.
- ๊ฐ๋ณ ์์ดํ ์ ์ด ๋ถ๊ฐ: ์ด ๊ธฐ์ ์ ์ ์ฒด ๊ทธ๋ฆฌ๋ ๊ตฌ์กฐ๋ฅผ ํ ๋ฒ์ ์ ๋๋ฉ์ด์ ํํฉ๋๋ค. ๊ฐ๋ณ ์์๋ฅผ ๋ณต์กํ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ๋๋ ์์ฐจ๋ฅผ ๋๊ณ ์ ๋๋ฉ์ด์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ, GreenSock Animation Platform (GSAP)์ด๋ Web Animations API์ ๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ ์๋ฃจ์ ์ด ๋ ์ธ๋ถํ๋ ์ ์ด๋ฅผ ์ ๊ณตํ ๊ฒ์ ๋๋ค.
- ์ฝํ ์ธ ๋ฆฌํ๋ก์ฐ(Reflow): ๋ ์ด์์ ์ ๋๋ฉ์ด์ ์ ์ฝํ ์ธ ๋ฆฌํ๋ก์ฐ๋ฅผ ์ ๋ฐํ๋ฉฐ, ์ ์คํ๊ฒ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ๊ฑฐ์ฌ๋ฆด ์ ์์ต๋๋ค. ์ฝํ ์ธ ๊ฐ ์์ ๋ฐ ๋ ์ํ๋ฟ๋ง ์๋๋ผ ์ ํ ์ค์๋ ๋ณด๊ธฐ ์ข๊ฒ ์ ์ง๋๋๋ก ํ์ธ์.
๊ฒฐ๋ก : ์น ๋ ์ด์์์ ์๋ก์ด ์๋
`grid-template-areas`๋ฅผ ์ ๋๋ฉ์ด์ ํํ๋ ๊ธฐ๋ฅ์ ๋จ์ํ ์๋ก์ด CSS ๊ธฐ๋ฅ ์ด์์ ๋๋ค; ์ด๋ ์ฐ๋ฆฌ๊ฐ ์น์์ ์ธํฐ๋ํฐ๋ธ ๋์์ธ์ ์ ๊ทผํ๋ ๋ฐฉ์์ ๊ทผ๋ณธ์ ์ธ ๋ณํ๋ฅผ ๋ํ๋ ๋๋ค. ์ด๋ ์ฐ๋ฆฌ๊ฐ ๋ ์ด์์์ ์ ์ ์ธ ์ฒญ์ฌ์ง์ด ์๋๋ผ, ์ฌ์ฉ์ ์ํธ์์ฉ์ ์๋ฏธ ์๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ํ ์ ์๋ ์ญ๋์ ์ด๊ณ ์ ๋์ ์ธ ๋งค์ฒด๋ก ์๊ฐํ๋๋ก ํ์ ์ค์ด์ค๋๋ค.
์ด ์ ์ธ์ ์ด๊ณ , ์ ์ง๋ณด์ ๊ฐ๋ฅํ๋ฉฐ, CSS ๋ค์ดํฐ๋ธ ๊ธฐ์ ์ ํ์ฉํจ์ผ๋ก์จ, ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ์ฆ๊ฒ๊ณ ์ง๊ด์ ์ธ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ฃผ์๋ฅผ ์ ๋ํ๊ณ , ์์ฌ์ ํ๋ฆ์ ๋ง๋ค๋ฉฐ, ์ด์์๋ ๋ฏํ ๊ฒฝํ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ง๊ธ ๋ฐ๋ก ์คํ์ ์์ํ๊ณ , ์ด๋ค ๋๋๊ณ ๋ถ๋๋ฝ๊ฒ ์ ํ๋๋ ๋ ์ด์์์ ๋ง๋ค ์ ์๋์ง ํ์ธํด ๋ณด์ธ์.