CSS 입문: 박스 모델·선택자·캐스케이드 직접 확인하기

2026.09.05·수정 2026.09.14·약 18분·작성: 해비·블로그 소개

이 글에서 만드는 것

HTML과 CSS를 별도 파일로 연결하고, 같은 width가 다른 실제 크기를 만드는 이유를 비교합니다. 선택자가 적용되는 범위와 캐스케이드, 상속을 개발자 도구에서 확인하는 첫 CSS 실습입니다.

시작·완성 예제 ZIP 내려받기 — starter에서 과제를 연습한 뒤 complete와 비교하세요.

CSS 입문: 박스 모델·선택자·캐스케이드 직접 확인하기 핵심 개념 도식
CSS 박스의 실제 크기는 content, padding, border와 box-sizing 설정을 함께 확인해야 합니다.

목차

전체 파일 전에 확인할 세 가지 선언

먼저 link 한 줄로 두 파일을 연결합니다. 그다음 공통 박스 치수를 선언하고 box-sizing 한 속성만 바꾸어 비교하세요. 마지막으로 색상 충돌을 추가하면 크기 문제와 선택자 문제를 분리해 관찰할 수 있습니다.

<link rel="stylesheet" href="styles.css">
.box { width: 240px; padding: 16px; border: 2px solid #777777; }
.box--content { box-sizing: content-box; }
.box--border { box-sizing: border-box; }
.box .note { color: #333333; }
.note { color: #777777; }

1. HTML과 CSS를 별도 파일로 연결하기

HTML 문서 구조와 링크를 먼저 익힌 뒤 진행합니다. 새 폴더에 index.htmlstyles.css 두 파일을 만드세요. 두 파일은 같은 폴더에 두며 글 마지막의 완성 코드에서 각 파일 전체를 확인할 수 있습니다. HTML 파일을 브라우저에서 열면 CSS가 함께 적용됩니다. 앞 실습의 폴더를 덮어쓰지 않고 별도 폴더를 쓰면 결과를 비교하기 쉽습니다.

linkhref="styles.css"는 현재 HTML 파일 기준 상대 경로입니다. 파일명이 다르거나 폴더가 다르면 스타일이 보이지 않습니다. 아래 CSS는 배경과 두 박스의 치수를 정하고, 일부 색상 선언을 의도적으로 충돌시켜 최종 규칙을 관찰하게 합니다.

완성 화면에는 연한 배경 위에 흰 박스 두 개가 세로로 표시됩니다. 위 박스가 아래 박스보다 36px 넓고, 박스 안 설명은 짙은 회색, 박스 아래 문장은 중간 회색이어야 합니다.

2. content, padding, border, margin 계산하기

콘텐츠 영역 바깥에 padding, 그 바깥에 border, 박스 사이에는 margin이 놓입니다. box-sizing은 지정한 width에 패딩과 테두리를 포함할지를 정합니다. W3C Box Sizing 정의에 따라 예제의 실제 테두리 너비를 계산해 보겠습니다.

설정 테두리까지 너비 내용 영역 너비
content-box 240 + 16 × 2 + 2 × 2 = 276px 240px
border-box 240px 240 − 16 × 2 − 2 × 2 = 204px

두 박스 모두 좌우 margin은 0입니다. margin은 border-box에도 포함되지 않습니다. 지정 너비보다 패딩과 테두리의 합이 더 크면 콘텐츠 크기를 음수로 만들 수 없으므로 박스가 지정값보다 커질 수 있지만, 이 예제는 그 상황에 해당하지 않습니다. 높이는 고정하지 않았기 때문에 문장이 줄바꿈되면 박스 높이가 늘어납니다.

위아래 margin을 각각 16px로 주었어도 일반 블록 흐름에서는 인접한 세로 margin이 상쇄되어 간격이 32px가 아닐 수 있습니다. 간격을 계산할 때 패딩과 마진을 바꾸어 쓰지 마세요. 여기서는 크기 비교가 목적이므로 고정 width를 유지합니다. 실제 작은 화면 대응은 다음 반응형 실습에서 다룹니다.

3. 선택자가 어느 요소를 가리키는지 읽기

선택자 가리키는 대상
body body 요소 자체입니다.
.box class 목록에 box가 있는 두 section입니다.
.box--border 두 번째 박스만 선택합니다. class 이름의 --에는 특별한 CSS 기능이 없습니다.
.box > h2 box의 직접 자식인 h2입니다. 중간에 div가 생기면 이 규칙은 그 안의 h2를 선택하지 못합니다.
.box .note box의 모든 후손 중 note 클래스가 있는 요소입니다.
a:focus-visible 브라우저가 초점 표시가 필요하다고 판단한 링크입니다. 키보드 이동으로 확인합니다.

class="box box--border"는 두 클래스에 동시에 속한다는 뜻입니다. 클래스는 재사용하고, 링크 목적지 등에 쓰는 id는 고유하게 정합니다. CSS에서 #content-title로 ID를 선택할 수도 있지만, 이 예제의 스타일은 재사용하기 쉬운 클래스로 작성했습니다.

.box .note.box.note도 구분하세요. 공백이 있는 전자는 후손 관계이고, 공백이 없는 후자는 한 요소가 두 클래스를 모두 가져야 합니다. 예제에는 box와 note를 동시에 가진 요소가 없으므로 후자로 바꾸면 짙은 회색 규칙이 사라집니다.

4. 나중에 쓴 CSS가 항상 이기지는 않습니다

캐스케이드는 여러 선언 중 최종 값을 고르는 과정입니다. 적용 조건과 선언 출처·중요도·레이어 등 우선 단계가 먼저 있으며, 그 조건이 같은 경우에 선택자 명시도와 작성 순서를 비교합니다. 이 실습은 같은 파일의 일반 작성자 스타일이며 !important, 레이어, 인라인 스타일, 애니메이션, @scope가 없는 경우로 한정합니다. W3C 캐스케이드 정의의 전체 우선순위를 단순히 “마지막 선언”으로 줄여 기억하지 마세요.

이 범위에서 .box .note는 클래스 두 개라 명시도가 (0, 2, 0), .note는 (0, 1, 0)입니다. 앞에 작성했어도 전자가 이기므로 짙은 회색이 보입니다. 명시도는 ID 수, 클래스·속성·의사 클래스 수, 타입·의사 요소 수를 차례로 비교합니다. 십진수 점수처럼 더하지 않습니다. 세부 계산 규칙은 W3C Selectors의 명시도 절에 나옵니다.

.order-note는 같은 선택자가 두 번 있고 같은 속성만 충돌합니다. 이 경우 뒤에 나온 #666666가 적용됩니다. 색만 덮어쓸 뿐 앞 규칙의 다른 속성을 통째로 지우는 방식은 아닙니다. 개발자 도구에서 두 문장을 각각 선택하면 패배한 color 선언에 취소선이 표시되는 것을 확인할 수 있습니다.

상속은 이 경쟁과 다릅니다. body의 글꼴과 기본 글자색은 자식에게 전달됩니다. 반면 박스의 padding이나 border가 자식에게 자동 복제되지는 않습니다. note 안 span에는 별도 color 선언이 없어서 부모 문장의 짙은 회색을 상속받습니다. 자식 span에 직접 색을 선언하면 부모에서 물려받은 색보다 먼저 적용됩니다.

5. 개발자 도구로 가설을 확인하기

  • 첫 번째 박스를 우클릭하고 검사합니다. Computed 또는 Layout의 박스 모델에서 콘텐츠 240px, 좌우 padding 16px, border 2px를 확인합니다.
  • 두 번째 박스는 테두리까지 240px인지 확인합니다. 두 박스에 같은 width가 적혔는데 결과가 다르다는 것을 계산과 연결합니다.
  • Styles에서 .box .note의 color 선언을 잠시 해제합니다. 두 설명이 .note의 밝은 회색으로 바뀌어야 합니다. 새로고침하면 원래 파일로 돌아옵니다.
  • 두 .order-note 규칙의 작성 순서를 파일에서 바꾸고 저장·새로고침합니다. 이번에는 더 짙은 회색이 되어야 합니다. 확인 뒤 원래대로 되돌립니다.
  • 스타일이 전혀 없으면 선택자 명시도보다 먼저 파일 경로와 로드 여부를 봅니다. 일부 속성만 안 보이면 해당 요소에 선택자가 실제로 일치하는지 확인합니다.

완성 코드: 두 파일을 같은 폴더에 저장하기

아래 두 블록은 complete 폴더의 파일 전체입니다. 먼저 starter에서 과제를 수행하고, 동작이나 계산이 다를 때 해당 선언을 비교하세요. HTML 안에 CSS를 붙여 넣지 않고 styles.css를 연결합니다.

index.html

실습 파일

파일 경로를 확인하고 같은 프로젝트 안에 저장하세요. 이미지 등 소스 목록에 없는 파일과 실행 안내는 실습 ZIP에 포함되어 있습니다.

지정한 너비에 padding과 border가 포함되도록 박스 모델을 바꾸고 계산 결과를 확인합니다. 수정 전은 시작 상태, 수정 후는 비교할 완성 상태입니다.

수정 전

index.html

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>CSS 박스와 우선순위 실습</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <h1>같은 width, 다른 박스 크기</h1>
      <p class="intro">글꼴과 기본 글자색은 body에서 상속받습니다.</p>
      <section class="box box--content" aria-labelledby="content-title">
        <h2 id="content-title">content-box</h2>
        <p class="note">
          테두리까지 276px입니다. <span>이 글자도 같은 색입니다.</span>
        </p>
      </section>
      <section class="box box--border" aria-labelledby="border-title">
        <h2 id="border-title">border-box</h2>
        <p class="note">
          테두리까지 240px입니다. <span>패딩도 그 안에 들어갑니다.</span>
        </p>
      </section>
      <p class="order-note">같은 선택자이면 나중에 작성한 색이 보입니다.</p>
      <a href="#content-title">첫 번째 박스로 이동</a>
    </main>
  </body>
</html>

styles.css

body {
  margin: 0;
  padding: 16px;
  font-family: system-ui, sans-serif;
  line-height: 1.6;
  color: #222222;
  background: #f5f5f5;
}

h1 {
  font-size: 1.6rem;
}
h2 {
  font-size: 1.2rem;
}

.box {
  width: 240px;
  padding: 16px;
  border: 2px solid #777777;
  margin: 16px 0;
  background: #ffffff;
}

.box--content {
  box-sizing: content-box;
}
.box--border {
  box-sizing: content-box;
}

.box > h2 {
  margin-top: 0;
}
.note {
  color: #777777;
}

.order-note {
  color: #444444;
}
.order-note {
  color: #666666;
}

a {
  color: #444444;
}
a:focus-visible {
  outline: 3px solid #444444;
  outline-offset: 4px;
}

수정 방법

index.html

이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.

styles.css

styles.css에서 아래 차이가 있는 위치를 수정하세요. -는 삭제할 줄, +는 추가할 줄이며 표시는 실제 코드에 넣지 않습니다.

지정한 너비에 padding과 border가 포함되도록 박스 모델을 바꾸고 계산 결과를 확인합니다.

--- 수정 전/styles.css
+++ 수정 후/styles.css
@@ -26,11 +26,14 @@
   box-sizing: content-box;
 }
 .box--border {
-  box-sizing: content-box;
+  box-sizing: border-box;
 }
 
 .box > h2 {
   margin-top: 0;
+}
+.box .note {
+  color: #333333;
 }
 .note {
   color: #777777;

수정 후 탭의 전체 파일과 비교한 뒤 본문의 확인 절차를 실행하세요.

수정 후

index.html

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>CSS 박스와 우선순위 실습</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <h1>같은 width, 다른 박스 크기</h1>
      <p class="intro">글꼴과 기본 글자색은 body에서 상속받습니다.</p>
      <section class="box box--content" aria-labelledby="content-title">
        <h2 id="content-title">content-box</h2>
        <p class="note">
          테두리까지 276px입니다. <span>이 글자도 같은 색입니다.</span>
        </p>
      </section>
      <section class="box box--border" aria-labelledby="border-title">
        <h2 id="border-title">border-box</h2>
        <p class="note">
          테두리까지 240px입니다. <span>패딩도 그 안에 들어갑니다.</span>
        </p>
      </section>
      <p class="order-note">같은 선택자이면 나중에 작성한 색이 보입니다.</p>
      <a href="#content-title">첫 번째 박스로 이동</a>
    </main>
  </body>
</html>

styles.css

body {
  margin: 0;
  padding: 16px;
  font-family: system-ui, sans-serif;
  line-height: 1.6;
  color: #222222;
  background: #f5f5f5;
}

h1 {
  font-size: 1.6rem;
}
h2 {
  font-size: 1.2rem;
}

.box {
  width: 240px;
  padding: 16px;
  border: 2px solid #777777;
  margin: 16px 0;
  background: #ffffff;
}

.box--content {
  box-sizing: content-box;
}
.box--border {
  box-sizing: border-box;
}

.box > h2 {
  margin-top: 0;
}
.box .note {
  color: #333333;
}
.note {
  color: #777777;
}

.order-note {
  color: #444444;
}
.order-note {
  color: #666666;
}

a {
  color: #444444;
}
a:focus-visible {
  outline: 3px solid #444444;
  outline-offset: 4px;
}

index.html 전체 코드 보기

styles.css

styles.css 전체 코드 보기

starter에서 직접 바꿀 내용

  1. 두 번째 박스만 border-box로 바꾸고 실제 너비가 240px인지 확인하세요.
  2. 일반 .note 선언 앞에 .box .note의 color를 #333333으로 추가하고 어떤 색이 선택되는지 설명하세요.
  3. 두 .order-note 선언의 순서를 바꾸어 결과를 비교한 뒤 완성 코드 순서로 되돌리세요.

완성 파일과 비교하기 전에 위 확인 절차를 직접 수행하세요. 한 번에 한 속성 또는 한 구조만 바꾸고 화면이 달라지는 이유를 적으면 다음 문제에서도 원인을 찾기 쉽습니다.

이 글이 도움이 되었나요?

조회 중

웹 퍼블리싱 학습 순서

필수 13개 · 전체 15개

읽음 기록 관리

전체 과정 목차 (15개)
  1. 필수 학습 · HTML 입문: 시맨틱 문서와 접근 가능한 폼 만들기
  2. 필수 학습 · CSS 입문: 박스 모델·선택자·캐스케이드 직접 확인하기 현재 글
  3. 필수 학습 · CSS Flex와 미디어 쿼리 입문: 반응형 카드 페이지 만들기
  4. 필수 학습 · CSS position 완전 이해: relative·absolute·fixed·sticky 실습
  5. 필수 학습 · HTML details와 summary로 접근 가능한 FAQ 만들기
  6. 필수 학습 · CSS Grid 실습: Flex 학습 카드로 열 맞추기와 auto-fit 비교
  7. 필수 학습 · CSS overflow 해결: 긴 텍스트·min-width: 0·말줄임 실습
  8. 필수 학습 · HTML 표 만들기: caption·scope로 비교표를 읽기 쉽게, 모바일에서는 표만 스크롤하기
  9. 필수 선수 · HTML CSS 이미지 문제 해결 실습: 경로·비율·잘림·흐림·CLS
  10. 필수 학습 · Container Query 실습: 같은 카드를 본문과 사이드바에 배치하기
  11. 선택 참고 · CSS Baseline 보는 법: 지원 범위와 폴백을 직접 확인하기
  12. 필수 학습 · CSS z-index가 안 먹힐 때: stacking context와 부모 층 디버깅
  13. 필수 선수 · 웹 접근성 기초 점검: 키보드 순서·초점 표시·확대 화면을 직접 확인하는 체크리스트
  14. 필수 학습 · HTML CSS 종합 실습: 소개·카드·이미지·요금표·문의 폼·FAQ가 있는 반응형 서비스 페이지
  15. 선택 참고 · 프론트엔드 SEO 기초: HTML 구조와 이미지 성능 진단하기

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기