: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는 이러한 그룹화 기능을 오랜 시간 연구했지만 아직도 정체되어 있고, 대부분 논의되지 않았다. 더 작은 스타일시트를 만들고 쉼표를 없애는데 재미를 들이길 바란다.