한 줄 요약 — 부모에 display: flex 한 줄을 주면 자식들이 한 줄로 정렬된다. 줄의 방향은 flex-direction(가로 row / 세로 column)이 정하고, 그 줄을 따라 자식을 모으거나 벌리는 일은 justify-content가 맡는다. 오늘은 이 세 속성으로 헤더의 로고·메뉴·버튼을 한 줄에 세운다.

학습 목표#

  • display: flex가 부모와 자식의 관계를 어떻게 바꾸는지 설명할 수 있다.
  • flex-direction으로 줄의 방향(가로·세로)을 바꾸고, 그때 두 축이 함께 바뀐다는 걸 안다.
  • justify-content의 주요 값(center, space-between 등)으로 자식을 줄을 따라 배치할 수 있다.
  • justify-content(주축)와 align-items(교차축)가 각각 어느 방향을 맡는지 구분할 수 있다.

오늘의 비유 — 한 줄로 세운 사람들에게 정렬을 명령하기#

체육 시간에 선생님이 학생들을 한 줄로 세운다고 해 보자. "한 줄로 서!" 한마디면 흩어져 있던 아이들이 가로로 죽 늘어선다. 이게 부모 요소에 display: flex를 주는 일이다. 부모가 "너희는 이제 한 줄이다"라고 선언하면, 그 안의 자식들이 차례로 줄을 선다.

줄을 세웠으면 이제 명령을 내린다. "가운데로 모여", "양 끝으로 벌려서 간격 똑같이", "다 왼쪽으로 붙어" — 줄을 따라 좌우로 어떻게 퍼질지를 정하는 이 명령이 justify-content다. 한편 "키 높이는 가운데에 맞춰"처럼 줄과 직각 방향(위아래)으로 맞추는 명령은 align-items가 맡는다. Flexbox(정식 명칭 Flexible Box Layout)는 이렇게 한 줄로 선 자식들에게 "어느 방향으로, 어떻게 정렬하라"를 부모가 일괄로 명령하는 도구다.

핵심 개념#

display: flex — 부모가 줄을 세운다#

display: flex는 자식이 아니라 **부모(컨테이너)**에 준다. 이 한 줄로 부모는 'flex 컨테이너'가 되고, 직계 자식들은 'flex 아이템'이 되어 한 줄로 늘어선다. 기본 방향은 가로다.

<nav class="bar">
  <span>로고</span>
  <span>메뉴</span>
  <span>로그인</span>
</nav>
.bar {
  display: flex;
}

span은 원래 인라인이라 옆으로 붙지만, flex 아이템이 되면 블록이든 인라인이든 상관없이 한 줄에 정렬된다. 줄을 세우는 주체가 부모라는 점이 핵심이다.

flex-direction — 줄의 방향과 두 축#

줄이 뻗는 방향을 정하는 게 flex-direction이다. 기본값 row는 가로 한 줄, column은 세로 한 줄이다.

.bar {
  display: flex;
  flex-direction: row; /* 가로(기본) — column으로 바꾸면 세로 */
}

여기서 중요한 개념 두 가지. 줄이 뻗는 방향을 주축(main axis), 그와 직각인 방향을 **교차축(cross axis)**이라 부른다. row면 주축이 가로, 교차축이 세로다. column으로 바꾸면 주축과 교차축이 통째로 90도 돌아간다. 이 사실이 다음 속성을 이해하는 열쇠다.

justify-content — 주축을 따라 모으고 벌린다#

justify-content주축 방향으로 자식을 어떻게 배치할지 정한다. 줄을 따라 한쪽으로 모을 수도, 균등하게 벌릴 수도 있다.

.bar {
  display: flex;
  justify-content: space-between; /* 양 끝으로 벌리고 사이를 균등하게 */
}

자주 쓰는 값은 이렇다.

  • flex-start(기본) — 줄 시작 쪽에 모은다.
  • center — 가운데로 모은다.
  • space-between — 양 끝에 붙이고 사이 간격을 똑같이 나눈다.
  • space-around / space-evenly — 바깥 여백까지 포함해 간격을 나눈다.

주의할 점 하나. justify-content는 항상 주축을 따라 작동한다. 그래서 flex-direction: column이면 이 속성이 좌우가 아니라 위아래로 모으고 벌린다. 방향을 바꾸면 명령의 대상 축도 함께 바뀐다는 걸 기억하자.

함께 따라하기 — 헤더의 로고·메뉴·버튼 한 줄에 세우기#

거의 모든 웹사이트 맨 위에 있는 그 헤더를 만들어 본다. 왼쪽에 로고, 오른쪽에 메뉴와 로그인 버튼을 두는 흔한 모양이다.

<header class="header">
  <span class="logo">LifeisOneCoin</span>
  <nav class="menu">
    <a href="/posts/"></a>
    <a href="/about/">소개</a>
    <a href="/login/" class="login">로그인</a>
  </nav>
</header>
.header {
  display: flex;
  justify-content: space-between; /* 로고는 왼쪽, 메뉴는 오른쪽 */
  align-items: center;            /* 위아래 가운데 맞춤 */
  padding: 12px 20px;
}

.menu {
  display: flex;
  gap: 16px; /* 메뉴 항목 사이 간격 */
}

저장하고 열어 보면, 로고가 왼쪽 끝, 메뉴 묶음이 오른쪽 끝에 자리 잡고, 둘 다 세로로는 가운데에 맞춰진다. .header.menu 두 군데에 display: flex를 준 점에 주목하자. 바깥 줄(로고 ↔ 메뉴)과 안쪽 줄(메뉴 항목들)은 각각 별도의 flex 컨테이너다. 줄 안에 또 줄을 세운 셈이다.

흔한 실수 3가지#

1. justify-content와 align-items의 축을 거꾸로 이해한다#

"가로로 가운데 두고 싶은데 왜 위아래로만 움직이지?" 하는 혼란이 가장 흔하다. 두 속성은 서로 다른 축을 맡는다.

/* (가로 정렬을 바라고 align-items를 쓰면 위아래만 바뀝니다) */
.bar {
  display: flex;
  align-items: center; /* 이건 교차축(세로) 가운데 */
}

row에서 좌우(주축)는 justify-content, 위아래(교차축)는 align-items다. 가로로 모으고 싶으면 이렇게 고친다.

.bar {
  display: flex;
  justify-content: center; /* 주축(좌우) 가운데 */
}

2. flex-direction을 바꾸면 두 축이 바뀐다는 걸 모른다#

column으로 바꿨더니 justify-content: center가 갑자기 위아래 가운데로 동작해 당황하는 경우다. 버그가 아니라 주축이 세로로 돌았기 때문이다.

.bar {
  display: flex;
  flex-direction: column;
  justify-content: center; /* 이제 '세로' 가운데로 모은다 */
  align-items: center;     /* 이제 '가로' 가운데로 맞춘다 */
}

방향을 바꿀 때마다 두 속성이 맡는 화면 방향을 다시 외우려 들면 헷갈린다. "둘은 늘 서로 직각"이라고만 기억하면 된다.

3. 가운데 정렬에 margin auto면 될 일을 transform으로 푼다#

요소 하나를 부모 한가운데 두려고 position: absolutetransform: translate(-50%, -50%)부터 꺼내는 경우가 많다. flex 안에서는 더 간단하다.

/* (한 요소를 가운데 두려고 굳이 좌표를 계산합니다) */
.item {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

부모가 flex라면 자식에 margin: auto 한 줄이면 주축·교차축 양쪽 가운데로 간다. 좌표 계산도, 부모의 position 설정도 필요 없다.

.parent { display: flex; }
.item   { margin: auto; }

오늘 배운 것 체크리스트#

  • display: flex는 자식이 아니라 부모에 준다.
  • flex-direction은 줄의 방향을 정하고, 그때 주축·교차축이 함께 돈다.
  • justify-content주축을 따라 자식을 모으고 벌린다.
  • 교차축 정렬은 align-items가 맡는다(둘은 늘 직각).
  • 요소 하나를 가운데 둘 땐 flex + margin: auto로 충분하다.

자주 묻는 질문#

Q. justify-content와 align-items는 무엇이 다른가요?

A. 맡는 축이 다릅니다. justify-content는 줄이 뻗는 방향(주축)을, align-items는 그와 직각인 방향(교차축)을 정렬합니다. 기본값인 가로 줄(row)에서는 justify-content가 좌우, align-items가 위아래를 맡습니다.

Q. flex로 가로·세로 둘 다 가운데 정렬하려면 어떻게 하나요?

A. 부모에 display: flex; justify-content: center; align-items: center; 세 줄이면 자식이 양방향 한가운데로 옵니다. 자식이 하나뿐이라면 그 자식에 margin: auto만 줘도 같은 결과가 됩니다.

Q. flex-direction을 column으로 바꿨더니 정렬이 반대로 동작해요.

A. 정상입니다. justify-contentalign-items는 늘 주축·교차축을 기준으로 움직이는데, column이면 주축이 세로로 돌기 때문입니다. 가로·세로라는 화면 방향이 아니라 '주축·교차축'으로 생각하면 헷갈리지 않습니다.

다음 시간 예고#

내일은 Flexbox 심화 — gap, flex-grow/shrink/basis, align-items 완전 정복을 다룬다. 오늘 한 줄에 세운 자식들이 남는 공간을 어떻게 나눠 갖고, 화면이 좁아질 때 어떻게 줄어드는지 — 비율을 다루는 속성들을 손에 익힌다.

더 알아보기#