Flexible box layout/Aligning flex items

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
93/190

안녕하세요! 오늘 번역해 볼 MDN 공식 문서는 CSS 플렉스박스(Flexbox)의 꽃이자 프론트엔드 개발자들이 가장 사랑하는 기능인 플렉스 컨테이너 안에서 아이템 정렬하기 (Aligning items in a flex container)에 대한 내용입니다.

웹 개발을 하다 보면 "요소 하나를 화면 정중앙에 배치해 주세요"라는 요구사항을 정말 자주 마주치게 되죠. 과거에는 이를 해결하기 위해 온갖 편법(hack)을 동원해야 했지만, 이제는 Flexbox 덕분에 단 두세 줄의 코드로 완벽한 중앙 정렬이 가능해졌습니다. 프론트엔드 직무 기술 면접에서도 빈출되는 Flexbox의 정렬 속성들, 그 원리와 작동 방식을 낱낱이 파헤쳐 봅시다!


플렉스 컨테이너 안에서 아이템 정렬하기 (Aligning items in a flex container)

플렉스박스(flexbox)가 그토록 유용한 이유 중 하나는 요소들을 완벽하게 정렬(alignment)할 수 있도록 도와주며, 특히 요소들을 수직으로 중앙 정렬(vertically centering)하는 아주 빠르고 직관적인 방법을 제공하기 때문입니다. 이 가이드에서는 플렉스박스에서 정렬(alignment) 및 공간 배분(justification) 속성들이 어떻게 작동하는지 철저하게 살펴보겠습니다.

이 문서에서 다룰 내용 (In this article)


플렉스박스에서 정렬 기능 사용하기 (Using alignment in flexbox)

플렉스박스는 정렬과 간격을 제어하기 위한 여러 가지 속성들을 제공하는데, 그중에서도 align-itemsjustify-content는 요소를 중앙에 배치하는 데 있어 가장 핵심적인 속성입니다.

요소를 정중앙에 배치하려면, 우리는 align-items 속성을 사용해 요소를 교차축(cross axis)을 기준으로 정렬합니다. 기본 설정(flex-direction: row)에서 교차축은 수직으로 달리는 블록 축(block axis)을 의미하죠. 또한 justify-content 속성을 사용하여 요소를 주축(main axis)을 기준으로 정렬합니다. 기본 설정에서 주축은 수평으로 달리는 인라인 축(inline axis)을 의미합니다.

The cross axis is the vertical axis and the main axis is the horizontal axis.

아래 코드 예제에서 부모 컨테이너나 내부 요소의 크기를 변경해 보세요. 크기가 어떻게 변하든 내부 요소는 항상 정중앙에 머물러 있는 것을 확인할 수 있습니다.

<div class="box">
  <div></div>
</div>
.box {
  display: flex;
  align-items: center; /* 교차축(세로) 중앙 정렬 */
  justify-content: center; /* 주축(가로) 중앙 정렬 */
  border: 2px dotted rgb(96 139 168);
}

.box div {
  width: 100px;
  height: 100px;
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
}

💡 강사의 실무 코딩 팁!
display: flex; align-items: center; justify-content: center; 이 3줄의 코드는 프론트엔드 개발자들의 '만능 치트키'입니다. 팝업창(모달)을 화면 한가운데 띄울 때나 버튼 안의 텍스트와 아이콘을 정중앙에 맞출 때 등, 하루에도 수십 번씩 쓰게 될 공식이니 손가락이 기억하도록 외워두세요!


플렉스박스의 정렬을 제어하는 속성들 (Properties for controlling alignment in flexbox)

이 가이드에서 살펴볼 정렬 속성들은 다음과 같습니다:

  • justify-content: 주축(main axis)을 기준으로 모든 아이템의 정렬을 제어합니다.
  • align-items: 교차축(cross axis)을 기준으로 모든 아이템의 정렬을 제어합니다.
  • align-self: 교차축을 기준으로 개별 플렉스 아이템 하나의 정렬을 제어합니다 (부모의 설정을 무시하고 자기 자신만 독자적으로 움직입니다).
  • align-content: 교차축을 기준으로 플렉스 라인(줄)들 사이의 공간을 제어합니다 (줄바꿈이 일어났을 때만 의미가 있습니다).
  • gap, column-gap, row-gap: 플렉스 아이템들 사이에 틈(gaps)이나 여백(gutters)을 만들 때 사용됩니다.

우리는 또한 플렉스박스에서 auto 마진(margin)이 정렬을 위해 어떻게 기발하게 사용될 수 있는지도 알아볼 것입니다.


교차축(cross axis)에서 아이템 정렬하기 (Aligning items on the cross axis)

플렉스 컨테이너에 설정하는 align-items 속성과 개별 플렉스 아이템에 설정하는 align-self 속성은 플렉스 아이템들이 교차축 상에서 어떻게 정렬될지를 제어합니다. flex-directionrow일 경우 교차축은 열(위아래)을 따라 달리고, flex-directioncolumn일 경우 교차축은 행(좌우)을 따라 달립니다.

가장 기본적인 플렉스 예제를 통해 교차축 정렬을 확인해 봅시다. 컨테이너에 display: flex를 추가하면, 자식 아이템들은 한 줄(row)로 배열된 플렉스 아이템이 됩니다. 기본적으로 이 아이템들은 컨테이너 내에서 가장 키가 큰 아이템의 높이에 맞춰 똑같이 늘어납니다(stretch). 가장 키가 큰 아이템이 교차축 상에서 아이템들이 가져야 할 높이의 기준을 정의하기 때문입니다. 만약 플렉스 컨테이너 자체에 고정된 높이가 설정되어 있다면, 아이템들은 자신들의 내부 콘텐츠 양과 상관없이 그 컨테이너의 높이만큼 쭈욱 늘어납니다.

Three items, one with additional text causing it to be taller than the others.

Three items stretched to 200 pixels tall

아이템들의 높이가 똑같아지는 이유는 교차축 정렬을 제어하는 align-items 속성의 초깃값(기본값)이 stretch(늘어나다)로 설정되어 있기 때문입니다.

우리는 아이템들의 정렬 방식을 제어하기 위해 stretch 이외의 다른 값들을 사용할 수 있습니다:

  • align-items: stretch (기본값: 교차축을 가득 채우도록 늘어남)
  • align-items: flex-start (교차축의 시작 부분에 붙음)
  • align-items: flex-end (교차축의 끝 부분에 붙음)
  • align-items: start
  • align-items: end
  • align-items: center (교차축의 중앙에 위치)
  • align-items: baseline (텍스트의 베이스라인-글자의 밑바닥 선-을 기준으로 정렬)
  • align-items: first baseline
  • align-items: last baseline

아래 예제에서 align-items 값은 현재 stretch로 설정되어 있습니다. 이 값을 다른 것들로 바꿔보면서 플렉스 컨테이너 안에서 아이템들이 서로 어떻게 다르게 정렬되는지 관찰해 보세요.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three <br />has <br />extra <br />text</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
}

.box {
  width: 500px;
  height: 130px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
  align-items: stretch; /* 이 값을 flex-start나 center 등으로 바꿔보세요! */
}

`align-self`로 아이템 하나만 따로 정렬하기 (Aligning one item with `align-self`)

align-items 속성은 플렉스 컨테이너에 선언되어 모든 플렉스 아이템들의 align-self 속성을 그룹으로 일괄 설정하는 역할을 합니다. 즉, 반대로 말하면 여러분이 특정 아이템 하나만 콕 집어서 align-self 속성을 명시적으로 선언해 줄 수 있다는 뜻입니다. align-self 속성은 align-items와 똑같은 값들을 받을 수 있으며, 추가로 auto라는 값을 받을 수 있습니다. auto는 부모 플렉스 컨테이너에 정의된 기본 정렬 방식(align-items 값)을 그대로 따르겠다는 의미입니다.

다음 예제에서 부모 플렉스 컨테이너는 align-items: flex-start를 가지고 있으므로, 모든 아이템은 기본적으로 교차축의 시작점(위쪽)에 정렬됩니다. 그러나 first-child 선택자를 사용하여 첫 번째 아이템에는 align-self: stretch를 설정했습니다. 그리고 selected 클래스를 가진 또 다른 아이템에는 align-self: center를 설정했습니다.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div class="selected">Three</div>
  <div>Four</div>
</div>
.box {
  border: 2px dotted rgb(96 139 168);
  display: flex;
  align-items: flex-start; /* 부모는 전체를 위로 올립니다 */
  height: 200px;
}
.box div {
  background-color: rgb(96 139 168 / 0.2);
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  padding: 20px;
}
.box > *:first-child {
  align-self: stretch; /* 첫째는 혼자만 아래위로 쭉 늘어납니다 */
}
.box .selected {
  align-self: center; /* 셋째는 혼자만 정중앙에 위치합니다 */
}

주축 방향 바꾸기 (Changing the main axis)

지금까지 우리는 문서의 언어가 위에서 아래로(top to bottom), 가로 방향(주축)과 세로 방향(교차축)을 가지고 쓰이는 환경에서 flex-direction이 기본값인 row일 때의 정렬 동작을 살펴봤습니다.

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

만약 문서의 쓰기 모드(writing mode)는 그대로 둔 채 flex-directioncolumn으로 변경하면 어떻게 될까요?
align-itemsalign-self 속성은 더 이상 상하(top and bottom)가 아닌 좌우(left and right)로 아이템들을 정렬하게 됩니다. 이 속성들은 여전히 변함없이 '교차축(cross axis)'을 따라 아이템을 정렬하고 있지만, flex-direction: column 때문에 이제 주축이 세로가 되고 교차축이 가로(horizontal)가 되었기 때문입니다!

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

아래 예제는 바로 전 예제와 코드가 완전히 똑같지만, 부모 컨테이너에 flex-direction: column이 추가되어 있습니다. 요소들이 좌우로 어떻게 다르게 정렬되는지 확인해 보세요.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div class="selected">Three</div>
  <div>Four</div>
</div>
.box {
  border: 2px dotted rgb(96 139 168);
  display: flex;
  flex-direction: column; /* 주축이 세로로 바뀝니다! */
  align-items: flex-start; /* 따라서 align-items는 좌우(가로)를 컨트롤하게 됩니다 */
  width: 200px;
}
.box div {
  background-color: rgb(96 139 168 / 0.2);
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  padding: 20px;
}
.box > *:first-child {
  align-self: stretch; /* 첫째는 가로로 쭉 늘어납니다 */
}
.box .selected {
  align-self: center; /* 셋째는 가로의 중앙에 위치합니다 */
}

`align-content` 속성으로 교차축에서 콘텐츠 정렬하기 (Aligning content on the cross axis with the `align-content` property)

지금까지는 플렉스 아이템들이 딱 한 줄(a single line)로만 배열되어 있는 플렉스 컨테이너 영역 안에서 아이템들을 정렬하는 데 집중했습니다. 하지만 만약 플렉스 아이템들이 여러 줄로 줄바꿈(wrap) 되도록 허용했다면 어떨까요?
이럴 때 사용하는 것이 바로 align-content 속성입니다. 이 속성은 여러 줄로 나뉜 플렉스 라인(줄)들 사이의 빈 공간을 어떻게 배분할지를 제어합니다. 이를 일컬어 플렉스 라인 패킹(packing flex lines)이라고도 부릅니다.

💡 강사의 핵심 포인트!
align-items각각의 줄 내부에서 아이템을 정렬하는 것이고, align-content는 줄바꿈(flex-wrap: wrap)이 발생하여 생긴 줄(Line) 덩어리들 자체를 교차축에서 어떻게 정렬할 것인지 결정합니다. 줄이 딱 한 줄뿐이라면 align-content는 아무런 일도 하지 않습니다!

align-content가 효과를 발휘하려면, 플렉스 컨테이너의 교차축 크기(지금 예제에서는 컨테이너의 전체 높이)가 아이템들을 표시하는 데 필요한 높이보다 훨씬 커서 여유 공간이 있어야 합니다. 그러면 이 속성은 아이템들 전체를 하나의 커다란 세트(set)로 보고 작동합니다. align-content 값은 남아도는 가용 공간(extra available space)을 가지고 무엇을 할 것인지, 그리고 그 안에서 아이템 세트 전체를 어떻게 정렬할 것인지를 지시합니다.

align-content 속성은 다음과 같은 값들을 가집니다:

  • align-content: flex-start
  • align-content: flex-end
  • align-content: start
  • align-content: end
  • align-content: center
  • align-content: space-between
  • align-content: space-around
  • align-content: space-evenly
  • align-content: stretch
  • align-content: normal (stretch와 동일하게 작동)

아래 예제에서 플렉스 컨테이너는 300px의 높이를 가지고 있는데, 이는 아이템들을 두 줄로 표시하는 데 필요한 공간보다 넉넉합니다. align-content 값이 space-between으로 설정되어 있기 때문에, 남는 가용 공간은 두 개의 플렉스 라인(줄) 사이(between)에 전부 배분되며, 첫 줄은 컨테이너의 맨 위(시작점)에, 두 번째 줄은 맨 아래(끝점)에 딱 달라붙게 됩니다.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
  <div>Six</div>
  <div>Seven</div>
  <div>Eight</div>
</div>
.box {
  width: 450px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
  flex-wrap: wrap; /* 아이템이 넘치면 다음 줄로 넘어갑니다 */
  height: 300px;
  align-content: space-between; /* 줄과 줄 사이의 여백을 끝까지 벌립니다 */
}

.box > * {
  padding: 20px;
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 1 1 100px;
}

만약 flex-directioncolumn으로 설정해서 주축이 세로 방향(블록 방향)이 되었다면, align-content는 컨테이너 안에 분배할 남는 공간이 있는 한 이제 가로 방향(좌우)으로 줄(열)들 사이의 공간을 분배하게 됩니다. (아래 코드를 참고하세요.)

.box {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column; /* 주축이 세로가 되었습니다 */
  justify-content: space-between; /* 주축(세로) 여백 분배 */
  height: 300px;
  align-content: space-between; /* 교차축(가로)의 열과 열 사이 여백 분배 */
  border: 2px dotted rgb(96 139 168);
}

주축(main axis)에서 콘텐츠 정렬하기 (Aligning content on the main axis)

지금까지 우리는 교차축에서의 정렬이 어떻게 작동하는지 살펴보았습니다. 이제 시선을 돌려 주축(main axis)을 살펴보겠습니다. 여기서는 우리가 쓸 수 있는 속성이 딱 하나뿐입니다. 바로 justify-content입니다. 왜냐하면 주축에서는 아이템들을 낱개가 아니라 무조건 '하나의 그룹'으로 취급하기 때문입니다. justify-content를 사용하면 아이템들을 모두 표시하고도 남는 공간(available space)이 있을 때, 그 공간을 어떻게 처리할지 제어할 수 있습니다.

display: flex를 적용한 우리의 초기 예제에서, 아이템들은 하나의 행(row)으로 표시되고 컨테이너의 시작 부분(왼쪽)에 모두 일렬로 줄을 섰습니다. 이는 justify-content의 초깃값이 start처럼 동작하는 normal이기 때문입니다. 남는 가용 공간은 모두 아이템들 그룹의 맨 끝(오른쪽)에 배치됩니다.

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

주축 정렬에서 baseline 값들은 의미가 없습니다. 그 외에는 justify-content 속성은 align-content와 동일한 값들을 받습니다. (가장 많이 쓰이는 값들은 center, space-between, space-around 등입니다.)

아래 예제에서 justify-content 값은 space-between입니다. 아이템들을 표시하고 남은 공간은 아이템들 '사이'에 고르게 분배됩니다. 왼쪽 끝 아이템과 오른쪽 끝 아이템은 컨테이너의 시작점과 끝점에 완벽하게 밀착됩니다.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
</div>
.box {
  display: flex;
  justify-content: space-between; /* 양 끝을 벽에 붙이고 남은 공간을 아이템 사이에 균등 분배합니다 */
  border: 2px dotted rgb(96 139 168);
}

.box > * {
  padding: 20px;
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
}

정렬과 `flex-direction` (Alignment and `flex-direction`)

이 모든 정렬 방식을 사용할 때 반드시 기억해야 할 규칙이 있습니다. 바로 startend의 위치는 문서의 쓰기 모드(writing mode)에 의해 결정된다는 것입니다.

만약 justify-content 값이 start이고 영어처럼 왼쪽에서 오른쪽(LTR)으로 쓰는 언어 환경이라면, 아이템들은 컨테이너의 왼쪽 가장자리를 시작점으로 정렬될 것입니다.

Three items lined up on the left

하지만 아랍어처럼 오른쪽에서 왼쪽(RTL)으로 쓰는 언어 환경이라면, 아이템들은 컨테이너의 오른쪽 가장자리를 시작점으로 하여 줄을 서게 됩니다.

Three items lined up from the right

또한 flex-direction 속성을 변경해도 start 라인의 방향이 바뀝니다. 예를 들어 row 대신 row-reverse를 사용한다면 시각적인 아이템의 순서가 역전됨과 동시에 start의 위치가 원래의 반대쪽 끝으로 이동하게 됩니다.


주축 정렬을 위해 auto 마진 사용하기 (Using auto margins for main axis alignment)

주축(main axis) 상에서는 아이템들이 하나의 그룹으로 묶여 처리되기 때문에, 교차축처럼 개별 아이템을 조작하는 justify-itemsjustify-self 같은 속성이 존재하지 않습니다. 하지만 자동 마진(auto margins) 기능과 플렉스박스를 결합하면, 개별 아이템이나 특정 아이템 그룹을 다른 아이템들로부터 뚝 떨어뜨려 정렬하는 아주 마법 같은 일을 해낼 수 있습니다.

💡 강사의 실무 포트폴리오 팁!
네비게이션 바(GNB)를 만들 때, 로고와 메인 메뉴들은 왼쪽에 뭉쳐두고 '로그인/회원가입' 버튼만 맨 오른쪽 끝으로 보내야 하는 경우가 정말 많습니다. 이때 justify-content만으로는 해결하기 어렵죠. 이럴 때 오른쪽으로 보내고 싶은 요소나 그 앞 요소에 margin-left: auto;를 주면 모든 고민이 깔끔하게 해결됩니다!

아래 이미지를 예로 들어볼까요? 한쪽에 3개, 반대쪽에 2개의 아이템이 있습니다. 만약 플렉스 아이템에 justify-self가 작동한다고 가정하고 아이템 d를 오른쪽 끝으로 밀어낸다면, 그 뒤에 따라오는 아이템 e의 정렬은 어떻게 될까요? 이게 의도한 것일 수도 있고 아닐 수도 있죠. 플렉스박스는 이런 혼란을 막기 위해 아예 이 속성을 지원하지 않습니다.

Five items, in two groups. Three on the left and two on the right.

그 대신, CSS 마진을 이용해서 아이템 d를 저 멀리 밀어버릴 수 있습니다.

아래 라이브 예제에서, 4번째 아이템에 margin-leftauto로 설정하여 앞의 세 아이템들과 완전히 분리시켰습니다. margin: auto는 해당 축에서 사용 가능한 모든 빈 공간을 마진이 다 흡수(consume)해 버립니다. 이것이 블록 요소의 좌우 마진을 auto로 주었을 때 가운데 정렬이 되는 원리와 똑같습니다. 양쪽 마진이 남은 공간을 서로 다 먹으려고 싸우다가 결국 딱 절반씩 나눠 가지며 가운데로 밀어버리는 것이죠.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div class="push">Four</div>
  <div>Five</div>
</div>
.box {
  display: flex;
  border: 2px dotted rgb(96 139 168);
}

.box > * {
  padding: 20px;
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
}
.push {
  margin-left: auto; /* 3번과 4번 사이의 남는 모든 공간을 이 왼쪽 마진이 다 차지해 버립니다! */
}

아이템 사이에 틈(gap) 만들기 (Creating gaps between items)

플렉스 아이템들 사이에 틈새(gap)를 만들려면, gap, column-gap, row-gap 속성을 사용하면 됩니다. (과거에는 margin으로 계산하느라 힘들었지만, 이제는 gap 속성이 플렉스박스에서도 완벽하게 지원됩니다!)

column-gap 속성은 가로 행(row)을 따라 나열된 아이템들 사이에 틈을 만듭니다. row-gap 속성은 flex-wrap: wrap이 설정되어 아이템이 여러 줄로 나뉘었을 때, 그 플렉스 라인(줄)들 사이에 위아래 틈을 만들어줍니다.

단축 속성인 gap을 사용하면 이 두 가지를 한 번에 설정할 수 있습니다.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
  <div>Six</div>
</div>
.box {
  display: flex;
  flex-wrap: wrap;
  row-gap: 10px; /* 줄과 줄 사이의 상하 간격 */
  column-gap: 2em; /* 아이템과 아이템 사이의 좌우 간격 */
  border: 2px dotted rgb(96 139 168);
}

.box > * {
  flex: 1; /* 모든 아이템이 동일한 비율로 늘어나 공간을 채웁니다 */
  padding: 20px;
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
}

같이 보기 (See also)


MDN 개선에 참여하기 (Help improve MDN)

이 페이지가 도움이 되셨나요?

기여하는 방법 알아보기 (Learn how to contribute)

이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다 (MDN contributors).

profile
프론트에_가까운_풀스택_개발자

0개의 댓글