CSS

CSS 포지셔닝 & HTML5와 시맨틱 태그

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: 숨김. 자신의 공간은 그대로 차지한다.

💡 요소를 숨기는 세 가지 방법 비교

속성

공간 차지

클릭/이벤트

스크린 리더에서 읽음

display: none

❌

❌

❌

visibility: hidden

✅

❌

❌

opacity: 0

✅

✅

✅

일시적으로 숨길 때는 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>&copy; 2025 My Website. All rights reserved.</p>
    </footer>
</body>

종합 실습: 상단 고정 네비게이션 만들기

지금까지 배운 시맨틱 태그와 position 속성을 활용하여, 스크롤을 내려도 항상 상단에 고정되는 네비게이션 바가 있는 웹 페이지를 만들어 본다.

요구사항

  1. header, nav, main, section, footer 시맨틱 태그를 사용하여 페이지 구조를 작성한다.

  2. <header> 요소는 브라우저 상단에 고정(position: fixed)되어 스크롤해도 움직이지 않아야 한다.

  3. 고정된 <header>가 <main> 콘텐츠를 가리지 않도록, <main> 영역에 적절한 padding 또는 margin을 적용한다.

  4. <header>는 z-index를 이용해 다른 모든 요소보다 위에 표시되도록 한다.

  5. 페이지 스크롤을 확인하기 위해 <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>&copy; 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;
}

마지막 수정 2026년 10월 22일