CSS λ μ΄μμμ μ²μ λ°°μΈ λ κ°μ₯ λ§μ΄ λμ€λ μ§λ¬Έμ΄ μλ€.
"Flexboxλ Grid μ€μ λ μ¨μΌ ν΄μ?"
μ λ΅μ "λ λ€ μμμΌ νλ€"λ€. λ κΈ°μ μ μλ‘ κ²½μνλ κ² μλλΌ λ€λ₯Έ λ¬Έμ λ₯Ό ν΄κ²°νλ€. μ΄ κΈμ μ½κ³ λλ©΄ μ΄λ€ μν©μμ μ΄λ€ κ±Έ μ¨μΌ νλμ§ λ°λ‘ νλ¨ν μ μμ κ±°λ€.
Flexbox vs Grid β ν΅μ¬ μ°¨μ΄
- Flexbox: ν λ°©ν₯(ν λλ μ΄)μΌλ‘ μμ΄ν μ λ°°μΉ β 1μ°¨μ λ μ΄μμ
- Grid: νκ³Ό μ΄μ λμμ μ μ΄ β 2μ°¨μ λ μ΄μμ
μ ν κΈ°μ€
| μν© | μΆμ² |
|---|---|
| κ°λ‘λ‘ λμ΄λ λ²νΌλ€, λ€λΉκ²μ΄μ λ©λ΄ | Flexbox |
| μΈλ‘λ‘ μμΈ λ¦¬μ€νΈ νλͺ©λ€ | Flexbox |
| μ»΄ν¬λνΈ λ΄λΆ μ λ ¬ (μμ΄μ½ + ν μ€νΈ) | Flexbox |
| μΉ΄λ 그리λ, μ΄λ―Έμ§ κ°€λ¬λ¦¬ | Grid |
| νμ΄μ§ μ 체 λ μ΄μμ (ν€λ, μ¬μ΄λλ°, λ©μΈ) | Grid |
| νκ³Ό μ΄μ μ λ ¬μ΄ λͺ¨λ μ€μν κ²½μ° | Grid |
| μ½ν μΈ μμ λ°λΌ ν¬κΈ°κ° λ¬λΌμ§λ κ²½μ° | Flexbox |
λ κ°μ§λ₯Ό ν¨κ» μ°λ κ²λ λ§€μ° μΌλ°μ μ΄λ€ β Gridλ‘ νμ΄μ§ λ μ΄μμμ μ‘κ³ , κ° μ λ΄λΆλ Flexboxλ‘ μ λ ¬νλ μμ΄λ€.
Flexbox μμ μ 볡
Flexboxλ λΆλͺ¨ μμμ display: flexλ₯Ό μ μΈνλ©΄ μμλλ€. μμ μμλ€μ΄ μλμΌλ‘ Flex μμ΄ν
μ΄ λλ€.
ν΅μ¬ κ°λ : μ£ΌμΆκ³Ό κ΅μ°¨μΆ
flex-direction: row (κΈ°λ³Έκ°)
βββββββββββββββββββββββββββββββββ μ£ΌμΆ (main axis)
β [μμ΄ν
1] [μμ΄ν
2] [μμ΄ν
3]
β
β κ΅μ°¨μΆ (cross axis)justify-contentλ μ£ΌμΆ μ λ ¬, align-itemsλ κ΅μ°¨μΆ μ λ ¬μ΄λ€.
Flex 컨ν μ΄λ μμ±
.container {
display: flex;
/* λ°©ν₯ */
flex-direction: row; /* κΈ°λ³Έκ°: κ°λ‘ */
flex-direction: column; /* μΈλ‘ (μ£ΌμΆμ΄ μμ§μΌλ‘ λ°λ) */
flex-direction: row-reverse; /* κ°λ‘ μμ */
flex-direction: column-reverse;
/* μ€λ°κΏ */
flex-wrap: nowrap; /* κΈ°λ³Έκ°: ν μ€μ λ€ μ±μ¬λ£μ */
flex-wrap: wrap; /* λμΉλ©΄ λ€μ μ€λ‘ */
flex-wrap: wrap-reverse;
/* μ£ΌμΆ μ λ ¬ (justify-content) */
justify-content: flex-start; /* κΈ°λ³Έκ°: μμμ */
justify-content: flex-end; /* λμ */
justify-content: center; /* κ°μ΄λ° */
justify-content: space-between; /* μ λ λΆμ΄κ³ μ¬μ΄ κ· λ± */
justify-content: space-around; /* μ λ ν¬ν¨ κ· λ± (μ λμ μ λ°) */
justify-content: space-evenly; /* λͺ¨λ κ· λ± */
/* κ΅μ°¨μΆ μ λ ¬ (align-items) */
align-items: stretch; /* κΈ°λ³Έκ°: 컨ν
μ΄λ λμ΄λ§νΌ λλ¦Ό */
align-items: flex-start; /* μμͺ½ μ λ ¬ */
align-items: flex-end; /* μλμͺ½ μ λ ¬ */
align-items: center; /* μμ§ κ°μ΄λ° */
align-items: baseline; /* ν
μ€νΈ κΈ°μ€μ λ§μΆ€ */
/* μ¬λ¬ μ€μΌ λ μ€ κ°κ²© */
align-content: flex-start;
align-content: space-between;
/* κ°κ²© */
gap: 16px; /* ν μ΄ λͺ¨λ κ°μ κ°κ²© */
gap: 16px 24px; /* ν κ°κ²©, μ΄ κ°κ²© */
row-gap: 16px;
column-gap: 24px;
}Flex μμ΄ν μμ±
.item {
/* flex-grow: λ¨μ 곡κ°μ μΌλ§λ μ°¨μ§ν μ§ */
flex-grow: 0; /* κΈ°λ³Έκ°: μ λμ΄λ¨ */
flex-grow: 1; /* κ°λ₯ν κ³΅κ° λͺ¨λ μ°¨μ§ */
flex-grow: 2; /* flex-grow: 1 μμ΄ν
μ 2λ°° κ³΅κ° */
/* flex-shrink: κ³΅κ° λΆμ‘±ν λ μΌλ§λ μ€μ΄λ€μ§ */
flex-shrink: 1; /* κΈ°λ³Έκ°: μ€μ΄λ¦ */
flex-shrink: 0; /* μ€μ΄λ€μ§ μμ */
/* flex-basis: κΈ°λ³Έ ν¬κΈ° */
flex-basis: auto; /* κΈ°λ³Έκ°: μ½ν
μΈ ν¬κΈ° */
flex-basis: 200px; /* 200pxλΆν° μμ */
flex-basis: 0; /* flex-growλ‘λ§ ν¬κΈ° κ²°μ */
/* λ¨μΆ μμ± */
flex: 1; /* flex: 1 1 0% */
flex: 0 0 200px; /* κ³ μ 200px */
flex: auto; /* flex: 1 1 auto */
/* κ°λ³ κ΅μ°¨μΆ μ λ ¬ */
align-self: center; /* μ΄ μμ΄ν
λ§ μμ§ κ°μ΄λ° */
/* μμ λ³κ²½ */
order: 0; /* κΈ°λ³Έκ° */
order: -1; /* 맨 μμΌλ‘ */
order: 99; /* 맨 λ€λ‘ */
}μμ£Ό νλ μ€μ
/* β flex 컨ν
μ΄λ μμμ width 100% μ£Όλ©΄ μλλλ‘ μ λ μ μμ */
.item {
width: 100%; /* flex μμ΄ν
μ widthλ³΄λ€ flex-basisκ° μ°μ */
}
/* β
flex-basis μ¬μ© */
.item {
flex: 0 0 100%;
}
/* β flex-shrink λͺ¨λ₯΄κ³ min-width μ€μ */
.item {
/* κΈ°λ³Έμ μΌλ‘ μμ΄ν
μ min-content ν¬κΈ°κΉμ§λ μ€μ΄λ€μ§ μμ */
/* ν
μ€νΈκ° κΈ΄ μμ΄ν
μ΄ μμλ³΄λ€ μ μ€μ΄λ€λ©΄ μλλ₯Ό μΆκ° */
}
/* β
ν
μ€νΈ λμΉ¨ ν΄κ²° */
.item {
min-width: 0; /* μ΄κ±Έ μΆκ°ν΄μΌ ν
μ€νΈκ° overflow μ²λ¦¬λ¨ */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}Flexbox μ€μ ν¨ν΄
μμ§/μν κ°μ΄λ° μ λ ¬
/* μλ²½ν κ°μ΄λ° μ λ ¬ */
.center-container {
display: flex;
justify-content: center; /* μν κ°μ΄λ° */
align-items: center; /* μμ§ κ°μ΄λ° */
min-height: 100vh; /* νλ©΄ μ 체 λμ΄ */
}<div class="center-container">
<div class="content">κ°μ΄λ°μ μλ μ½ν
μΈ </div>
</div>λ€λΉκ²μ΄μ λ° (λ‘κ³ μΌμͺ½, λ©λ΄ μ€λ₯Έμͺ½)
.navbar {
display: flex;
align-items: center;
padding: 0 24px;
height: 60px;
}
.logo {
margin-right: auto; /* λλ¨Έμ§ κ³΅κ°μ logo μ€λ₯Έμͺ½μ ν λΉ β λ©λ΄κ° μ€λ₯Έμͺ½μΌλ‘ λ°λ¦Ό */
}
.nav-menu {
display: flex;
gap: 24px;
}<nav class="navbar">
<a class="logo" href="/">MyBrand</a>
<ul class="nav-menu">
<li><a href="/about">About</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>μΉ΄λ μ»΄ν¬λνΈ λ΄λΆ λ μ΄μμ
.card {
display: flex;
flex-direction: column; /* μΈλ‘ λ°°μΉ */
height: 100%; /* λμ΄ ν΅μΌμ μν΄
}
.card-body {
flex: 1; /* λ¨μ κ³΅κ° λͺ¨λ μ°¨μ§ β λ²νΌμ νμ νλ¨μ */
}
.card-footer {
margin-top: auto; /* λλ μ΄ λ°©λ²λ κ°λ₯ */
}νΈν°λ₯Ό νμ νλ¨μ κ³ μ (Sticky Footer)
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1; /* λ¨μ κ³΅κ° λͺ¨λ μ°¨μ§ β footerκ° νμ μλ */
}
footer {
/* μλμΌλ‘ νλ¨μ μμΉ */
}λ°μν νκ·Έ λͺ©λ‘
.tags {
display: flex;
flex-wrap: wrap; /* νκ·Έκ° λ§μΌλ©΄ μλμΌλ‘ μ€λ°κΏ */
gap: 8px;
}
.tag {
padding: 4px 12px;
background: #e2e8f0;
border-radius: 99px;
white-space: nowrap;
}CSS Grid μμ μ 볡
Gridλ ν(row)κ³Ό μ΄(column)μ λμμ μ μν΄μ μμ΄ν μ λ°°μΉνλ€.
Grid 컨ν μ΄λ μμ±
.grid-container {
display: grid;
/* μ΄ μ μ */
grid-template-columns: 200px 1fr 1fr; /* 200px κ³ μ , λλ¨Έμ§ 1:1 */
grid-template-columns: repeat(3, 1fr); /* 3λ±λΆ */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* λ°μν! */
/* ν μ μ */
grid-template-rows: 60px 1fr 60px; /* ν€λ, λ©μΈ, νΈν° */
grid-template-rows: repeat(3, auto); /* μ½ν
μΈ ν¬κΈ°μ λ§κ² */
/* κ°κ²© */
gap: 16px;
row-gap: 24px;
column-gap: 16px;
/* μλ μμ±λλ νμ ν¬κΈ° */
grid-auto-rows: minmax(100px, auto);
/* Named Areas */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}fr λ¨μ
frμ fractional unit β λ¨μ 곡κ°μ λΉμ¨μ΄λ€.
/* 3:1:1 λΉμ¨λ‘ λλ */
grid-template-columns: 3fr 1fr 1fr;
/* 200px κ³ μ ν λλ¨Έμ§λ₯Ό 2:1λ‘ λλ */
grid-template-columns: 200px 2fr 1fr;auto-fill vs auto-fit
/* auto-fill: λΉ μΉΌλΌ μ μ§ */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* μμ΄ν
μ΄ 3κ°μ¬λ 5μΉΈμ΄ λ€μ΄κ° 곡κ°μ΄λ©΄ 5μΉΈ μ μ§ */
/* auto-fit: λΉ μΉΌλΌ μ ν */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* μμ΄ν
μ΄ 3κ°λ©΄ 3κ°κ° λ¨μ 곡κ°μ κ· λ± λΆν */λλΆλΆμ λ°μν μΉ΄λ 그리λμλ auto-fillμ΄ λ μμ°μ€λ½λ€.
Grid μμ΄ν μμ±
.item {
/* μμμ΄, λμ΄ μ§μ */
grid-column: 1 / 3; /* 1λ²μ§Έ μ μμ 3λ²μ§Έ μ κΉμ§ */
grid-column: 1 / span 2; /* 1λ²μ§Έ μ΄μμ 2μΉΈ μ°¨μ§ */
grid-column: span 2; /* νμ¬ μμΉμμ 2μΉΈ μ°¨μ§ */
/* μμν, λν μ§μ */
grid-row: 1 / 3;
grid-row: span 2;
/* Named Area μ¬μ© */
grid-area: header;
/* μ
λ΄λΆ μ λ ¬ */
justify-self: center; /* μν */
align-self: center; /* μμ§ */
place-self: center; /* λ λ€ */
}Grid μ€μ ν¨ν΄
λ°μν μΉ΄λ 그리λ (ν΅μ¬ ν¨ν΄!)
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}<div class="card-grid">
<div class="card">μΉ΄λ 1</div>
<div class="card">μΉ΄λ 2</div>
<div class="card">μΉ΄λ 3</div>
<!-- λͺ κ°λ μλμΌλ‘ λ°μν 그리λ κ΅¬μ± -->
</div>μ΄ λ¨ 3μ€μ§λ¦¬ CSSκ° λ―Έλμ΄ μΏΌλ¦¬ μμ΄ μμ ν λ°μν 그리λλ₯Ό λ§λ€μ΄μ€λ€.
- λμ λ: 4μ΄, 5μ΄, ...
- μ’μ λ: 3μ΄, 2μ΄, 1μ΄
μΉμ¬μ΄νΈ μ 체 λ μ΄μμ
.page-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 50px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }βββββββββββββββββββββββββββββββββββ
β header β
ββββββββββββ¬βββββββββββββββββββββββ€
β β β
β sidebar β main β
β β β
ββββββββββββ΄βββββββββββββββββββββββ€
β footer β
βββββββββββββββββββββββββββββββββββμ¬μ§ κ°€λ¬λ¦¬ (λΉλμΉ span)
.gallery {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
gap: 8px;
}
/* 첫 λ²μ§Έ μ¬μ§μ 2λ°° ν¬κ² */
.gallery-item:first-child {
grid-column: span 2;
grid-row: span 2;
}
/* κ°λ‘λ‘ κΈ΄ μ¬μ§ */
.gallery-item.wide {
grid-column: span 2;
}λμ보λ λ μ΄μμ
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr); /* 12μ΄ κ·Έλ¦¬λ */
gap: 16px;
padding: 24px;
}
/* ν΅κ³ μΉ΄λ: 12μ΄ μ€ 3μ΄μ© (4κ°) */
.stat-card {
grid-column: span 3;
}
/* μ°¨νΈ: 8μ΄ */
.chart {
grid-column: span 8;
}
/* μ¬μ΄λ ν¨λ: 4μ΄ */
.side-panel {
grid-column: span 4;
}
/* ν
μ΄λΈ: μ 체 λλΉ */
.data-table {
grid-column: 1 / -1; /* μ²μλΆν° λκΉμ§ */
}λ°μν λ μ΄μμ μ λ΅
Mobile First μ κ·Όλ²
/* κΈ°λ³Έ μ€νμΌ = λͺ¨λ°μΌ */
.container {
display: flex;
flex-direction: column;
gap: 16px;
}
/* νλΈλ¦Ώ (768px μ΄μ) */
@media (min-width: 768px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.card {
flex: 0 0 calc(50% - 8px); /* 2μ΄ */
}
}
/* λ°μ€ν¬ν± (1024px μ΄μ) */
@media (min-width: 1024px) {
.card {
flex: 0 0 calc(33.333% - 11px); /* 3μ΄ */
}
}λ―Έλμ΄ μΏΌλ¦¬ μμ΄ λ°μν λ§λ€κΈ°
/* auto-fill + minmax β λ―Έλμ΄ μΏΌλ¦¬ λΆνμ */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}clamp()λ‘ μ λμ μΈ ν¬κΈ°
/* clamp(μ΅μκ°, κΈ°λ³Έκ°, μ΅λκ°) */
.title {
font-size: clamp(1.25rem, 4vw, 2.5rem);
/* μ΅μ 20px, λ·°ν¬νΈ λλΉμ 4%, μ΅λ 40px */
}
.container {
width: clamp(320px, 90%, 1200px);
/* μ΅μ 320px, νλ©΄μ 90%, μ΅λ 1200px */
margin: 0 auto;
}CSS λ³μλ‘ λ μ΄μμ κ΄λ¦¬
:root {
--columns: 1;
--gap: 16px;
--sidebar-width: 0px;
}
@media (min-width: 768px) {
:root {
--columns: 2;
--gap: 24px;
}
}
@media (min-width: 1024px) {
:root {
--columns: 3;
--sidebar-width: 260px;
}
}
.grid {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
gap: var(--gap);
}CSS λ μ΄μμ λλ²κΉ
Chrome DevTools Grid/Flex μκ°ν
Chrome DevToolsλ Gridμ Flex λ μ΄μμμ μκ°μ μΌλ‘ 보μ¬μ£Όλ κΈ°λ₯μ΄ μλ€.
- Elements νμμ
display: gridλλdisplay: flexμμ μ ν - μμ μμ λνλλ
grid/flexλ±μ§ ν΄λ¦ - μ€λ²λ μ΄λ‘ 그리λ/νλ μ€ λΌμΈ, μμ μ΄λ¦μ΄ νμλ¨
μμ£Ό λ°μνλ λ¬Έμ μ ν΄κ²°λ²
λ¬Έμ 1: ν μ€νΈκ° Flex μμ΄ν μ λ°μ΄λ
/* λ¬Έμ : ν
μ€νΈκ° κΈΈλ©΄ μμ΄ν
μ΄ μ€μ΄λ€μ§ μμ */
.nav-item { ... }
/* ν΄κ²°: min-width: 0 μΆκ° */
.nav-item {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}λ¬Έμ 2: Grid μμ΄ν μ΄ μμλ³΄λ€ νΌ
/* λ¬Έμ : μ½ν
μΈ κ° grid μ
μ λ²μ΄λ¨ */
.grid-item { ... }
/* ν΄κ²°: min-width: 0 λλ overflow μ€μ */
.grid-item {
min-width: 0; /* Gridμμλ λμΌνκ² νμ */
}λ¬Έμ 3: box-sizing λ¬Έμ
/* paddingμ΄ ν¬ν¨λ ν¬κΈ° κ³μ°μ μν΄ μ μ μ€μ κΆμ₯ */
*, *::before, *::after {
box-sizing: border-box;
}λ¬Έμ 4: z-indexκ° μ λ¨Ήν
z-indexλ positionμ΄ μ€μ λμ΄ μκ±°λ, Flex/Grid μμ΄ν
μΈ κ²½μ°μλ§ λμνλ€.
/* z-indexκ° μ λ¨Ήν λ */
.item {
position: relative; /* λλ absolute, fixed, sticky */
z-index: 10;
}λ¬Έμ 5: Flex μμ΄ν μ΄ μμ ν¬κΈ°μ λ€λ¦
/* flex-shrink: 1 μ΄ κΈ°λ³Έκ°μ΄λΌ μμ΄ν
μ΄ μ€μ΄λ€ μ μμ */
.item {
flex-shrink: 0; /* μ€μ΄λ€μ§ μκ² κ³ μ */
}Flexbox vs Grid μ΅μ’ μ ν κ°μ΄λ
| μ¬μ© μ¬λ‘ | Flexbox | Grid | λΉκ³ |
|---|---|---|---|
| λ²νΌ κ·Έλ£Ή, ν΄λ° | β | - | 1μ°¨μ λμ΄ |
| λ€λΉκ²μ΄μ λ©λ΄ | β | - | ν λ°©ν₯ λ°°μΉ |
| μΉ΄λ/μμ΄ν μ λ ¬ | β³ | β | λ°μνμ΄λ©΄ Grid |
| νμ΄μ§ μ 체 λ μ΄μμ | - | β | 2μ°¨μ ꡬ쑰 |
| μμ§/μν κ°μ΄λ° μ λ ¬ | β | β | λ λ€ OK |
| μμ΄μ½ + ν μ€νΈ μ λ ¬ | β | - | μ»΄ν¬λνΈ λ΄λΆ |
| μ΄λ―Έμ§ κ°€λ¬λ¦¬ | - | β | 2μ°¨μ λ°°μΉ |
| λ°μν μ΄ λ μ΄μμ | β³ | β | Gridκ° λ κ°κ²° |
| μ½ν μΈ ν¬κΈ°μ λ°λ₯Έ λμ λ°°μΉ | β | - | Flexκ° μ μ° |
| κ³ μ λ μ΄ κ΅¬μ‘° (ν μ΄λΈν) | - | β | Gridκ° λͺ ν |
κ²°λ‘ : μ»΄ν¬λνΈ λ΄λΆ μ λ ¬μ΄λ ν λ°©ν₯ λμ΄μ Flexbox, 2μ°¨μ λ μ΄μμκ³Ό μ 체 νμ΄μ§ ꡬ쑰λ Grid. κ·Έλ¦¬κ³ λλΆλΆμ νλ‘λμ UIμμλ λμ ν¨κ» μ΄λ€.
/* μ€λ¬΄μμ μμ£Ό 보μ΄λ μ‘°ν© */
.page {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header {
grid-area: header;
display: flex; /* ν€λ λ΄λΆλ Flex */
align-items: center;
justify-content: space-between;
}
.main {
grid-area: main;
display: grid; /* λ©μΈ μ½ν
μΈ λ Grid */
grid-template-columns: 1fr 300px;
gap: 24px;
}
.card-list {
display: grid; /* μΉ΄λ λͺ©λ‘λ Grid */
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
align-content: start;
}
.card {
display: flex; /* μΉ΄λ λ΄λΆλ Flex */
flex-direction: column;
}Flexboxμ Gridλ₯Ό λͺ¨λ μ΅νλ€λ©΄ κ±°μ λͺ¨λ UI λ μ΄μμμ ꡬνν μ μλ€. μ²μμ νλμ© μ¨λ³΄λ©΄μ μ΅νκ³ , μμ°μ€λ½κ² μν©μ λ§κ² μ ννλ κ°μ΄ μκΈΈ κ²μ΄λ€.
κ΄λ ¨ κΈ
- π μΉ μ κ·Όμ±μ μ€μμ±κ³Ό κΈ°λ³Έ μμΉ β λ μ΄μμμ μ κ·Όμ± μκ² λ§λλ λ°©λ²
- β‘ JavaScript λΉλκΈ° μ²λ¦¬ μμ κ°μ΄λ β CSSμ ν¨κ» λ°°μ°λ νλ‘ νΈμλ ν΅μ¬
- π· TypeScript μ λ¬Έ β νλ‘ νΈμλ κ°λ°μ ν λ¨κ³ μ¬λ €μ£Όλ νμ μμ€ν
