Flexbox로 가로 정렬과 가운데 정렬 끝내기
Flexbox는 정렬을 맡기는 방법이다
이전 장에서는 block, inline, inline-block으로 요소가 한 줄을 차지하는지, 옆으로 붙는지 살펴보았다. 이번 장에서는 한 걸음 더 나아가 여러 요소를 보기 좋게 정렬하는 방법을 배운다.
Flexbox는 CSS에서 요소들을 한 방향으로 정렬하기 위한 배치 방식이다. 식탁 위에 컵 여러 개를 올려놓고 "가운데로 모아 줘", "간격을 똑같이 벌려 줘", "왼쪽과 오른쪽 끝으로 나눠 줘"라고 말하는 것과 비슷하다.
Flexbox를 쓰면 이런 문제를 훨씬 단순하게 해결할 수 있다.
메뉴 항목을 가로로 나란히 놓기
버튼 두 개를 일정한 간격으로 배치하기
카드 목록 사이의 간격을 맞추기
배너 안에서 문구는 왼쪽, 버튼은 오른쪽에 놓기
로고와 메뉴가 있는 상단 헤더 정리하기
핵심은 하나다. 정렬하고 싶은 요소들의 부모에게 display: flex;를 준다.
AI 생성 이미지
부모에게 display: flex를 준다
Flexbox에서 가장 먼저 기억할 말은 부모에게 적용한다는 것이다.
예를 들어 메뉴 항목 세 개가 있다고 해 보자.
<nav class="menu">
<a href="#">소개</a>
<a href="#">서비스</a>
<a href="#">문의</a>
</nav>여기서 실제로 나란히 놓고 싶은 것은 a 태그들이다. 하지만 CSS는 각각의 a가 아니라, 그들을 감싸고 있는 부모인 .menu에 준다.
.menu {
display: flex;
}이 한 줄을 넣으면 .menu 안의 자식 요소인 링크들이 기본적으로 가로 방향으로 나란히 배치된다.
.menu {
display: flex;
gap: 24px;
}여기에 gap을 추가하면 메뉴 사이 간격이 일정해진다. gap은 요소와 요소 사이에 끼워 넣는 일정한 간격이다. 예전에는 각 메뉴에 margin-right를 따로 주는 일이 많았지만, Flexbox에서는 부모에게 gap을 주는 방식이 더 깔끔하다.
정리하면 이렇다.
.menu {
display: flex; /* 자식들을 한 줄 흐름으로 배치 */
gap: 24px; /* 자식들 사이 간격 */
}가로 정렬은 justify-content로 조절한다
justify-content는 Flexbox 안에서 자식 요소들을 가로 방향으로 어떻게 배치할지 정하는 속성이다. 긴 선반 위에 물건들을 왼쪽에 둘지, 가운데에 모을지, 양쪽 끝으로 벌릴지 정한다고 생각하면 된다.
대표 값만 먼저 익히면 충분하다.
.menu {
display: flex;
justify-content: center;
}이렇게 하면 메뉴들이 가운데로 모인다.
자주 쓰는 값은 다음과 같다.
flex-start: 왼쪽부터 배치center: 가운데 배치flex-end: 오른쪽으로 배치space-between: 첫 요소는 왼쪽 끝, 마지막 요소는 오른쪽 끝에 두고 사이를 벌림
상단 헤더에서 로고는 왼쪽, 메뉴는 오른쪽에 놓고 싶을 때 space-between이 특히 자주 쓰인다.
.header {
display: flex;
justify-content: space-between;
}이 코드는 "헤더 안의 요소들을 양쪽 끝으로 나누어 배치해 줘"라는 뜻이다.
세로 가운데 정렬은 align-items로 맞춘다
가로 정렬을 justify-content로 다뤘다면, 세로 정렬은 align-items로 다룬다.
align-items는 Flexbox 안에서 자식 요소들의 높낮이를 맞추는 속성이다. 서로 키가 다른 물건들을 한 줄에 세워 놓고 위쪽에 맞출지, 가운데 높이에 맞출지 정하는 것과 비슷하다.
버튼과 문구가 있는 배너를 예로 보자.
<div class="event-banner">
<p>여름 할인 이벤트가 진행 중입니다.</p>
<a href="#">자세히 보기</a>
</div>완성 결과는 이렇다. 문구는 왼쪽에, 버튼은 오른쪽에 있고, 둘은 세로 가운데에 가지런히 놓인다.
.event-banner {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background-color: #eff6ff;
border-radius: 12px;
}여기서 각 줄의 역할은 분명하다.
display: flex;자식 요소인 문구와 버튼을 한 줄 흐름으로 바꾼다.
justify-content: space-between;문구와 버튼을 양쪽 끝으로 벌린다.
align-items: center;문구와 버튼의 세로 위치를 가운데로 맞춘다.
Flexbox에서 가운데 정렬을 만들 때 가장 많이 쓰는 조합은 다음이다.
.box {
display: flex;
justify-content: center;
align-items: center;
}이 코드는 자식 요소를 가로 가운데, 세로 가운데에 놓는다. 팝업 안의 버튼, 카드 안의 아이콘, 빈 상태 안내 문구를 가운데 놓을 때 자주 사용한다.
gap으로 간격을 일정하게 만든다
화면이 어수선해 보이는 이유 중 하나는 간격이 제각각이기 때문이다. 어떤 메뉴는 너무 붙어 있고, 어떤 버튼은 멀리 떨어져 있으면 화면의 질서가 약해진다.
Flexbox에서는 gap으로 이 문제를 쉽게 줄일 수 있다.
<div class="button-group">
<button>취소</button>
<button>저장</button>
</div>.button-group {
display: flex;
gap: 12px;
}이렇게 하면 두 버튼 사이가 항상 12px만큼 떨어진다.
카드 목록에도 같은 생각을 적용할 수 있다.
.card-list {
display: flex;
gap: 20px;
}단, 카드가 많아 화면을 넘어갈 수 있다면 flex-wrap을 함께 쓸 수 있다. flex-wrap은 공간이 부족할 때 다음 줄로 내려가게 하는 속성이다.
.card-list {
display: flex;
gap: 20px;
flex-wrap: wrap;
}지금은 flex-wrap을 깊게 외울 필요는 없다. "카드가 한 줄에 다 안 들어가면 다음 줄로 내려가게 할 수 있다" 정도로 이해하면 충분하다.
flex-direction으로 방향을 바꾼다
Flexbox는 기본적으로 자식 요소들을 가로로 배치한다. 이 기본 방향은 flex-direction: row;이다.
.menu {
display: flex;
flex-direction: row;
}row는 행, 즉 가로줄이라는 뜻이다. 기본값이라 보통은 생략한다.
반대로 세로로 쌓고 싶을 때는 column을 쓴다.
.menu {
display: flex;
flex-direction: column;
gap: 12px;
}이렇게 하면 메뉴 항목이 위에서 아래로 쌓인다.
이 사고방식은 반응형 화면을 만들 때 중요하다. PC에서는 가로로 넓게 펼치고, 모바일에서는 세로로 쌓는다.
예를 들어 카드 목록을 PC에서는 가로로 보여 주고, 작은 화면에서는 세로로 보여 주고 싶다면 다음처럼 생각할 수 있다.
.card-list {
display: flex;
gap: 20px;
}
@media (max-width: 600px) {
.card-list {
flex-direction: column;
}
}@media는 조건을 붙이는 CSS 문장이다. 위 코드는 "화면 너비가 600px 이하일 때는 카드 목록을 세로 방향으로 바꿔 줘"라는 뜻이다. 반응형 CSS는 뒤에서 더 자세히 다루므로, 지금은 방향을 바꾸는 감각만 잡으면 된다.
실습: 로고와 메뉴가 있는 상단 헤더 만들기
이번에는 실제 웹사이트에서 자주 보는 상단 헤더를 정리해 보자.
완성 결과는 다음과 같다.
로고는 왼쪽에 있다.
메뉴는 오른쪽에 가로로 놓인다.
로고와 메뉴는 세로 가운데가 맞는다.
메뉴 사이 간격은 일정하다.
HTML은 다음과 같다.
<header class="site-header">
<div class="logo">Fresh Market</div>
<nav class="site-menu">
<a href="#">상품</a>
<a href="#">이벤트</a>
<a href="#">고객센터</a>
</nav>
</header>먼저 헤더 전체를 Flexbox로 만든다.
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 18px 24px;
border-bottom: 1px solid #e5e7eb;
}display: flex;는 로고와 메뉴를 한 줄에 놓는다. justify-content: space-between;은 로고와 메뉴를 양쪽 끝으로 보낸다. align-items: center;는 로고와 메뉴의 세로 위치를 가운데로 맞춘다.
다음으로 메뉴 자체도 Flexbox로 만든다.
.site-menu {
display: flex;
gap: 20px;
}여기서 중요한 점이 있다. .site-header도 Flexbox이고, .site-menu도 Flexbox이다.
.site-header는 로고와 메뉴 묶음의 배치를 담당한다..site-menu는 메뉴 안의 링크들을 배치한다.
부모가 달라지면 Flexbox가 정리하는 대상도 달라진다. 이 감각이 생기면 복잡한 화면도 작은 묶음으로 나누어 볼 수 있다.
마지막으로 링크의 기본 밑줄과 색을 정리한다.
.site-menu a {
color: #374151;
text-decoration: none;
font-size: 15px;
}
.logo {
font-weight: 700;
color: #111827;
}이제 헤더는 훨씬 안정적으로 보인다.
모바일에서는 세로로 바꿔 보기
화면이 좁아지면 로고와 메뉴가 한 줄에 모두 들어가기 어려울 수 있다. 이때는 헤더를 세로로 쌓고 가운데 정렬할 수 있다.
@media (max-width: 600px) {
.site-header {
flex-direction: column;
gap: 14px;
}
}이 코드는 작은 화면에서 .site-header 안의 로고와 메뉴를 위아래로 쌓는다. gap: 14px;는 로고와 메뉴 사이의 간격을 만든다.
필요하다면 메뉴도 세로로 바꿀 수 있다.
@media (max-width: 600px) {
.site-menu {
flex-direction: column;
align-items: center;
gap: 10px;
}
}PC와 모바일을 완전히 따로 만든다고 생각하지 않아도 된다. 기본 모양을 먼저 만들고, 좁은 화면에서 방향만 바꾼다고 생각하면 훨씬 쉽다.
자주 헷갈리는 지점 체크리스트
Flexbox가 적용되지 않을 때는 다음을 확인해 보자.
display: flex;를 자식이 아니라 부모에게 주었는가?정렬하고 싶은 요소들이 같은 부모 안에 들어 있는가?
가로 정렬 문제인데
align-items만 바꾸고 있지는 않은가?세로 가운데 정렬 문제인데
justify-content만 바꾸고 있지는 않은가?요소 사이 간격을 각 요소의
margin으로 제각각 주고 있지는 않은가?모바일에서 가로 배치가 답답하면
flex-direction: column;을 고려했는가?
처음에는 justify-content와 align-items가 자주 헷갈린다. 이때는 이렇게 기억하면 좋다.
justify-content: 주된 방향으로 정렬한다. 기본 Flexbox에서는 보통 가로 정렬이다.align-items: 그 반대 방향으로 맞춘다. 기본 Flexbox에서는 보통 세로 정렬이다.
다만 flex-direction: column;으로 방향을 바꾸면 두 속성이 다루는 방향도 함께 달라진다. 처음에는 기본값인 가로 배치에서 충분히 연습한 뒤, 세로 배치를 다루면 이해하기 쉽다.
작은 실습: 흩어진 링크를 메뉴처럼 정리하기
수정 전에는 링크들이 줄줄이 붙어 있거나 간격이 일정하지 않다.
<div class="footer-links">
<a href="#">회사 소개</a>
<a href="#">이용약관</a>
<a href="#">개인정보처리방침</a>
</div>수정 전 CSS가 다음과 같다고 해 보자.
.footer-links a {
margin-right: 8px;
}마지막 링크 뒤에도 불필요한 여백이 생기고, 간격 관리가 링크마다 흩어진다.
수정 후에는 부모에게 Flexbox를 적용한다.
.footer-links {
display: flex;
justify-content: center;
gap: 16px;
}
.footer-links a {
color: #4b5563;
text-decoration: none;
}수정 전후를 비교하면 차이가 분명하다.
| 구분 | 수정 전 | 수정 후 |
|---|---|---|
| 배치 기준 | 각 링크에 여백을 따로 줌 | 부모가 링크들을 정렬함 |
| 간격 | 마지막 요소 처리에 신경 써야 함 | gap으로 일정하게 관리함 |
| 가운데 정렬 | 별도 조정이 필요함 | justify-content: center로 해결함 |
| 유지보수 | 링크가 늘면 손볼 곳이 많음 | 링크가 늘어도 구조가 단순함 |
Flexbox의 핵심은 복잡한 계산이 아니다. 정렬하고 싶은 요소들을 하나의 묶음으로 보고, 그 부모에게 "가로로 놓아 줘", "가운데 맞춰 줘", "사이를 일정하게 벌려 줘"라고 말하는 것이다. 이 감각만 익혀도 메뉴, 버튼 묶음, 카드 목록, 상단 헤더를 훨씬 안정적으로 다룰 수 있다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.