๐ŸŽจ CSS Flexbox & Grid ์™„์ „ ์ •๋ณต: ์–ธ์ œ ๋ญ˜ ์จ์•ผ ํ•˜๋Š”๊ฐ€

@leekh8 ยท April 20, 2026 ยท 12 min read

CSS ๋ ˆ์ด์•„์›ƒ์„ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ๋‚˜์˜ค๋Š” ์งˆ๋ฌธ์ด ์žˆ๋‹ค.

"Flexbox๋ž‘ Grid ์ค‘์— ๋ญ˜ ์จ์•ผ ํ•ด์š”?"

์ •๋‹ต์€ "๋‘˜ ๋‹ค ์•Œ์•„์•ผ ํ•œ๋‹ค"๋‹ค. ๋‘ ๊ธฐ์ˆ ์€ ์„œ๋กœ ๊ฒฝ์Ÿํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค. ์ด ๊ธ€์„ ์ฝ๊ณ  ๋‚˜๋ฉด ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์–ด๋–ค ๊ฑธ ์จ์•ผ ํ•˜๋Š”์ง€ ๋ฐ”๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ๋‹ค.


Flexbox vs Grid โ€” ํ•ต์‹ฌ ์ฐจ์ด

Grid โ€” 2์ฐจ์›
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
Flexbox โ€” 1์ฐจ์›
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ
์•„์ดํ…œ

  • 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 ๋ ˆ์ด์•„์›ƒ์„ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

  1. Elements ํƒญ์—์„œ display: grid ๋˜๋Š” display: flex ์š”์†Œ ์„ ํƒ
  2. ์š”์†Œ ์˜†์— ๋‚˜ํƒ€๋‚˜๋Š” grid / flex ๋ฑƒ์ง€ ํด๋ฆญ
  3. ์˜ค๋ฒ„๋ ˆ์ด๋กœ ๊ทธ๋ฆฌ๋“œ/ํ”Œ๋ ‰์Šค ๋ผ์ธ, ์˜์—ญ ์ด๋ฆ„์ด ํ‘œ์‹œ๋จ

์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ๋ฒ•

๋ฌธ์ œ 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 ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฒ˜์Œ์—” ํ•˜๋‚˜์”ฉ ์จ๋ณด๋ฉด์„œ ์ตํžˆ๊ณ , ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์„ ํƒํ•˜๋Š” ๊ฐ์ด ์ƒ๊ธธ ๊ฒƒ์ด๋‹ค.


์ด์–ด์„œ ์ฝ๊ธฐ


@leekh8
๋ณด์•ˆ, ์›น ๊ฐœ๋ฐœ, Python์„ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ