한 줄 요약 — 선택자는 CSS 규칙이 어떤 태그를 꾸밀지 가리키는 이름입니다. 태그 선택자(
h1)는 같은 종류 전체에, 클래스 선택자(.card)는 같은 유니폼을 입은 무리에, ID 선택자(#hero)는 한 페이지에 단 하나뿐인 그 자리에 적용됩니다. 셋이 같이 부딪치면 ID가 가장 강하고 그다음이 클래스, 마지막이 태그입니다.
학습 목표
- 태그·클래스·ID 선택자를 구분해 쓸 수 있다.
- 같은 디자인을 세 선택자로 똑같이 만들어 보고 차이를 설명할 수 있다.
- 한 태그에 클래스를 여러 개 붙이는 방법과, 그게 왜 유용한지 안다.
- 같은 자리에서 셋이 부딪칠 때 누가 이기는지 짐작할 수 있다.
- ID는 한 페이지에 한 번만 써야 한다는 규칙을 이유와 함께 안다.
오늘의 비유 — 종류, 유니폼, 그리고 이름표
학교 운동장을 떠올려 봅니다. 거기 모인 사람들을 부르는 방법은 세 가지입니다.
첫째, "학생"이라고 부릅니다. 운동장에 있는 학생 전부가 일제히 돌아봅니다. 한 명을 콕 집어 부른 것이 아니라 그 종류 전체를 부른 셈이라, 흰 셔츠를 입은 학생도, 파란 트랙복을 입은 학생도 같이 반응합니다.
둘째, "3반 학생들"처럼 같은 유니폼을 입은 무리를 부릅니다. 3반 표식이 들어간 옷을 입은 학생들만 골라 반응합니다. 종류는 같은 학생이지만, 표식이 있는 사람과 없는 사람이 갈립니다. 같은 학생이 동시에 "농구부 유니폼"과 "3반 표식" 두 개를 입고 있어도 자연스럽습니다.
셋째, "학생회장 김민지"라고 부릅니다. 그 자리에는 한 명뿐이라 누가 반응할지 헷갈릴 일이 없습니다. 같은 이름표가 두 명에게 동시에 붙어 있으면 운동장 전체가 혼란에 빠집니다.
CSS의 세 선택자가 그대로 이 셋입니다. 태그 선택자는 종류를 부릅니다 — h1을 가리키면 페이지 안의 모든 <h1>이 같이 반응합니다. 클래스 선택자는 유니폼을 부릅니다 — .card를 가리키면 class="card"라고 표식이 붙은 태그들만 반응합니다. ID 선택자는 이름표를 부릅니다 — #hero는 그 페이지의 단 한 자리에만 붙여 두는 표식입니다.
핵심 개념
지난 회차에서 CSS 규칙은 늘 선택자 { 속성: 값; }의 모양이라고 정리했습니다. 선택자 자리가 곧 "누구에게 입힐지"를 정하는 칸입니다. 같은 옷장에서 옷을 꺼내더라도 누구에게 입힐지에 따라 화면이 완전히 달라지므로, 선택자를 어떻게 적느냐가 사실상 CSS의 절반입니다.
태그 선택자 — 종류 전체에
태그 이름을 그대로 적습니다. 그 종류의 태그 모두가 한꺼번에 반응합니다.
h1 {
color: tomato;
}
p {
line-height: 1.7;
}
이 규칙은 페이지의 모든 <h1>을 토마토 색으로, 모든 <p>의 줄 간격을 1.7로 잡습니다. "이 종류는 기본적으로 이런 모양"이라고 한 번 정해 두기에 편합니다. 예를 들어 본문의 모든 문단이 같은 줄 간격을 갖길 원할 때, 태그 선택자 한 줄이면 충분합니다.
다만 "어떤 <h1>만"이나 "이 자리의 <h1>만"이라고 좁히지는 못합니다. 종류를 부르는 것이지 무리를 부르는 것이 아니기 때문입니다.
클래스 선택자 — 유니폼 입은 무리에
HTML 쪽에서 그 태그에 class="이름"을 달아 두고, CSS 쪽에서는 그 이름 앞에 점(.)을 붙여 가리킵니다.
<p class="lead">첫 줄에 살짝 강조하고 싶은 문단입니다.</p>
<p>이 문단은 보통 본문입니다.</p>
<p class="lead">여기도 살짝 강조하고 싶습니다.</p>
.lead {
font-size: 1.2rem;
color: navy;
}
class="lead"가 붙은 두 문단만 1.2rem 크기에 남색이 되고, 나머지 문단은 본문 그대로 남습니다. 같은 종류(<p>) 안에서 일부만 골라 다른 옷을 입힌 셈입니다.
한 태그에 클래스를 여러 개 붙일 수 있습니다. 띄어쓰기로 구분합니다.
<button class="btn btn-primary">저장</button>
<button class="btn btn-secondary">취소</button>
.btn {
padding: 8px 16px;
border-radius: 6px;
border: 0;
}
.btn-primary {
background: royalblue;
color: white;
}
.btn-secondary {
background: #eee;
color: #333;
}
두 버튼 모두 .btn의 규칙(여백·둥근 모서리·테두리 없음)을 공통으로 받고, 거기에 각자 다른 색 유니폼을 한 벌씩 더 입었습니다. 농구부 유니폼과 3반 표식을 같이 단 학생을 떠올리면 자연스럽습니다.
ID 선택자 — 한 자리에만 붙는 이름표
HTML 쪽에서 그 태그에 id="이름"을 달아 두고, CSS 쪽에서는 그 이름 앞에 우물 정(#)을 붙여 가리킵니다.
<header id="site-header">
<h1>Life is One Coin</h1>
</header>
#site-header {
background: black;
color: white;
padding: 16px;
}
같은 페이지 안에 id="site-header"는 단 한 번만 쓸 수 있습니다. 이름표는 그 자리에 한 명뿐이라는 약속이기 때문입니다. 그래서 ID는 "이 페이지의 그 한 자리"를 가리킬 때만 씁니다.
셋이 같은 자리에서 부딪치면
같은 태그를 향해 세 선택자가 동시에 다른 색을 지정하면, 화면에는 단 하나만 나타납니다. 우선순위는 다음 순서입니다.
- ID 선택자 (
#hero) — 가장 강합니다. - 클래스 선택자 (
.card) — 그다음입니다. - 태그 선택자 (
h1) — 가장 약합니다.
이 순서가 절대인 것은 아니지만(다음 회차의 "명시도"가 이 정확한 계산법을 다룹니다), 오늘은 "이름표가 유니폼을 이기고, 유니폼이 종류를 이긴다" 정도로 기억해 두면 됩니다.
함께 따라하기 — 같은 카드를 세 방식으로 꾸며 보기
day-13 폴더를 만들고 그 안에 index.html과 style.css 두 파일을 둡니다. 같은 모양의 카드 세 장을, 한 번은 태그로, 한 번은 클래스로, 한 번은 ID로 꾸며 봅니다.
<!-- index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>CSS 선택자 기초</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<article>
<h2>태그로만 꾸민 카드</h2>
<p>이 페이지의 모든 article이 같은 모양이 됩니다.</p>
</article>
<article class="card">
<h2>클래스로 꾸민 카드</h2>
<p>class="card"가 붙은 article만 이 옷을 입습니다.</p>
</article>
<article id="hero" class="card">
<h2>ID로 한 번 더 짚어 준 카드</h2>
<p>이 페이지에 단 하나뿐인 자리입니다.</p>
</article>
</body>
</html>
/* style.css */
article {
padding: 16px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
.card {
background: #f6f8ff;
border-color: royalblue;
}
#hero {
background: navy;
color: white;
}
저장하고 브라우저로 열어 봅니다. 첫 카드는 흰 바탕에 회색 테두리(태그 선택자만 적용), 두 번째 카드는 연한 파란 바탕에 파란 테두리(태그 + 클래스), 세 번째 카드는 짙은 남색 바탕에 흰 글자(태그 + 클래스 + ID)로 보입니다.
세 번째 카드에는 .card와 #hero 두 옷이 같이 걸려 있는데, 바탕색이 남색으로 보이는 이유는 ID가 클래스보다 강하기 때문입니다. #hero { background: navy; } 한 줄을 잠깐 지워 보면 세 번째 카드도 연한 파란 바탕으로 돌아옵니다. 그 자리에 남은 옷이 .card뿐이라 그 옷이 보이는 셈입니다.
흔한 실수 3가지
1. 한 페이지 안에서 같은 ID를 여러 곳에 쓴다
같은 이름표를 두 학생에게 동시에 붙인 운동장과 같습니다.
<section id="pricing">…</section>
<section id="pricing">…</section>
(이 코드는 첫 번째 #pricing까지만 정상으로 동작하고 두 번째부터는 행동이 어긋납니다.) HTML 표준은 같은 페이지에서 id 값을 단 한 번만 쓰도록 정해 두었습니다. 단순히 CSS만의 문제가 아니라, 본문 안 링크(<a href="#pricing">)나 자바스크립트 코드도 모두 "그 자리에 단 하나"라는 약속에 기대고 있어서, 같은 ID가 두 개면 어디로 갈지 약속을 어기는 셈이 됩니다.
<section class="pricing">…</section>
<section class="pricing">…</section>
여럿이 같은 옷을 입는 자리에는 ID 대신 클래스를 씁니다. 이름표는 한 명에게만, 유니폼은 무리에게 — 이 원칙을 그대로 따르면 헷갈릴 일이 없습니다.
2. 모든 스타일을 태그 선택자로 적어 재사용을 망친다
태그 선택자가 익숙해지면 모든 디자인을 태그 단위로 적는 버릇이 생깁니다.
article {
background: #f6f8ff;
border: 1px solid royalblue;
padding: 16px;
}
(이 코드는 페이지에 있는 모든 <article>을 한 가지 모양으로 묶어 버립니다.) 한 페이지에 카드 모양 <article>과 그냥 글 모양 <article>이 같이 있어야 한다면 곤란합니다. 종류 전체에 옷을 입혀 둔 탓에 그중 일부만 다른 옷으로 바꿀 길이 없습니다.
.card {
background: #f6f8ff;
border: 1px solid royalblue;
padding: 16px;
}
<article class="card">…</article>
<article>…</article>
class="card"를 붙인 것만 카드 모양으로, 나머지 <article>은 본래 모습대로 남습니다. "같은 옷을 입는 무리"를 클래스로 묶어 두는 습관을 들이면, 나중에 그 옷만 바꾸거나 다른 자리에도 그대로 입히기가 쉽습니다.
3. .card .header에서 띄어쓰기를 빼 .card.header로 만든다
띄어쓰기 한 칸이 의미를 완전히 바꿉니다.
.card .header {
font-weight: bold;
}
이 코드는 ".card 안에 있는 .header"를 가리킵니다. 즉 다음 HTML에서 <h3 class="header">가 바깥쪽 .card의 자손이라서 굵게 표시됩니다.
<article class="card">
<h3 class="header">소개</h3>
</article>
같은 페이지에 띄어쓰기를 빼고 적으면 의미가 완전히 달라집니다.
.card.header {
font-weight: bold;
}
(이 코드는 같은 태그가 card와 header 두 유니폼을 동시에 입고 있을 때만 동작합니다.) 위의 HTML에서는 한 태그가 두 클래스를 같이 단 자리가 없으므로 아무 데도 적용되지 않습니다.
<article class="card header">…</article>
이렇게 한 태그에 두 옷을 같이 입혀 두어야 비로소 .card.header가 그 자리를 가리키게 됩니다. 띄어쓰기 한 칸이 "안에 있는"(자손)인지 "같이 입은"(결합)인지를 가르는 결정타이니, 적을 때 한 번 더 들여다봅니다. 자손 선택자의 자세한 결합 방법은 다음 회차에서 따로 다룹니다.
오늘 배운 것 체크리스트
- 태그·클래스·ID 세 선택자의 적는 모양과 의미를 구분할 수 있다.
- 한 태그에 클래스를 여러 개 띄어쓰기로 붙일 수 있다.
- 같은 자리에서 셋이 부딪치면 ID가 가장 강하다는 것을 안다.
- ID는 한 페이지에 한 번만 쓴다는 규칙을 그 이유와 함께 안다.
-
.a .b(자손)와.a.b(결합)의 띄어쓰기 차이를 의식한다.
자주 묻는 질문
Q. 클래스와 ID의 차이가 정확히 무엇인가요?
A. 둘 다 태그에 표식을 붙여 두는 방법이라는 점은 같습니다만, 클래스는 같은 표식을 여러 자리에 붙일 수 있고, ID는 한 페이지에 한 번만 붙일 수 있습니다. CSS 우선순위도 ID가 더 강합니다. 표식이 여럿일 수 있는 유니폼이 클래스, 그 자리에 단 하나뿐인 이름표가 ID라고 생각하면 헷갈리지 않습니다.
Q. 한 태그에 클래스를 여러 개 동시에 줘도 되나요?
A. 됩니다. class="btn btn-primary"처럼 띄어쓰기로 나열하면 됩니다. 공통 모양은 .btn에, 변종 모양은 .btn-primary에 적는 식으로 나누면, 새 변종이 생길 때 공통 부분을 그대로 두고 차이만 새 클래스로 추가할 수 있어 편합니다.
Q. 선택자 우선순위는 ID > 클래스 > 태그가 절대 법칙인가요?
A. 큰 그림으로는 맞습니다만, 정확한 계산은 다음 회차의 "명시도(specificity)"에서 다룹니다. 예를 들어 클래스를 두 번 겹쳐 적은 선택자(.card.featured)는 클래스 하나짜리(.card)보다 강합니다. 오늘은 이름표가 유니폼을 이기고, 유니폼이 종류를 이긴다 정도로 기억해 두면 충분합니다.
다음 시간 예고
내일은 **결합 선택자와 가상 클래스 — >, +, ~, :hover, :focus, :nth-child**를 다룹니다. 오늘은 같은 종류 전체 또는 같은 표식을 단 무리만 부를 수 있었다면, 내일은 "이 카드 바로 안의 제목만"이나 "마우스를 올렸을 때만"처럼 자리와 상태로 더 좁혀 부르는 법을 배웁니다.