새로운 CSS 기능적인 의사 클래스 :is():where()


원문: Adam Argyle, https://web.dev/css-is-and-where/

CSS 선택자 구문에 생긴 작은 추가 사항이 앞으로 큰 영향을 끼칠 것이다.

CSS를 작성할 때 여러 요소에 동일한 스타일을 적용하기 위해 종종 긴 선택자 목록들을 작성해야 했다. 예를 들어, 제목 요소 안에 있는 <b> 태그의 색상을 변경하려면 다음과 같이 작성했다.

h1 > b, h2 > b, h3 > b, h4 > b, h5 > b, h6 > b {
  color: hotpink;
}

이제 :is()를 이용하면 긴 선택자 목록을 사용하지 않고 가독성 또한 향상시킬 수 있다.

:is(h1,h2,h3,h4,h5,h6) > b {
  color: hotpink;
}

읽기 쉽고 짧은 선택자가 주는 편의성은 :is():where()가 CSS에 가져다 준 가치 중에 일부일 뿐이다. 이 글에서는 두 가지 기능적인 의사 클래스의 문법과 값을 설명할 것이다.


:is() 사용 전과 후

브라우저 호환성

:is(), :where() 기능적인 가상 클래스는 현재 크롬(>=88), 파이어폭스(>=78), 사파리(>=14)에서 지원된다. 자세한 정보는 MDN의 브라우저 호환성 표를 참고하자. 이전 버전의 일부 브라우저에서는 :is() 선택자를 :matches()-webkit-any()로 지원한다. 자세한 내용은 MDN의 :is() 페이지를 참고해라.

:is():where() 살펴 보기

이 둘은 기능적인 의사 클래스 선택자이다. :로 시작하여 ()로 끝난다는 점에 주목하자. 해당하는 요소를 찾는 함수를 런타임에 동적으로 호출했다고 생각해라. CSS를 작성할 때 선택자의 중간, 시작 또는 끝에서 요소를 그룹화할 수 있다. 또한 이들은 CSS 명시도를 변경할 수 있어서 명시도를 무효화하거나 증가시킬 수도 있다.

선택자 그룹화

:is()가 할 수 있는 그룹화라면 :where()도 할 수 있다. 그룹화는 선택자 어디에서나 사용할 수 있고, 중첩 및 결합도 할 수 있다. 이것이 우리가 알고 있고 사랑하는 CSS의 유연함이다. 아래에 몇 가지 예시가 있다.

/* 선택자 처음 */
:where(h1,h2,h3,h4,h5,h6) > b {
  color: hotpink;
}

/* 선택자 중간 */
article :is(header,footer) > p {
  color: gray;
}

/* 선택자 끝 */
.dark-theme :where(button,a) {
  color: rebeccapurple;
}

/* 여러 가지 사용 */
:is(.dark-theme, .dim-theme) :where(button,a) {
  color: rebeccapurple;
}

/* 결합 */
:is(h1,h2):where(.hero,.subtitle) {
  text-transform: uppercase;
}

/* 중첩 */
.hero:is(h1,h2,:is(.header,.boldest)) {
  font-weight: 900;
}

위의 각 예시는 두 가지 기능적인 의사 클래스의 유연함을 보여준다. :is():where()에서 이점을 얻을 수 있는 코드를 찾으려면 쉼표가 여러 개 있고 선택자가 반복되는 곳을 찾아라.

단순하고 복잡한 선택자를 :is()와 함께 사용하기

선택자에 대한 지식을 다시 떠올리기 위해서는 Learn CSS의 선택자 모듈 편을 참고해라. 아래는 간단하고 복잡한 선택자의 몇 가지 예시이다. 기능을 설명하는데 도움을 줄 것이다.

article > :is(p,blockquote) {
  color: black;
}

:is(.dark-theme.hero > h1) {
  font-weight: bold;
}

article:is(.dark-theme:not(main .hero)) {
  font-size: 2rem;
}

추가 설명
일반적으로 ,를 이용하여 선택자 목록을 만들 때, 선택자 중 하나라도 유효하지 않다면 모든 선택자가 무효화되고 요소를 찾는데 실패한다. 즉, CSS는 실수를 용납하지 않는다. 하지만 :is():where()은 실수를 용납하고 선택자 목록 전체가 무효화되는 것을 방지할 수 있다.

지금까지는 :is():where()를 구문적으로 서로 바꿔쓸 수 있었다. 이제는 이 둘이 어떻게 다른지에 대해 살펴보자.

:is():where()의 차이

명시도에 관한 한 :is():where()은 극과 극을 달린다. 명시도가 무엇인지 기억나지 않는다면 Learn CSS의 명시도 편을 참고하자.

요약하자면,

  • :where()은 명시도가 없다.
    :where()은 매개변수로 전달된 선택자 목록의 모든 명시도를 무시한다. 이러한 기능은 다른 선택자에선 볼 수 없다.
  • :is()는 가장 구체적인 선택자의 명시도를 따라간다.
    :is(a,div,#id)의 명시도는 ID의 명시도인 100점이다.

필자가 그룹화를 남발했을 때 선택자 목록에서 가장 높은 명시도를 따라가는 특징이 문제가 되었다. 높은 명시도를 가진 선택자를 따로 분리하여 큰 영향을 미치지 않게 하면서 가독성을 높일 수 있었다. 필자가 얘기한 바의 예시는 아래와 같다.

article > :is(header, #nav) {
  background: white;
}

/* 아래가 더 낫다 */
article > header,
article > #nav {
  background: white;
}

필자는 라이브러리에서 :where()을 사용하여 명시도가 없는 버전을 제공하길 기다리고 있다. 라이브러리에서 :where()을 사용한다면 경쟁할 명시도가 없기 때문에 더 이상 작성자 스타일과 라이브러리 스타일이 명시도 경쟁을 하지 않아도 된다. CSS는 이러한 그룹화 기능을 오랜 시간 연구했지만 아직도 정체되어 있고, 대부분 논의되지 않았다. 더 작은 스타일시트를 만들고 쉼표를 없애는데 재미를 들이길 바란다.

곽희나2021.07.21
Back to list