Selectors/Selectors and combinators

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
145/190

안녕하세요! 프론트엔드 강사입니다.

오늘은 CSS의 시작이자 끝이라고 할 수 있는 '선택자(Selectors)''결합자(Combinators)'에 대해 MDN 공식 문서를 통해 완벽하게 정리해 보겠습니다. HTML 요소들을 예쁘게 꾸미려면 먼저 "누구를 꾸밀 것인가?"를 정확하게 콕 집어낼 수 있어야 하겠죠? 이 문서를 다 읽고 나면 복잡한 HTML 구조 속에서도 내가 원하는 요소만 귀신같이 찾아내는 CSS 명사수가 되실 수 있을 겁니다.

제 실무 경험을 담은 꿀팁들도 가득 준비했으니 재미있게 따라와 주세요!


CSS 선택자와 결합자 (CSS selectors and combinators)

CSS 선택자(selectors)는 여러분이 CSS 규칙(스타일)을 적용하고 싶은 요소들의 패턴을 정의하는 데 사용됩니다. 결합자(combinators)는 이러한 선택자들 사이의 관계를 정의하죠. 다양한 선택자와 결합자를 조합하면, 요소의 타입, 속성, 상태, 또는 다른 요소와의 관계를 기반으로 여러분이 원하는 요소를 아주 정밀하게 선택하고 스타일을 입힐 수 있습니다.


이 문서의 목차 (In this article)


선택자의 종류 (Types of selectors)

CSS에는 무려 80개가 넘는 선택자와 결합자가 존재합니다! 선택할 수 있는 요소의 종류에 따라 다음과 같은 카테고리로 묶어볼 수 있습니다.

기본 선택자 (Basic selectors)

  • 타입 선택자 (Type selector): 주어진 노드 이름(태그 이름)을 가진 모든 요소를 선택합니다. 예를 들어, div는 모든 <div> 요소를 선택하고, input은 모든 <input> 요소를 선택합니다.
  • 전체 선택자 (Universal selector): 별표(*)로 표시하며, 문서 내의 모든 요소를 선택하는 특별한 타입 선택자입니다.
  • 클래스 선택자 (Class selector): 마침표(.)를 앞에 붙여서 특정 class 속성을 가진 모든 요소를 선택합니다. 예를 들어, .indexclass="index"를 가진 모든 요소와 일치합니다.
  • ID 선택자 (ID selector): 우물 정자(#, 해시 기호)를 앞에 붙여서 특정 id 속성값을 가진 단 하나의 요소를 선택합니다. 예를 들어, #tocid="toc"를 가진 요소와 일치합니다.

classid는 모두 전역 속성(global attributes)입니다. 한 문서 안에서 동일한 id를 가진 요소는 딱 하나만 존재해야 합니다. (하지만 만약 실수로 여러 개를 만들었다 하더라도, CSS의 ID 선택자는 그 id를 가진 모든 요소를 선택하긴 합니다.)

타입 선택자나 전체 선택자를 클래스나 ID 선택자와 결합하여 복합 선택자(compound selector)를 만들 때는, 반드시 타입/전체 선택자가 클래스나 ID보다 먼저 와야 합니다 (예: p.myClass).

👨‍🏫 강사님의 꿀팁:
실무에서는 * (전체 선택자)를 사용할 때 주의해야 합니다! 모든 요소를 훑어야 하므로 브라우저 렌더링 성능을 떨어뜨릴 수 있거든요. 주로 box-sizing: border-box; 같은 전역 초기화 설정을 할 때만 제한적으로 쓰는 것이 좋습니다.

CSS

이 예제에서는 위에서 설명한 4가지 기본 선택자 타입을 사용해 4개의 단순 선택자(simple selectors)와 1개의 복합 선택자(compound selector)를 선언합니다.

* {
  font-style: italic; /* 문서의 모든 글씨를 기울입니다 */
}
p {
  color: red; /* 모든 p 태그 글씨를 빨갛게 만듭니다 */
}
.myClass {
  text-decoration: underline; /* myClass를 가진 요소에 밑줄을 긋습니다 */
}
#myId {
  font-family: monospace; /* myId를 가진 요소의 폰트를 바꿉니다 */
}
p.myClass#myId {
  font-size: 1.5rem; /* p태그이면서 클래스가 myClass이고 아이디가 myId인 녀석만 글씨를 키웁니다! */
}

HTML

<p class="myClass" id="myId">I match everything.</p>
<p>I match the universal and type selectors only.</p>

결과 (Result)


결합자 (Combinators)

단일 선택자만으로는 원하는 요소를 정확히 짚어내기 어려울 때가 많습니다. 이때 CSS 결합자를 사용하면, 문서 노드 트리 내에서 다른 요소와의 관계(Relationship)를 기반으로 요소를 선택할 수 있습니다. 결합자를 통해 선택자들을 엮어놓은 것을 복잡한 선택자(complex selectors)라고 부릅니다.

자손 결합자 (Descendant combinator)

[공백(space)] 으로 표시합니다. 첫 번째 요소의 '자손'인 모든 노드를 선택합니다. 자식이든, 손자든, 증손자든 그 안에 포함되어 있기만 하면 다 찾아냅니다.

  • 예시: div span<div> 요소 내부에 있는 모든 <span> 요소를 선택합니다.

자식 결합자 (Child combinator)

> (크다 기호)로 표시합니다. 자손 결합자보다 훨씬 까다롭습니다. 오직 첫 번째 요소의 '직계 자식(바로 한 단계 아래)'인 노드만 선택합니다.

  • 예시: div > span<div>직접적인 자식<span> 요소만 선택합니다. div 안의 p 안에 있는 span은 선택되지 않아요!

일반 형제 결합자 (Subsequent-sibling combinator)

~ (물결표)로 표시합니다. 부모에서 자식으로 내려가는 게 아니라, 같은 부모를 가진 '형제(sibling)' 요소들을 찾을 때 씁니다. A ~ B라고 적으면, A 요소 뒤에 따라오는 모든 B 요소를 선택합니다 (바로 뒤에 붙어있지 않아도 됩니다).

  • 예시: h2 ~ p<h2> 뒤에 나오는 모든 <p> 요소를 선택합니다.

인접 형제 결합자 (Next-sibling combinator)

+ (더하기 기호)로 표시합니다. 일반 형제 결합자와 비슷하지만, 훨씬 엄격합니다. A + BA 요소 바로 직후에 딱 붙어서 나오는 B 요소 단 하나만 선택합니다.

  • 예시: h2 + p<h2> 요소 바로 다음에 딱 붙어있는 첫 번째 <p> 요소만 선택합니다.

👨‍🏫 강사님의 꿀팁:
+ 결합자는 실무에서 폼(Form) 유효성 검사할 때 정말 자주 씁니다!
input:invalid + .error-msg { display: block; } 처럼 써서, input에 잘못된 값이 들어가면 그 바로 밑에 있는 에러 메시지만 딱 나타나게 하는 마법 같은 코드를 짤 수 있답니다.

열(Column) 결합자 및 네임스페이스(Namespace) 구분자

  • || (이중 파이프): 특정 열(column)에 속한 노드를 선택할 때 씁니다. (예: col || td)
  • | (단일 파이프): XML 기반 문서(SVG, MathML 등)에서 특정 네임스페이스 안에 있는 요소만 선택할 때 사용합니다. 일반적인 웹 개발에서는 자주 쓰이지 않습니다.

CSS

다양한 결합자를 조합한 예제를 살펴봅시다.

h2 + p ~ p {
  font-style: italic; /* h2 바로 다음 p, 그 뒤에 나오는 p들을 기울입니다 */
}
h2 + p + p {
  color: red; /* h2 다음 p, 그다음 바로 붙어있는 p를 빨갛게 합니다 */
}
.myClass + p {
  text-decoration: underline;
}
#myId > .myClass {
  outline: 3px dashed red; /* #myId의 직계 자식 중 .myClass만 선택! */
}
* > p {
  font-size: 1.1rem;
}

HTML

<h2 class="myClass" id="myId">
  No selectors match. <span class="myClass">This span has an outline</span> as it is both myClass and a child of #myId.
</h2>
<p>The first paragraph is underlined. All the paragraphs are 1.1rem.</p>
<p>The second paragraph is red. This and the following paragraphs are italic.</p>
<p>The third paragraph is NOT red. It is italic and 1.1rem.</p>
<p class="myClass">Does not have an outline; this is a sibling of H2, not a child.</p>

결과 (Result)


CSS 중첩(Nesting)을 사용한 복잡한 선택자 만들기

방금 위에서 본 복잡한 결합자들은 최신 스펙인 CSS 중첩 (CSS nesting)을 사용하면 훨씬 읽기 쉽고 구조적으로 작성할 수 있습니다. (Sass나 SCSS를 써보신 분들에겐 매우 익숙할 거예요!)

CSS

위의 코드를 네이티브 CSS Nesting 기법을 사용해서 다시 작성해 보았습니다. 기능은 100% 동일하지만 코드가 부모-자식 관계로 예쁘게 묶인 걸 볼 수 있습니다.

h2 {
  & + p {
    & ~ p {
      font-style: italic;
    }
    & + p {
      color: red;
    }
  }
}
.myClass {
  & + p {
    text-decoration: underline;
  }
}
#myId {
  & > .myClass {
    outline: 3px dashed red;
  }
}
* {
  & > p {
    font-size: 1.1rem;
  }
}

결과 (Result)


속성 선택자 (Attribute selectors)

속성 선택자(Attribute selectors)는 태그 이름이나 클래스가 아니라, 요소가 가진 특정 HTML 속성(attribute)이나 그 속성의 값을 기준으로 요소를 쏙쏙 골라냅니다. 대괄호 [] 안에 작성합니다.

  • [type]: type이라는 속성을 가지기만 하면 무조건 선택합니다 (값이 뭐든 상관없음).
  • [type="submit"]: type 속성값이 정확히 "submit"인 요소만 선택합니다.

속성값의 대소문자 구분은 언어의 특성에 따라 다릅니다. 일반적인 HTML에서는 열거형(enumerated) 속성의 경우 대소문자를 구분하지 않지만, class, id, data-* 속성 등은 철저하게 대소문자를 구분합니다. 만약 대소문자를 무시하고 싶다면 선택자 끝에 i 식별자를 붙여주면 됩니다 (예: [class*="btn" i]).

👨‍🏫 강사님의 꿀팁:
이 기능은 특정 링크만 골라낼 때 최고입니다!
외부로 나가는 링크 아이콘을 달고 싶다? a[href^="http"] (href가 http로 시작하는 a 태그)를 쓰시면 되고요,
PDF 다운로드 링크를 빨갛게 칠하고 싶다? a[href$=".pdf"] (href가 .pdf로 끝나는 a 태그)를 쓰시면 됩니다. 정규표현식 같아서 정말 유용해요!


가상 클래스 선택자 (Pseudo-class selectors)

가상 클래스(Pseudo-classes)는 문서 트리(HTML)에는 존재하지 않지만, 브라우저가 알고 있는 요소의 특정 '상태(state)'를 기반으로 스타일을 입힐 때 씁니다. 콜론(:) 하나를 접두사로 사용합니다.

  • 예시: 사용자가 링크를 클릭한 적이 있는지(:visited), 요소에 마우스를 올렸는지(:hover), 체크박스에 체크가 되었는지(:checked) 등을 감지해서 스타일을 바꿀 수 있습니다.

가상 클래스는 표시 상태, 사용자 입력, 시간 차원, DOM 트리 구조 등 다양한 카테고리로 나뉘며, 무려 60개가 넘게 존재합니다! 여러 가상 클래스를 조합할 수도 있으며(a:hover:visited), 타입 선택자나 클래스 뒤에 붙여서 사용합니다.


가상 요소 선택자 (Pseudo-element selectors)

가상 요소(Pseudo-elements)는 아예 HTML에 존재하지 않는 새로운 가짜 요소(entity)를 CSS를 통해 화면에 만들어 내거나, 요소의 아주 특정한 일부(첫 글자, 첫 줄 등)만을 선택할 때 사용합니다. 콜론 두 개(::)를 접두사로 사용합니다.

  • 예시: 리스트의 마커(글머리 기호)를 가리키는 ::marker, 문단의 첫 번째 줄만 가리키는 ::first-line, 혹은 빈 공간을 만들어 아이콘을 넣을 수 있는 ::before, ::after 등이 있습니다.

👨‍🏫 강사님의 꿀팁:
:hover (마우스 오버 상태)는 가상 클래스(Class)이므로 콜론 1개!
::before (새로 만들어낸 가짜 박스)는 가상 요소(Element)이므로 콜론 2개!
이 차이점을 묻는 질문이 프론트엔드 면접에서 꽤 자주 나오니 꼭 구분해서 외워두세요!


명세서 (Specifications)

명세서 (Specification)
Selectors Level 4
CSS Pseudo-Elements Module Level 4
  • 가상 클래스와 가상 요소에 대한 더 자세한 스펙은 각 MDN 문서의 명세서 표를 참고하세요.

같이 보기 (See also)


MDN 개선에 도움을 주세요 (Help improve MDN)

이 페이지가 도움이 되었나요? (Was this page helpful to you?)

이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다.


수고하셨습니다! CSS 선택자는 마치 외계어처럼 보일 수도 있지만, 오늘 배운 기본 기호( , >, +, ~, [], :, ::)들의 의미만 잘 기억해두시면 어떤 복잡한 구조의 HTML이라도 거뜬히 스타일링하실 수 있을 겁니다. 다음 프로젝트에 바로 적용해 보세요!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글