안녕하세요! 프론트엔드 개발자들의 영원한 친구, 플렉스박스(Flexbox)의 세계에 오신 것을 환영합니다. 오늘 저와 함께 살펴볼 내용은 플렉스박스에서 요소들을 어떻게 자유자재로 배치하고 정렬하는지에 대한 내용입니다.
박스 정렬(Box alignment) 모듈은 다양한 레이아웃 방식에서 정렬이 어떻게 작동하는지 상세히 설명하고 있습니다. 이번 가이드에서는 오직 플렉스박스(flexbox) 환경에서 박스 정렬이 어떻게 동작하는지 집중적으로 탐구해 볼 거예요!
이 문서는 플렉스박스에 특화된 정렬 팁들을 다루고 있기 때문에, CSS의 모든 레이아웃에 걸쳐 공통적으로 적용되는 정렬 기능들을 설명하는 박스 정렬 개요(box alignment overview) 문서와 짝꿍처럼 함께 읽어보시길 강력히 권장합니다.
플렉스박스에서 정렬을 할 때 가장 기본이 되는 예제를 먼저 볼까요? 이 예제에서는 세 개의 플렉스 항목(flex items)이 메인 축(main axis)을 따라 justify-content로 정렬되고, 교차 축(cross axis)을 따라 align-items로 정렬됩니다.
재미있는 점은 첫 번째 항목(One)에 주목해 보세요! 이 녀석은 그룹 전체에 설정된 align-items 값을 쿨하게 무시하고, align-self를 center로 설정해서 독자적으로 수직 중앙에 위치하고 있습니다.
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three <br />has <br />extra <br />text</div>
</div>
body {
font-family: sans-serif;
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
display: flex;
align-items: flex-start;
justify-content: space-between;
border: 2px dotted rgb(96 139 168);
}
.box :first-child {
align-self: center;
}
MDN Playground에서 이 예제 실행해보기 (Run example in MDN Playground)
💡 강사님의 꿀팁:
align-self는 마치 "엄마(부모 컨테이너)가 모두 위로 붙어라(flex-start)라고 했지만, 난 내 맘대로 가운데(center)에 있을래!" 라고 선언하는 것과 같습니다. 부모의 규칙을 자식이 개별적으로 덮어쓸 수 있는 아주 유용한 속성이죠!
플렉스박스는 문서의 '쓰기 모드(writing mode)'를 철저히 존중합니다. 따라서 여러분이 영어(또는 한국어) 환경에서 작업하고 계실 때 justify-content를 flex-end로 설정하면 항목들이 플렉스 컨테이너의 끝, 즉 '오른쪽'으로 찰싹 달라붙게 됩니다. 기본적으로 flex-direction이 row(가로 방향)로 설정되어 있기 때문에, 이 정렬은 인라인(수평) 방향으로 일어나는 것이죠.
하지만, 플렉스박스에서는 flex-direction을 column으로 설정해서 메인 축 자체를 세로로 확 바꿔버릴 수도 있습니다! 이 경우 justify-content는 항목들을 수평이 아닌 블록(수직) 방향으로 정렬하게 됩니다. 그래서 플렉스박스를 다룰 때는 단순히 "가로/세로"로 외우기보다는 "메인 축"과 "교차 축"이라는 개념으로 생각하는 것이 훨씬 편합니다.
flex-direction 속성으로 방향이 결정되는 축 = justify-content를 사용해 정렬합니다.align-content, align-self, align-items를 사용해 정렬합니다.정말 많은 분들이 헷갈려하시는 부분입니다! 메인 축에서 플렉스박스는 플렉스 항목들을 개별이 아닌 '하나의 덩어리(그룹)'로 취급합니다. 먼저 항목들을 배치하는 데 필요한 공간을 계산한 다음, 남은 잉여 공간(leftover space)을 어떻게 분배할지 결정하죠. justify-content 속성이 바로 이 남은 공간을 어떻게 배치할지 통제하는 역할을 합니다. justify-content: flex-end를 주면 남은 공간을 통째로 항목들 앞에 밀어 넣고, justify-content: space-around를 주면 항목들 양옆으로 남은 공간을 공평하게 쪼개어 배치합니다.
이 말은 즉, 플렉스박스 메인 축에서는 전체 항목들을 한 번에 움직이는 것만 고려하기 때문에, 항목 하나만 콕 집어서 움직이려는 justify-self 속성은 애초에 이치에 맞지 않는다는 뜻입니다. (그래서 CSS에 존재하지도, 작동하지도 않습니다!)
반면, 교차 축에서는 align-self가 완벽하게 이치에 맞습니다. 교차 축 방향으로는 플렉스 컨테이너의 높이(또는 너비)에 따라 잉여 공간이 생길 수 있고, 그 공간 안에서 단일 항목을 시작점이나 끝점으로 위아래 자유롭게 이동시킬 수 있기 때문이죠.
💡 강사님의 꿀팁: 면접 단골 질문이기도 합니다! "Flexbox에서
justify-self가 안 먹히는데 왜 그런가요?" 라고 묻는다면, "메인 축은 남은 공간을 분배(distribution)하는 방식이라 개별 이동이 불가능하기 때문입니다" 라고 멋지게 대답해 보세요!
"그럼 메인 축에서 항목 하나만 뚝 떼어놓고 싶을 땐 어떡하죠?"라는 의문이 드실 겁니다. 예를 들어 로고는 맨 왼쪽에, 네비게이션 메뉴들은 맨 오른쪽에 분리해 두는 '스플릿 네비게이션(split navigation)' 패턴을 만들고 싶을 때 말이죠. 이때 바로 우리가 찾던 justify-self 역할을 대신해 주는 마법의 트릭이 있는데, 바로 auto 마진(margin)입니다!
마진을 auto로 설정하면, 해당 축에서 사용 가능한 모든 여분의 공간을 진공청소기처럼 싹 흡수해 버립니다. 박스를 가운데 정렬할 때 margin: auto를 쓰는 것과 똑같은 원리예요. 왼쪽과 오른쪽 마진을 모두 auto로 주면, 양쪽 마진이 남은 공간을 서로 차지하려고 팽팽하게 밀어내기 때문에 박스가 정중앙에 위치하게 됩니다.
이 원리를 응용해서, 모두 시작점(flex-start)에 정렬된 플렉스 항목들 중 특정 항목 하나에만 한쪽 방향으로 auto 마진을 주면 스플릿 네비게이션을 아주 쉽게 구현할 수 있습니다. 공간이 넉넉할 땐 마진이 쫙 늘어나서 항목을 밀어내지만, 화면이 좁아져서 자동 마진이 흡수할 여유 공간이 사라지면, 해당 항목은 다른 평범한 플렉스 항목들처럼 행동하며 공간에 맞춰 자연스럽게 줄어들게(shrink) 됩니다. 아주 똑똑하죠!
<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);
}
.push {
margin-left: auto;
}
MDN Playground에서 이 예제 실행해보기 (Run example in MDN Playground)
💡 강사님의 꿀팁: 위 예제에서 4번 항목에
.push { margin-left: auto; }를 주었죠? 이 한 줄 덕분에 1,2,3번은 왼쪽에 남고, 4번부터 그 뒤에 있는 5번까지는 모두 우측 끝으로 밀려나게 됩니다. GNB(Global Navigation Bar) 만들 때 정말정말 유용한 최고의 스킬입니다!
gap 속성들 (The gap properties)플렉스 항목들 사이를 일정하게 띄우고 싶을 때 사용하는 속성들입니다.
메인 축 방향으로는 column-gap 속성을 사용하여 인접한 항목들 사이에 고정된 크기의 간격(여백)을 만들 수 있습니다. (예전에 요소마다 margin을 주고 last-child 마진을 빼던 번거로운 작업은 이제 안녕입니다!)
교차 축 방향에서 row-gap 속성은 인접한 플렉스 줄(flex lines)들 사이에 위아래 간격을 만듭니다. 따라서 이 속성이 의미가 있으려면, 요소들이 한 줄을 넘어가서 다음 줄로 넘칠 수 있도록 반드시 flex-wrap 속성이 wrap으로 설정되어 있어야 합니다.
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
</div>
.box {
width: 450px;
display: flex;
flex-wrap: wrap;
row-gap: 10px;
column-gap: 2em;
border: 2px dotted rgb(96 139 168);
}
.box > * {
flex: 1;
}
MDN Playground에서 이 예제 실행해보기 (Run example in MDN Playground)
더 깊이 있는 학습을 위해 아래의 관련 문서들도 꼭 확인해 보세요!
이 문서가 학습에 도움이 되셨나요? (Was this page helpful to you?)
[Yes][No]
문서 기여 방법 알아보기: Learn how to contribute
최종 수정일: 2025년 11월 20일 (MDN contributors 작성)
이 문서를 GitHub에서 보기 | 문서의 문제점 신고하기