Skip to Content
WebCSSCSS 기본기08. Flexbox로 내비게이션 정렬하기

이번 편의 결과물: 내비게이션 메뉴 항목이 데스크톱 폭에서 가로로 정렬됩니다. 다루는 개념: flex container/item, justify-content/align-items, gap

이 편에서 만드는 파일

web-practice/portfolio/ └── css/ └── styles.css ~ (.site-nav Flexbox 규칙 추가)

개념 정리

Flexbox는 display: flex를 지정한 요소(flex container)의 자식들(flex item)을 한 방향(메인 축)으로 배치하는 1차원 레이아웃입니다. .site-nav<nav> 안에 <a> 3개(소개·프로젝트·연락)를 직접 담고 있으며, 기본 상태에서는 <a>가 인라인 요소라 옆으로 붙어 보이긴 하지만 줄바꿈 없이 정렬되지는 않습니다.

속성적용 대상역할
display: flexcontainer(.site-nav)자식을 flex item으로 전환, 기본 방향은 가로(row)
justify-contentcontainer메인 축(가로) 정렬. flex-start/center/space-between
align-itemscontainer크로스 축(세로) 정렬. 내비 항목 높이를 맞출 때 사용
gapcontaineritem 사이 간격. margin보다 간단하고 마진 상쇄가 없다

흔한 오해는 justify-content를 item에 지정하는 것입니다. 정렬 속성은 항상 container(부모)에 지정합니다. item에는 flex-grow·flex-shrink·align-self처럼 자기 자신의 크기·정렬을 조정하는 속성만 씁니다.

실습

1. 마크업 확인

index.html(다른 두 페이지도 동일)의 헤더 구조는 다음과 같습니다(마크업은 수정하지 않고 확인만 합니다).

<!-- web-practice/portfolio/index.html (헤더 부분 발췌, 수정하지 않음) --> <header class="site-header"> <a class="logo" href="index.html">Zeno Kim</a> <nav class="site-nav"> <a href="index.html" aria-current="page">소개</a> <a href="projects.html">프로젝트</a> <a href="contact.html">연락</a> </nav> </header>

<nav class="site-nav"> 안에는 <ul>·<li> 없이 <a> 3개가 바로 들어 있습니다. flex container로 만들 대상은 이 <a>들의 직계 부모인 .site-nav 자체입니다.

2. styles.css 열기

07편 여백 규칙 아래에 이어서 작성합니다.

3. .site-nav를 flex container로 전환

/* web-practice/portfolio/css/styles.css */ /* ...03~07편 리셋·타이포그래피·색·여백 유지... */ .site-nav { display: flex; gap: var(--space-6); } .site-nav a { color: var(--color-text); font-weight: 500; text-decoration: none; } .site-nav a[aria-current='page'] { color: var(--color-primary); font-weight: 700; }

.site-nav의 자식이 <a>뿐이므로 flex container도 .site-nav 자체에 지정합니다(<ul>이 없으니 list-style 제거는 필요 없습니다). aria-current="page"는 마크업에 이미 있는 접근성 속성으로, 현재 페이지 링크를 시각적으로도 구분하는 데 그대로 활용합니다.

4. 헤더 전체를 가로 배치로 정리

.site-header 자체도 로고와 내비를 양 끝으로 배치해야 합니다.

.site-header { display: flex; align-items: center; justify-content: space-between; padding: 0 var(--space-6); height: var(--header-height); }

justify-content: space-between은 첫 item(로고)과 마지막 item(내비)을 양 끝에 붙이고 그 사이 공간을 균등하게 벌립니다. align-items: center는 로고와 내비 항목의 세로 중앙을 맞춥니다.

5. 실행

파일을 저장하고 세 페이지를 모두 브라우저로 새로고침합니다.

6. 확인

  • 로고 “Zeno Kim”이 왼쪽, 내비 메뉴 3개(소개·프로젝트·연락)가 오른쪽에 가로로 나란히 보입니다.
  • 메뉴 항목 사이 간격이 --space-6(1.5rem)만큼 일정합니다.
  • 현재 열려 있는 페이지의 메뉴 링크만 파란색(--color-primary)과 굵은 글씨로 구분됩니다.
  • 개발자 도구에서 .site-nav를 선택하면 Layout 탭(Chrome 기준)에 파란 flex 배지가 표시되고, 자식 <a> 3개에 노란 flex item 표시가 뜹니다.

직접 해보기

  1. .site-navgapvar(--space-2)로 줄여 메뉴 항목이 얼마나 촘촘해지는지 비교해 보세요.
  2. .site-headerjustify-contentspace-between에서 flex-end로 바꿔, 로고와 내비가 모두 오른쪽으로 몰리는 모습을 확인해 보세요. 확인 후 space-between으로 되돌립니다.

정답 확인

  1. gap: var(--space-2)(0.5rem)로 바꾸면 메뉴 항목 사이가 좁아져 세 링크가 서로 가까이 붙습니다. 시안 값인 --space-6과 비교하면 답답해 보이므로 원래 값이 왜 선택됐는지 감이 옵니다.
  2. flex-end는 모든 item을 메인 축 끝(오른쪽)으로 모읍니다. 로고까지 오른쪽으로 밀려 헤더 왼쪽이 비어 보이므로, 로고와 내비를 양 끝에 고정하려면 space-between이 맞는 선택입니다.

자주 하는 실수

증상원인고치는 법
메뉴가 옆으로 안 붙는다display: flex.site-nav가 아니라 다른 요소에 줬다flex container를 <a> 3개의 직계 부모인 .site-nav에 지정
justify-content가 안 먹는다container가 아니라 item(a)에 지정했다정렬 속성은 항상 부모(container)에 지정
메뉴 항목 사이 간격이 짝이 안 맞는다gap 대신 margin-right를 각 항목에 줘서 마지막 항목에도 여백이 남았다gap을 쓰면 item 사이에만 간격이 생겨 마지막 항목 뒤에는 여백이 남지 않는다
헤더 높이가 시안보다 낮다--header-heightpadding에만 의존해 계산했다height: var(--header-height)를 직접 지정하고 align-items: center로 내용만 세로 중앙 정렬

확인 문제

문제 14지선다
display: flex는 어디에 지정해야 자식이 flex item이 되는가?
문제 24지선다
.site-header에 justify-content: space-between을 쓴 이유는?
문제 34지선다
.site-nav에 gap 대신 각 a에 margin-right를 주는 방식의 단점은?

참고 자료

Last updated on