이번 편의 결과물: 로고와 내비게이션이 헤더 안에서 좌우로 나뉘어 시안대로 한 줄에 배치됩니다. · 다루는 개념: flex-wrap, 자동 마진으로 밀어내기, align-self
이 편에서 만드는 파일
web-practice/portfolio/
└ css/
└ styles.css ~ (.site-header, .logo, .site-nav 규칙 추가)개념 정리
08편에서 .site-nav를 flex 컨테이너로 만들어 링크 3개를 가로로 정렬했습니다. 이번 편은 그 .site-nav를 .logo와 함께 헤더 한 줄 안에 배치합니다. 헤더 자체도 flex 컨테이너로 만들고, 로고는 왼쪽 끝에 내비게이션은 오른쪽 끝에 붙입니다.
| 속성 | 역할 |
|---|---|
flex-wrap: nowrap (기본값) | 아이템이 넘쳐도 한 줄을 유지하며 크기가 줄어든다 |
flex-wrap: wrap | 한 줄에 다 안 들어가면 다음 줄로 넘긴다 |
margin-left: auto | 그 아이템과 앞 아이템 사이의 남는 공간을 전부 마진으로 차지해 뒤로 밀어낸다 |
align-self | 컨테이너의 align-items 값을 특정 아이템 하나만 덮어쓴다 |
로고와 내비를 좌우로 벌리는 방법은 두 가지입니다. justify-content: space-between을 헤더에 주거나, 내비 하나에만 margin-left: auto를 주는 방법입니다. 아이템이 두 개뿐일 때는 결과가 같지만, 나중에 헤더 안에 항목이 하나 더 들어와도(예: 로그인 버튼) margin-left: auto는 그 항목 앞에서만 밀어내므로 더 유연합니다. 이 과목에서는 margin-left: auto 방식을 씁니다.
align-self는 헤더의 align-items: center를 기본으로 쓰되, 특정 아이템만 다른 정렬이 필요할 때 그 아이템에만 적용합니다. 지금 헤더 구성에서는 모든 아이템이 세로 중앙 정렬이면 충분하므로, align-self는 “직접 해보기”에서 다뤄봅니다.
자주 하는 오해: flex-wrap을 주지 않으면 화면이 아주 좁아졌을 때 로고와 내비가 겹치거나 화면 밖으로 밀려납니다. 완전한 모바일 대응은 13편에서 미디어 쿼리로 처리하지만, flex-wrap: wrap을 미리 걸어 두면 그 전까지도 최소한 줄바꿈으로 안전하게 대응합니다.
실습
1. 기존 마크업 확인하기
index.html·projects.html·contact.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>2. css/styles.css에 헤더 레이아웃 규칙 작성하기
08편에서 만든 .site-nav 규칙 아래에 .site-header와 .logo 규칙을 추가합니다.
/* css/styles.css (일부) */
.site-header {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: var(--space-4) var(--space-6);
height: var(--header-height);
}
.logo {
font-size: var(--text-lg);
font-weight: 700;
color: var(--color-text);
text-decoration: none;
}
.site-nav {
display: flex;
align-items: center;
gap: var(--space-6);
margin-left: auto;
}
.site-nav a {
color: var(--color-text-muted);
text-decoration: none;
}
.site-nav a[aria-current='page'] {
color: var(--color-primary);
font-weight: 600;
}.site-nav에는 08편에서 만든 display: flex와 gap이 이미 있다면 중복으로 적지 않고, 이번 편에서 추가하는 margin-left: auto 한 줄만 더합니다.
3. 실행
index.html 파일을 브라우저로 엽니다(VS Code의 Live Server 확장을 쓰면 저장할 때마다 자동 새로고침됩니다).
VS Code 좌측 탐색기 → index.html 우클릭 → Open with Live Server4. 확인
- 로고 “Zeno Kim”이 헤더 왼쪽 끝에, 내비게이션 3개 링크가 오른쪽 끝에 붙어 있습니다.
- 로고와 내비 모두 세로 중앙 정렬되어 높이가 어긋나지 않습니다.
- 현재 페이지 링크(
aria-current="page")만 강조 색으로 표시됩니다.index.html에서는 “소개”가,projects.html에서는 “프로젝트”가 강조됩니다. - 브라우저 창 폭을 아주 좁게 줄여도 요소끼리 겹치지 않고 다음 줄로 넘어갑니다(완전한 모바일 배치는 13편).
직접 해보기
.site-nav의 링크 3개 중 가운데 하나에만align-self: flex-end를 적용해 봅니다. 다른 두 링크와 세로 위치가 어떻게 달라지는지 확인한 뒤 원래대로 되돌립니다.margin-left: auto를 지우고 대신.site-header에justify-content: space-between을 넣어 봅니다. 화면에 보이는 결과가 같은지 비교합니다.
답 보기
.site-nav a:nth-child(2) {
align-self: flex-end; /* 확인용 임시 실습. 확인 후 제거 */
}justify-content: space-between으로 바꾸면 아이템이 두 개(로고, 내비)뿐이므로 결과는 margin-left: auto와 동일하게 양 끝으로 벌어집니다. 차이는 아이템이 세 개 이상으로 늘어날 때 드러납니다.
자주 하는 실수
| 증상 | 원인 | 고치는 법 |
|---|---|---|
| 로고와 내비가 세로로 쌓인다 | .site-header에 display: flex를 빠뜨림 | .site-header { display: flex; } 확인 |
| 로고와 내비 사이가 벌어지지 않는다 | margin-left: auto를 헤더가 아니라 다른 요소에 넣음 | .site-nav에 직접 적용했는지 확인 |
| 좁은 화면에서 요소가 겹친다 | flex-wrap을 지정하지 않음(기본값 nowrap) | .site-header에 flex-wrap: wrap 추가 |
| 로고 밑줄이 그대로 보인다 | <a> 기본 스타일 미해제 | .logo에 text-decoration: none 확인 |