Skip to Content

이번 문서의 목표: 이 문서를 다 읽으면 CSS 규칙의 문법 요소를 정확히 구분하고, 태그·클래스·아이디·속성·의사 클래스 선택자를 상황에 맞게 고르며, 결합자(combinator)로 요소 간 관계를 표현하고, 우선순위(cascade)와 상속(inheritance)의 기본 판단 순서를 설명할 수 있게 됩니다.

CSS는 왜 필요한가

쉽게 말하면: HTML이 “무엇이 있는가”를 정하는 언어라면, CSS는 “그것이 어떻게 보이는가”를 정하는 언어입니다.

03~05편에서 다룬 HTML은 문서의 구조와 의미를 담당합니다. 제목이 어디부터 어디까지인지, 어떤 부분이 표이고 어떤 부분이 폼인지 같은 정보입니다. 그런데 HTML만으로 페이지를 만들면 모든 브라우저의 기본 스타일(제목은 크고 굵게, 링크는 파란 밑줄 등)만 적용되어 밋밋합니다. CSS(Cascading Style Sheets, 캐스케이딩 스타일 시트)는 이 구조 위에 색상·글꼴·간격·배치 같은 표현(presentation)을 입히는 언어입니다. “캐스케이딩(cascading)“이라는 이름 자체가 “위에서 아래로 흘러내리며 규칙이 겹쳐 적용된다”는 CSS의 핵심 동작 방식을 가리키는데, 이 흘러내림의 규칙을 뒤에서 자세히 다룹니다.

CSS 문법의 구성 요소

CSS 규칙 하나는 다음과 같은 조각들로 이루어집니다.

p { color: blue; font-size: 16px; }
조각이름(영단어)역할
p선택자(selector)스타일을 적용할 대상을 지정
{ ... }선언 블록(declaration block)적용할 스타일들을 담는 중괄호 묶음
color: blue;선언(declaration)속성과 값을 콜론으로 짝지은 한 줄
color속성(property)무엇을 바꿀지(색상, 크기 등)
blue값(value)속성을 어떤 값으로 바꿀지
;세미콜론선언과 선언을 구분하는 구분자

이 구조를 통틀어 p { color: blue; font-size: 16px; } 전체를 규칙(rule) 또는 규칙 집합(ruleset)이라고 부릅니다. 시험에서 “선택자와 선언의 위치를 바르게 짝지은 것은?”류의 문제가 나오면, 중괄호 앞이 선택자, 안이 선언들이라는 위치 관계를 정확히 짚어야 합니다.

자주 틀리는 점: 마지막 선언 뒤의 세미콜론은 생략해도 문법 오류가 나지 않지만, 습관적으로 붙이는 것이 안전합니다. 선언 사이의 세미콜론을 빠뜨리면 그 뒤의 속성과 값이 앞의 값과 합쳐져 해석되어 스타일이 깨지는 원인이 됩니다.

CSS를 HTML에 적용하는 세 가지 방법

CSS를 문서에 연결하는 방법은 세 가지이며, 이 방법 자체가 뒤에서 다룰 우선순위 계산에 영향을 줍니다.

방법작성 위치예시
인라인(inline) 스타일태그의 style 속성 안<p style="color: red;">글자</p>
내부(internal) 스타일시트head 안의 style 태그<style>p { color: red; }</style>
외부(external) 스타일시트별도 .css 파일을 link로 연결<link rel="stylesheet" href="styles.css" />

실무와 시험 모두에서 외부 스타일시트를 가장 권장하는데, 이유는 여러 HTML 문서가 하나의 .css 파일을 공유해 유지보수가 쉽고 캐싱으로 성능도 유리하기 때문입니다. 인라인 스타일은 뒤에서 다룰 우선순위 계산에서 특별히 강한 위치를 차지하지만, 그만큼 재사용이 어렵고 유지보수를 어렵게 만들어 시험에서도 “권장하지 않는 방식”으로 자주 다뤄집니다.

선택자(selector)의 종류

쉽게 말하면: 선택자는 “이 스타일을 누구에게 적용할지” 고르는 규칙입니다.

선택자는 독학사 CSS 파트에서 가장 비중이 큰 주제입니다. 종류별로 정확히 구분해 봅니다.

선택자 종류문법 예시대상
전체(universal)*문서의 모든 요소
타입(type/element)p, div해당 태그 이름을 가진 모든 요소
클래스(class).introclass="intro"를 가진 모든 요소
아이디(ID)#headerid="header"를 가진 단 하나의 요소
속성(attribute)[type="text"]해당 속성·값을 가진 요소
그룹(grouping)h1, h2, h3쉼표로 나열된 여러 선택자를 동시에 적용

클래스와 아이디의 차이는 시험에 반드시 나옵니다. HTML 문서 안에서 같은 class 값은 여러 요소에 중복해서 붙일 수 있지만, id 값은 한 문서 안에서 유일해야 한다는 규칙이 있습니다(02편에서 언급한 속성 규칙과 연결됩니다). 그래서 클래스는 “같은 스타일을 여러 곳에 재사용”하는 데, 아이디는 “문서 안에서 딱 하나뿐인 특정 요소를 정확히 지목”하는 데 쓰입니다. 뒤에서 다룰 우선순위에서도 아이디 선택자가 클래스 선택자보다 강하다는 규칙이 이 “유일성” 성격과 맞물립니다.

* { margin: 0; } /* 전체 선택자 */ p { line-height: 1.6; } /* 타입 선택자 */ .badge { color: white; } /* 클래스 선택자 */ #main-title { font-size: 2rem; } /* 아이디 선택자 */ input[type="email"] { border-color: green; } /* 속성 선택자 */ h1, h2, h3 { font-weight: bold; } /* 그룹 선택자 */

의사 클래스(pseudo-class)와 의사 요소(pseudo-element)

의사(pseudo, “가짜”라는 뜻의 접두사)라는 이름이 붙은 이유는, 이 선택자들이 HTML에 실제로 존재하는 클래스나 요소가 아니라 상태나 위치를 기준으로 CSS가 가상으로 만들어내는 대상을 가리키기 때문입니다.

구분예시
의사 클래스a:hover마우스를 올린 상태의 링크
의사 클래스input:focus초점을 받은 상태의 입력란
의사 클래스li:first-child부모의 첫 번째 자식인 li
의사 요소p::first-line문단의 첫 줄(실제 태그가 아님)
의사 요소.box::before요소 콘텐츠 앞에 가상으로 삽입되는 위치

의사 클래스는 콜론 하나(:), 의사 요소는 콜론 두 개(::)로 표기하는 것이 현재 표준(CSS3 이후)입니다. 다만 :before, :after처럼 콜론 하나로 쓴 오래된 표기도 하위 호환을 위해 여전히 동작합니다. 시험에서 “의사 클래스와 의사 요소를 콜론 개수로 구분하는 기준”을 물으면, 상태·위치 판별이면 의사 클래스, 실제 존재하지 않는 콘텐츠 조각을 가리키면 의사 요소라는 성격 차이로 접근하는 것이 안전합니다.

결합자(combinator) — 요소 간 관계 표현

쉽게 말하면: 결합자는 “이 선택자와 저 선택자가 어떤 위치 관계에 있을 때만 적용할지” 연결하는 기호입니다.

결합자기호예시대상
자손(descendant)공백nav anav 안에 있는 모든 깊이의 a
자식(child)>nav > anav의 바로 아래 자식인 a만
인접 형제(adjacent sibling)+h2 + ph2 바로 다음에 오는 형제 p 하나
일반 형제(general sibling)~h2 ~ ph2 뒤에 오는 모든 형제 p

자손 결합자와 자식 결합자의 차이가 시험에서 특히 자주 나옵니다. nav a(자손)는 nav 안에 a가 몇 단계 깊이 중첩되어 있든 전부 선택하지만, nav > a(자식)는 nav 바로 아래 한 단계에 있는 a만 선택합니다.

<nav> <a href="#">1단계 링크</a> <ul> <li><a href="#">2단계 링크</a></li> </ul> </nav>
nav a { color: blue; } /* 1단계 링크와 2단계 링크 모두 파란색 */ nav > a { color: red; } /* 1단계 링크만 빨간색, 2단계 링크는 영향 없음 */

인접 형제(+)와 일반 형제(~)의 차이도 마찬가지로 “바로 다음 하나만”과 “뒤에 오는 전부”의 차이입니다. h2 + ph2 바로 뒤에 붙어 있는 문단 딱 하나에만 적용되지만, h2 ~ p는 그 h2와 같은 부모를 공유하며 뒤에 나오는 모든 p에 적용됩니다.

자주 틀리는 점: 표 셀 등에서 이 기호들을 다룰 때 물결표(~)를 범위 표시(예: “0~10”)로 착각해 헷갈리는 경우가 있는데, CSS에서 ~는 항상 일반 형제 결합자를 뜻하는 문법 기호입니다. 숫자 범위의 물결표와는 전혀 다른 용도입니다.

우선순위(cascade)와 상속(inheritance)의 시작점

쉽게 말하면: 여러 규칙이 같은 요소를 노리고 충돌할 때 “누가 이길지” 정하는 것이 캐스케이드(cascade)이고, 부모의 스타일이 자식에게 자동으로 넘어가는 것이 상속(inheritance)입니다.

같은 요소에 서로 다른 값을 주는 규칙이 동시에 걸리는 상황은 실제 CSS 작업에서 매우 흔합니다.

p { color: black; } .notice { color: red; } #warning { color: orange; }
<p id="warning" class="notice">이 문단은 무슨 색일까?</p>

이 문단은 세 규칙이 모두 대상이 되지만 결과는 주황색입니다. 브라우저가 충돌하는 규칙 중 하나를 고르는 판단 기준을 명시도(specificity)라고 부릅니다. 명시도는 선택자를 이루는 요소를 세 자리 숫자 튜플 (b, c, d)로 환산해 비교하는 방식으로 계산합니다.

자리세는 대상
b아이디 선택자 개수
c클래스·속성·의사 클래스 선택자 개수
d타입(태그) 선택자·의사 요소 개수

비교는 왼쪽 자리부터 합니다. b 자리 값이 큰 쪽이 다른 자리를 볼 것도 없이 무조건 이기고, b가 같으면 c를 비교하고, c도 같으면 d를 비교합니다. 앞서 예시로 든 세 선택자를 계산해 보면 다음과 같습니다.

p(0,0,1)\text{p} \rightarrow (0, 0, 1)
  • b=0(아이디 없음), c=0(클래스 없음), d=1(타입 선택자 p 1개)
.notice(0,1,0)\text{.notice} \rightarrow (0, 1, 0)
  • b=0, c=1(클래스 1개), d=0
#warning(1,0,0)\text{\#warning} \rightarrow (1, 0, 0)
  • b=1(아이디 1개), c=0, d=0

#warning의 b 자리가 1로 나머지 둘의 0보다 크므로, c·d 자리를 비교할 필요도 없이 #warning이 이겨 문단이 주황색이 됩니다. 결합자(>, +, ~, 공백)는 관계만 표현할 뿐 어떤 자리에도 점수를 더하지 않는다는 점도 함정으로 자주 나옵니다.

명시도가 완전히 같은 두 규칙이 충돌하면 소스 순서(source order), 즉 스타일시트에서 더 나중에 나온 규칙이 이깁니다. 그리고 이 모든 계산 위에 예외적으로 군림하는 두 가지가 있습니다. 인라인 스타일(style 속성)은 선택자 튜플 계산에 아예 들어가지 않는 별도의 최상위 등급으로 취급되어 어떤 선택자 기반 규칙보다도 강하며, 선언 끝에 !important를 붙인 규칙은 인라인 스타일까지 포함해 그 무엇보다도 강하게 적용됩니다. 다만 !important는 나중에 유지보수를 어렵게 만들기 쉬워 남용하지 않는 것이 원칙이라는 점도 함께 기억해 둘 필요가 있습니다.

지금까지의 내용을 우선순위가 낮은 것부터 높은 순으로 정리하면 다음과 같습니다.

타입 선택자 < 클래스·속성·의사 클래스 < 아이디 선택자 < 인라인 스타일 < !important

상속(inheritance)은 우선순위와는 별개의 개념입니다. 일부 CSS 속성(주로 글자와 관련된 color, font-family, font-size, line-height 등)은 부모 요소에 지정하면 자식 요소에도 별도로 지정하지 않는 한 자동으로 같은 값이 적용됩니다.

body { color: darkslategray; font-family: sans-serif; }

이렇게만 지정해도 body 안의 모든 p, span, li 등이 별도 지정 없이 같은 글자색·글꼴을 물려받습니다. 반대로 margin, padding, border, width 같은 박스 관련 속성은 기본적으로 상속되지 않습니다. 이는 각 요소가 자신만의 박스 크기와 여백을 가지는 것이 자연스럽기 때문입니다(이 박스 개념은 07편에서 본격적으로 다룹니다). “특정 속성이 상속되는지 여부”를 묻는 문제는 결국 “그 속성이 글자에 관한 것인가, 박스 배치에 관한 것인가”로 큰 틀에서 접근하면 대부분 맞힐 수 있습니다.

<link rel="stylesheet" href="styles.css" />
<nav>
<a href="#" class="notice">1단계 링크</a>
<ul>
  <li><a href="#" id="warning" class="notice">2단계 링크</a></li>
</ul>
</nav>
<p>일반 문단은 상속받은 색만 적용됩니다.</p>

핵심 정리

  • CSS 규칙은 선택자 + 선언 블록(속성: 값; 쌍들)으로 구성되며, 적용 방법은 인라인·내부·외부 세 가지다. 외부 스타일시트가 유지보수·재사용에 가장 유리하다.
  • 타입·클래스·아이디·속성·그룹 선택자는 각각 대상 범위가 다르며, 아이디는 문서 안에서 유일해야 한다.
  • 의사 클래스(콜론 하나, 상태·위치)와 의사 요소(콜론 둘, 가상의 콘텐츠 조각)는 성격이 다르다.
  • 자손(공백)·자식(>)·인접 형제(+)·일반 형제(~) 결합자는 요소 간 위치 관계로 대상을 좁힌다.
  • 캐스케이드는 충돌하는 규칙 중 하나를 명시도로 결정하며 대략 아이디 > 클래스류 > 타입 순이다. 상속은 우선순위와 별개로, 주로 글자 관련 속성이 부모에서 자식으로 자동 전달되는 것이다.

마무리 복습

문제 14지선다
다음 규칙에서 color는 무엇에 해당하는가?
p {
  color: blue;
  font-size: 16px;
}
문제 24지선다
클래스 선택자와 아이디 선택자의 차이로 옳은 것은?
문제 34지선다
nav a와 nav > a의 차이를 옳게 설명한 것은?
문제 44지선다
h2 + p와 h2 ~ p의 차이로 옳은 것은?
문제 54지선다
의사 클래스와 의사 요소를 구분하는 표준 표기 방식으로 옳은 것은?
문제 64지선다
다음 중 캐스케이드(우선순위) 판단의 큰 흐름으로 옳은 것은?
문제 74지선다
다음 중 부모에서 자식으로 기본적으로 상속되는 속성으로 옳은 것은?

참고 자료

Last updated on