CSS 포지셔닝과 주요 속성들
웹 페이지의 요소를 원하는 위치에 배치하는 방법을 학습한다. 박스 모델을 벗어나 자유롭게 요소를 배치하고 겹치게 할 수 있다.
box-sizing
요소의 너비(width)와 높이(height)를 계산하는 기준을 정한다.
content-box(기본값):width와height가 콘텐츠 영역만 포함하고,padding과border는 별도로 추가된다.border-box:width와height에padding과border가 포함된다. 레이아웃을 직관적으로 설계할 수 있어 매우 유용하다.
* {
box-sizing: border-box; /* 모든 요소에 적용하는 것을 권장 */
}
.box {
width: 200px;
padding: 20px;
border: 10px solid black;
/* 최종 너비가 200px로 유지됨 */
}둘 다 width: 200px이지만, content-box는 padding·border가 밖으로 더해져 실제 너비가 260px가 된다.
content-box (기본) → 실제 260px
width:200 + padding + border
border-box → 실제 200px 유지
width:200 안에 모두 포함
float와 clear
실무 참고
과거에는 레이아웃 구성에 float가 널리 쓰였지만, 현재는 Flexbox와 Grid로 대체되었다. float는 주로 이미지 주변에 텍스트 흐르게 하기 같은 용도로 남아 있다.
float: 요소를 보통의 흐름에서 벗어나 좌측(left)이나 우측(right)에 떠 있게 만든다.clear:float속성이 적용된 요소의 영향을 받지 않고, 다음 줄에 배치되도록 한다. (left,right,both)
.profile-img {
float: left;
margin-right: 15px;
}
.footer {
clear: both; /* float 효과를 해제 */
}position 속성
요소의 배치 방식을 결정하는 핵심 속성이다.
static(기본값): 일반적인 문서의 흐름에 따라 배치된다. 위치 지정 속성(top,right,bottom,left)이 적용되지 않는다.relative: 자신의 원래 위치(static)를 기준으로top,right등으로 위치를 이동시킨다. 다른 요소에 영향을 주지 않으며,absolute자식 요소의 기준점이 된다.absolute:position이static이 아닌 가장 가까운 조상 요소를 기준으로 위치를 지정한다. 그런 조상이 없다면 초기 컨테이닝 블록(보통 뷰포트)을 기준으로 한다. 일반적인 문서 흐름에서 벗어난다.fixed: 브라우저 창(Viewport)을 기준으로 위치를 지정한다. 스크롤을 해도 항상 같은 자리에 고정된다. (예: 상단 고정 메뉴, 팝업 창)sticky: 평소에는relative처럼 동작하다가, 스크롤 시 지정된 위치에 도달하면fixed처럼 고정된다. 섹션 제목이 스크롤에 따라 상단에 붙는 패턴 등에 유용.
.wrapper {
position: relative; /* 자식 요소인 .box의 기준점 */
width: 300px;
height: 300px;
}
.box {
position: absolute;
top: 20px;
left: 20px;
/* .wrapper의 좌측 상단에서 (20px, 20px) 떨어진 위치 */
}
.top-banner {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
.sticky-header {
position: sticky;
top: 0; /* 스크롤 시 상단에 도달하면 고정 */
}relative 부모 안에 absolute 자식을 두면, 자식은 부모의 좌상단을 기준으로 배치된다.
position: relative (기준이 되는 부모)
top:30 left:20
(absolute 자식)
bottom:8 right:8
💡 절대 위치 가운데 정렬 패턴
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}부모 영역을 가득 채우는 패턴은 position: absolute; inset: 0; (또는 top:0; right:0; bottom:0; left:0;).
visibility와 z-index
visibility: 요소를 보이거나 숨긴다.visible(기본값): 보임hidden: 숨김. 자신의 공간은 그대로 차지한다.
💡 요소를 숨기는 세 가지 방법 비교
속성 | 공간 차지 | 클릭/이벤트 | 스크린 리더에서 읽음 |
|---|---|---|---|
| ❌ | ❌ | ❌ |
| ✅ | ❌ | ❌ |
| ✅ | ✅ | ✅ |
일시적으로 숨길 때는 visibility, 완전히 제거할 때는 display: none, 페이드아웃 애니메이션용으로는 opacity를 자주 쓴다.
z-index: 요소들의 쌓임 순서(stack order)를 결정한다. 값이 클수록 위로 올라온다. 주의:position이static이 아닌 요소에만 적용된다 (relative,absolute,fixed,sticky). 스택킹 컨텍스트(stacking context) 안에서만 비교되므로, 부모 요소가 새로운 컨텍스트를 만들면 그 안에서만 비교된다.
z-index: 1
z-index: 3 (맨 위)
z-index: 2
다단으로 편집하기 (Multi-column)
신문이나 잡지처럼 텍스트를 여러 개의 단으로 나눌 수 있다.
column-count: 단의 개수를 지정한다.column-width: 각 단의 너비를 지정한다.column-gap: 단과 단 사이의 간격을 지정한다.column-rule: 단과 단 사이에 구분선을 추가한다. (border속성과 유사)column-span: 특정 요소가 여러 단에 걸쳐 표시되도록 한다.
.newspaper-article {
column-count: 3;
column-gap: 40px;
column-rule: 1px solid lightgray;
}
.newspaper-article h2 {
column-span: all; /* 제목은 모든 단에 걸쳐서 표시 */
}신문 기사처럼 텍스트가 세 개의 단으로 나뉘어 흐릅니다. 한 단이 가득 차면 자동으로 다음 단으로 이어집니다. column-count로 단 개수를, column-gap으로 단 사이 간격을, column-rule로 구분선을 지정합니다. 긴 글을 좁은 폭으로 읽기 좋게 배치할 때 유용합니다.
표 스타일 (Table Style)
HTML <table> 요소를 보기 좋게 꾸미는 속성들이다.
caption-side:<caption>태그의 위치를 지정한다. (top,bottom)border-collapse: 셀 테두리를 합칠지(collapse), 분리할지(separate) 결정한다.border-spacing: 셀과 셀 사이의 간격을 지정한다.border-collapse: separate;일 때만 동작한다 (separate가 기본값이지만,collapse로 바꾸면 무시됨).empty-cells: 내용이 없는 셀의 테두리와 배경을 표시할지 여부를 결정한다.table-layout: 테이블의 레이아웃 알고리즘을 결정한다.auto(기본값): 셀의 내용에 따라 너비가 결정된다.fixed: 테이블 및 열의 너비에 따라 결정된다. 렌더링 속도가 빠르다.
vertical-align: 셀 안에서 콘텐츠의 수직 정렬을 지정한다. (top,middle,bottom)
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
th, td {
border: 1px solid #ccc;
padding: 10px;
text-align: center;
vertical-align: middle;
}HTML5와 시맨틱 태그 (Semantic Tags)
시맨틱(Semantic) 태그는 브라우저와 개발자 모두에게 콘텐츠의 의미를 명확하게 전달하는 역할을 한다. <div> 태그를 사용하는 대신 의미에 맞는 태그를 사용하면 코드의 가독성과 웹 접근성이 향상된다.
대표적인 페이지는 아래처럼 의미 단위로 구획된다. 똑같이 <div>로만 짜도 화면은 같아 보이지만, 시맨틱 태그를 쓰면 각 영역이 "무슨 역할인지"가 코드에 드러난다.
<header> 머리말 (로고·소개)
<nav> 메뉴 (Home · About · Contact)
<main>
<article> / <section>
핵심 콘텐츠
<aside>
보조
<footer> 꼬리말 (저작권·링크)
<header>: 페이지나 특정 섹션의 소개, 탐색(navigation) 등 머리말 영역을 나타낸다.<nav>: 다른 페이지로 이동하는 네비게이션 링크(메뉴) 그룹을 나타낸다.<main>: 해당 문서의 핵심적인 콘텐츠를 나타낸다.main태그는 문서에 단 한 번만 사용해야 한다.<section>: 문서의 독립적인 구획을 나타내며, 보통 제목(<h1>~<h6>)을 포함한다.<article>: 블로그 글, 뉴스 기사처럼 독립적으로 배포하거나 재사용할 수 있는 내용을 나타낸다.<aside>: 본문과 직접 관련은 적지만 보조적인 콘텐츠를 나타낸다. 사이드바, 광고, 참고 링크 등.<figure>와<figcaption>: 이미지·차트·코드 블록 등 독립적인 콘텐츠와 그 설명을 묶는다.<time>: 날짜나 시간을 기계가 읽을 수 있는 형식으로 명시한다.<time datetime="2026-03-31">2026년 3월 31일</time>처럼 사용.<footer>: 페이지나 특정 섹션의 작성자 정보, 저작권, 관련 링크 등 꼬리말 영역을 나타낸다.
💡 <section> vs <article> vs <div> 언제 쓰나?
<article>: 독립적으로 배포/재사용할 수 있는 내용 (블로그 글, 뉴스 기사, 포럼 게시글, 제품 카드 하나)<section>: 제목을 가진 함께 묶이는 구획 ("회사 소개", "고객 후기" 등 의미 있는 그룹)<div>: 의미는 없고 순수한 스타일/레이아웃 목적 (<section>도 아니고<article>도 아니라면<div>)
대체로 "제목을 쓸 수 있을까?"를 스스로 물어보면 도움이 된다. 쓸 수 있으면 <section>/<article>, 아니면 <div>.
<body>
<header>
<h1>My Website</h1>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h2>Article Title</h2>
<p>Article content...</p>
</article>
</main>
<footer>
<p>© 2025 My Website. All rights reserved.</p>
</footer>
</body>종합 실습: 상단 고정 네비게이션 만들기
지금까지 배운 시맨틱 태그와 position 속성을 활용하여, 스크롤을 내려도 항상 상단에 고정되는 네비게이션 바가 있는 웹 페이지를 만들어 본다.
요구사항
header,nav,main,section,footer시맨틱 태그를 사용하여 페이지 구조를 작성한다.<header>요소는 브라우저 상단에 고정(position: fixed)되어 스크롤해도 움직이지 않아야 한다.고정된
<header>가<main>콘텐츠를 가리지 않도록,<main>영역에 적절한padding또는margin을 적용한다.<header>는z-index를 이용해 다른 모든 요소보다 위에 표시되도록 한다.페이지 스크롤을 확인하기 위해
<main>영역에 충분한 양의 콘텐츠를 채운다.
완성 코드
index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>상단 고정 네비게이션</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="main-header">
<nav>
<a href="#" class="logo">MyLogo</a>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">Features</a></li>
<li><a href="#">Pricing</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<main class="content-area">
<section>
<h1>메인 콘텐츠 영역</h1>
<p>이 페이지는 스크롤을 내려도 상단 네비게이션 바가 고정되어 있습니다.</p>
<p>Lorem ipsum dolor sit amet... (내용 반복) ...</p>
</section>
</main>
<footer>
<p>© 2025 Fixed Navigation Example. All rights reserved.</p>
</footer>
</body>
</html>style.css
body, h1, ul, p {
margin: 0;
padding: 0;
}
body {
font-family: sans-serif;
line-height: 1.6;
}
.main-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #333;
color: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 1000;
}
.main-header nav {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
height: 60px;
}
.logo {
font-size: 24px;
font-weight: bold;
color: white;
text-decoration: none;
}
.nav-links {
list-style: none;
display: flex;
}
.nav-links li {
margin-left: 20px;
}
.nav-links a {
color: white;
text-decoration: none;
font-size: 16px;
}
.content-area {
padding-top: 60px;
max-width: 1200px;
margin: 0 auto;
padding-left: 20px;
padding-right: 20px;
}
.content-area section {
padding: 40px 0;
}
footer {
text-align: center;
padding: 20px;
background-color: #f2f2f2;
margin-top: 40px;
}