Flexbox란?
Flexbox(Flexible Box Layout)는 CSS에서 1차원 레이아웃을 만드는 가장 강력한 도구입니다. "1차원"이라는 말은 한 방향(가로 또는 세로)으로 아이템을 정렬한다는 뜻입니다.
Flexbox 이전에는 float, inline-block, position 등을 조합해서 레이아웃을 잡았는데, 코드가 복잡하고 수직 중앙 정렬 같은 기본적인 작업도 까다로웠습니다. Flexbox는 이 모든 문제를 깔끔하게 해결합니다.
기본 개념: 컨테이너와 아이템
Flexbox는 두 가지 역할로 나뉩니다:
- Flex Container (부모):
display: flex를 선언하는 요소 - Flex Item (자식): 컨테이너 안에 있는 직계 자식 요소들
.container {
display: flex;
}이 한 줄만 추가하면, .container의 모든 직계 자식이 자동으로 가로로 나란히 배치됩니다. 이것만으로도 기존의 float 해킹을 완전히 대체할 수 있습니다.
flex-direction: 배치 방향 정하기
아이템이 나열되는 방향을 지정합니다.
| 값 | 설명 |
|---|---|
row (기본값) | 왼쪽 → 오른쪽 |
row-reverse | 오른쪽 → 왼쪽 |
column | 위 → 아래 |
column-reverse | 아래 → 위 |
.container {
display: flex;
flex-direction: column; /* 세로로 쌓기 */
}모바일에서는 column, 데스크톱에서는 row로 바꾸는 패턴이 반응형 웹에서 자주 사용됩니다.
justify-content: 주축 정렬
아이템을 주축(main axis) 방향으로 어떻게 배치할지 결정합니다. flex-direction이 row면 가로 방향, column이면 세로 방향입니다.
.container {
display: flex;
justify-content: center; /* 가운데 정렬 */
}| 값 | 동작 |
|---|---|
flex-start | 시작점에 모음 |
flex-end | 끝점에 모음 |
center | 가운데 정렬 |
space-between | 양 끝 붙이고 나머지 균등 배분 |
space-around | 각 아이템 양옆에 동일 여백 |
space-evenly | 모든 간격을 완전히 동일하게 |
실전 팁: 네비게이션 바에서 로고와 메뉴를 양 끝에 배치하려면 justify-content: space-between이 정답입니다.
align-items: 교차축 정렬
주축과 수직인 방향(교차축, cross axis)으로 아이템을 정렬합니다.
.container {
display: flex;
height: 300px;
align-items: center; /* 수직 중앙 정렬! */
}| 값 | 동작 |
|---|---|
stretch (기본값) | 컨테이너 높이에 맞게 늘림 |
flex-start | 위쪽 정렬 |
flex-end | 아래쪽 정렬 |
center | 수직 중앙 정렬 |
baseline | 텍스트 기준선 맞춤 |
가장 유명한 CSS 트릭: 완벽한 중앙 정렬
.container {
display: flex;
justify-content: center;
align-items: center;
}이 3줄이면 어떤 요소든 정확히 가운데에 놓을 수 있습니다. CSS 역사상 가장 많은 개발자를 구원한 코드라고 해도 과언이 아닙니다.
gap: 아이템 간격
Flexbox 아이템 사이의 간격을 지정합니다. 예전에는 margin으로 처리했지만, gap이 훨씬 깔끔합니다.
.container {
display: flex;
gap: 16px; /* 모든 방향 16px */
gap: 16px 24px; /* 세로 16px, 가로 24px */
}margin과 달리 gap은 아이템 "사이"에만 적용되므로, 첫 번째와 마지막 아이템에 불필요한 여백이 생기지 않습니다.
flex-wrap: 줄바꿈
기본적으로 Flex 아이템은 한 줄에 모두 들어가려고 합니다. 아이템이 많아지면 찌그러지죠. flex-wrap: wrap을 사용하면 자연스럽게 줄바꿈됩니다.
.container {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.item {
width: 200px; /* 200px 이상이면 다음 줄로 */
}카드 그리드를 만들 때 flex-wrap: wrap과 함께 카드에 고정 너비를 주면 간단한 반응형 그리드가 완성됩니다.
Flex 아이템 속성들
flex-grow: 남은 공간 차지 비율
.sidebar { flex-grow: 0; width: 250px; } /* 고정 */
.main { flex-grow: 1; } /* 나머지 전부 차지 */flex-shrink: 줄어드는 비율
공간이 부족할 때 아이템이 얼마나 줄어들지 결정합니다. 기본값은 1이고, 0으로 설정하면 절대 줄어들지 않습니다.
flex-basis: 기본 크기
width와 비슷하지만, flex 환경에서는 flex-basis가 우선합니다.
/* 단축 속성: flex: grow shrink basis */
.item { flex: 1 0 300px; } /* 최소 300px, 남으면 균등 분배, 절대 안 줄어듦 */실전 예제: 네비게이션 바
<nav class="navbar">
<div class="logo">Compit</div>
<ul class="nav-links">
<li><a href="#">챌린지</a></li>
<li><a href="#">학습</a></li>
<li><a href="#">랭킹</a></li>
</ul>
<button class="btn-login">로그인</button>
</nav>.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
}
.nav-links {
display: flex;
list-style: none;
gap: 24px;
}justify-content: space-between으로 로고, 메뉴, 버튼이 자동으로 양 끝과 가운데에 배치됩니다.
실전 예제: 카드 그리드
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 280px; /* 최소 280px, 남으면 균등 분배 */
padding: 24px;
border-radius: 12px;
background: #f8f9fa;
}이 패턴 하나로 반응형 카드 레이아웃이 완성됩니다. 화면이 넓으면 3열, 좁으면 2열, 더 좁으면 1열로 자동 변환됩니다.
Flexbox vs Grid: 언제 뭘 쓸까?
| 상황 | 추천 |
|---|---|
| 한 줄 정렬 (네비, 버튼 그룹) | Flexbox |
| 2차원 격자 레이아웃 | Grid |
| 아이템 크기가 콘텐츠에 따라 다름 | Flexbox |
| 정확한 열/행 구조 필요 | Grid |
| 수직 중앙 정렬 | 둘 다 가능 |
대부분의 경우 Flexbox로 시작하고, 2차원 배치가 필요하면 Grid로 전환하는 것이 좋습니다.
정리
Flexbox의 핵심 속성을 정리하면:
- display: flex — 시작점
- flex-direction — 방향 (row/column)
- justify-content — 주축 정렬
- align-items — 교차축 정렬
- gap — 간격
- flex-wrap — 줄바꿈
- flex: grow shrink basis — 아이템 크기 제어
이 7가지만 익히면 웹 레이아웃의 80%는 해결할 수 있습니다. 이론을 읽었다면 이제 직접 만들어볼 차례입니다!