Logo

CSS 결합자(combinator)로 선택자 조합하기

CSS 코드를 읽다보면 아래와 같이 선택자(selector) 사이에서 >+, 또는 ~와 같은 기호를 어렵지 않게 볼 수 있습니다.

CSS에서는 이렇게 선택자 사이에 나오는 기호들을 결합자(combinator)라는 다소 어려운 이름으로 부르는데요. 이번 포스팅에서는 CSS의 결합자(combinator)에 대해서 한번 알아보려고 합니다.

Descendant combinator

CSS에서 너무 흔하게 볼 수 있어서 많은 개발자들이 결합자라는 인식도 없이 사용하는 결합자가 있습니다. 바로 공백 문자를 사용해서 선택자를 조합하는 후손 결합자(descendant combinator)입니다.

선택자1 선택자2 {
  /* 스타일 선언 */
}

공백 문자를 사용해서 두 개의 선택자를 조합하면 첫번째 선택자로 선택된 영역 하위에서 두번째 선택자로 스타일을 적용할 요소를 찾습니다. 바로 아래의 자식 요소뿐만 아니라 여러 단계 아래의 후손 요소까지 선택하기 때문에 후손 선택자라고 부릅니다.

예를 들어, 아래 CSS 코드는 웹페이지 상에서 일단 <article> 요소를 먼저 찾고, 그 하위에 있는 모든 <a> 요소를 찾습니다. 즉, <a> 요소가 <article> 요소 하위에 있다면 DOM 트리 내에 어디에 위치하든 스타일을 적용해줍니다.

article a {
  color: red;
  text-decoration: none;
}

다음과 같은 HTML 코드가 있다면, <article> 요소와 <a> 요소 사이에 <p> 요소가 위치하지만 글자가 빨간색이 되고 밑줄이 사라질 것입니다.

<article>
  <p><a href="#">여기</a>를 클릭하세요.</p>
</article>

Child combinator

모든 후손 요소가 아닌 직계 자식 요소만 선택하고 싶다면 > 기호를 사용하는 자식 결합자(child combinator)를 사용할 수 있습니다.

선택자1 > 선택자2 {
  /* 스타일 선언 */
}

먼저 살펴본 후손 결합자를 사용하면 DOM 트리를 따라 내려가면서 너무 많은 요소가 선택될 수 있기 때문에 선택 범위를 자식 요소로만 제한할 때 유용하게 쓰입니다.

예를 들어, 아래 CSS 코드는 <article> 요소 바로 아래에 위치하고 있는 <h3> 요소만을 찾아서 스타일을 적용해줍니다.

article > h3 {
  font-size: 2rem;
  text-align: center;
  margin: 10px;
}

만약에 다음 HTML 코드에서 <h3> 요소가 <article> 요소 바로 아래에 있지 않고, 중간에 <div> 요소가 같은 래퍼(wrapper) 요소가 있었다면 스타일이 적용되지 않을 것입니다.

<article>
  <h3>제목</h3>
</article>

Adjacent sibling combinator

다음으로 살펴본 결합자는 + 기호를 사용하는 인접 형제 결합자(adjacent sibling combinator)입니다. + 기호를 사용해서 두 개의 선택자를 조합하면 첫번째 선택자로 선택된 요소의 바로 뒤에 나오는 형제 요소가 두번째 선택자에 부합한다면 선택됩니다.

예를 들어, 아래 CSS 코드는 <h3> 요소 바로 뒤에 붙어있는 요소가 <p> 요소라면 스타일을 적용해줍니다.

h3 + p {
  text-indent: 1em;
}

즉, 다음과 같은 HTML 코드가 있다면 첫번째 단락에만 들여쓰기가 됩니다.

<h3>제목</h3>
<p>여기에는 내용이 옵니다.</p>
<p><a href="#">여기</a>를 클릭하세요.</p>

General sibling combinator

마지막으로 살펴볼 결합자는 ~ 기호를 사용하는 일반 형제 결합자(general sibling combinator)입니다. ~ 기호를 사용해서 두 개의 선택자를 조합하면 첫번째 선택자로 선택된 요소의 다음에 나오는 모든 형제 요소 중에서 두번째 선택자에 부합한다면 선택됩니다.

위에서 살펴본 인접 형제 결합자와 달리 두 요소가 반드시 서로 붙어있을 필요는 없으면, 여러 개의 요소가 선택될 수 있습니다.

예를 들어, 아래 CSS 코드는 <h3> 요소 뒤에 나오는 모든 <p> 요소를 찾아서 스타일을 적용해줍니다.

h3 ~ p {
  font-style: italic;
}

즉, 다음과 같은 HTML 코드가 있다면 첫번째, 두번째 단락 모두 단락에 이탤릭체가 적용됩니다.

<h3>제목</h3>
<p>여기에는 내용이 옵니다.</p>
<p><a href="#">여기</a>를 클릭하세요.</p>

쉼표 기호도 결합자일까?

선택자 사이에서 자주 볼 수 있는 , 기호도 결합자일까요? , 기호는 단순히 동일한 스타일을 여러 개의 선택자를 대상으로 적용하고 싶을 때 사용됩니다. 그렇게 때문에 엄밀히 얘기해서 , 기호는 결합자로 분류되지는 않습니다. 별로 중요한 부분은 아니지만 헛갈려 하시는 분이 있을까봐 잠깐 언급해봤습니다. 😅

마치면서

지금까지 CSS의 조합자에 대해서 간단하게 살펴보았습니다. CSS 조합자를 사용하면 웹페이지의 매우 특정한 부분을 섬세하게 선택할 수 있어서 좋지만 모든 기술이 그러하듯이 납용하지 않도록 주의해야 합니다. 해당 HTML 요소에 class 속성을 할당하고 CSS의 클래스 선택자를 사용하는 편이 코드 재사용성과 유지보수 측면에서 유리한 경우가 많기 때문입니다. 하지만 제 경험상 외부에서 작성되어 내가 수정할 수 없는 웹페이지를 스타일할 때는 CSS 조합자가 매우 큰 힘을 발휘합니다.