CSS Flexbox 완전 가이드: 한 축 레이아웃의 핵심
CSS Flexbox 완전 가이드: 한 축의 레이아웃을 예측 가능하게 만드는 법
Flexbox는 카드, 내비게이션, 입력 폼처럼 요소들을 한 줄 또는 한 열에서 배치할 때 강력한 CSS 레이아웃 모델이다. 핵심은 ‘가로 정렬 도구’가 아니라 주축(main axis)과 교차축(cross axis)을 기준으로 남는 공간과 정렬을 계산하는 모델이라는 점이다. W3C 명세에서 display: flex 또는 inline-flex를 계산값으로 갖는 상자는 flex container가 되고, 그 안의 일반 흐름 자식이 flex item이 된다.
먼저 축을 정한다
기본 flex-direction: row에서는 주축이 행 방향이고 justify-content가 그 축의 배치를 조절한다. align-items는 교차축의 기본 정렬을 정한다. 방향을 column으로 바꾸면 ‘가로/세로’라는 감각도 함께 바뀐다. 그래서 아래 코드는 버튼을 가로·세로 중앙으로 모은다.
.dialog {
min-height: 18rem;
display: flex;
justify-content: center;
align-items: center;
}
justify-content와 align-items를 외워서 쓰기보다, 현재 주축이 어느 방향인지 먼저 말로 설명해 보면 실수가 줄어든다. 여러 줄을 만들고 싶을 때는 flex-wrap: wrap을 명시한다. 기본값은 한 줄이므로, 좁아진 화면에서 항목이 자동으로 다음 줄로 넘어갈 것이라 기대하면 안 된다.
flex 값은 남는 공간의 규칙이다
flex는 flex-grow, flex-shrink, flex-basis를 줄여 쓰는 속성이다. 예를 들어 두 칸을 똑같이 나누려면 다음과 같이 작성할 수 있다.
.row { display: flex; gap: 1rem; }
.row > * { flex: 1; min-width: 0; }
MDN은 flex: 1을 flex: 1 1 0으로 설명한다. 즉 0을 기준 크기로 두고 가용 공간을 같은 비율로 배분하는 패턴이다. 반면 flex: auto는 flex: 1 1 auto여서 각 항목의 콘텐츠 크기 또는 지정된 크기를 출발점으로 삼는다. 같은 ‘1’이라도 결과가 달라지는 이유다. 긴 파일명이나 URL이 있는 카드에서 줄어들지 않고 넘치는 현상은 flex item의 기본 최소 크기와 관련될 수 있다. 그때 무작정 overflow: hidden부터 넣기보다, 실제로 줄어들어야 하는 항목에 min-width: 0을 주고 텍스트 처리 방식을 별도로 선택한다.
정렬, 간격, 순서의 함정
요소 사이 간격은 자식 마진을 흩뿌리기보다 컨테이너의 gap으로 표현하면 마지막 항목 예외가 줄어든다. 한 항목만 오른쪽으로 밀고 싶다면 해당 항목에 margin-left: auto를 주는 패턴도 유용하다. 단, 시각적 순서만 바꾸는 order와 row-reverse는 키보드 탐색·스크린 리더 사용자의 문서 순서를 바꾸지 않을 수 있다. 읽는 순서가 의미 있는 콘텐츠라면 HTML 순서를 우선 맞추고 CSS는 장식적 배치에만 사용한다.
또한 align-content는 여러 flex line을 교차축에서 배치할 때의 속성이다. 단일 줄 컨테이너에서는 효과가 없다. 한 줄 안의 아이템 정렬에는 보통 align-items 또는 개별 아이템의 align-self가 맞다. 이 차이만 알아도 “왜 중앙 정렬이 안 되지?”라는 문제의 상당수를 빠르게 좁힐 수 있다.
Flexbox와 Grid의 경계
Flexbox는 한 차원—행 또는 열—의 분배와 정렬에 특히 적합하다. 행과 열을 동시에 엄격하게 맞춰야 하는 상품 목록이나 대시보드 격자라면 Grid가 더 자연스러울 수 있다. 실제 화면은 두 기술을 함께 쓰는 경우가 많다. 바깥쪽은 Grid로 영역을 정하고, 카드 내부의 아이콘·제목·버튼은 Flexbox로 한 축 정렬을 하는 식이다.
새 레이아웃을 만들 때는 화면을 억지로 맞춘 뒤 속성을 덧붙이지 말고, (1) 주축, (2) 줄바꿈 여부, (3) 각 아이템의 기준 크기, (4) 남는 공간 분배, (5) 콘텐츠 순서의 다섯 가지를 먼저 정하자. 그러면 Flexbox는 마법이 아니라 재현 가능한 계산 규칙이 된다.