:where()
함수형 가상 클래스
:where()
함수형 가상 클래스 선택자는
괄호()
안의 선택자 목록 중 하나라도 존재하는지 확인해서 있으면 요소를 선택합니다.
하나 이상의 여러 선택자를 쉼표로 구분하여 묶어, 그 중 하나라도 일치하면 요소를 선택합니다.
괄호()
안의 선택자 목록에 여러 개의 선택자를 사용할 때 사용하는 쉼표(,
)는 "또는(or)"이라고 해석합니다. 예를 들어, :where(A, B, C)
는 "A 또는 B 또는 C가 존재하면 선택"과 같은 논리적 의미를 가집니다.
구문
/* <한 개의 선택자 목록> */
:where(p) {}
:where(.class) {}
:where(#id) {}
/* <여래 개의 선택자 목록>
쉼표(,)로 구분합니다.
쉼표(,) 앞 뒤의 띄어쓰기는 없거나 있거나 동일하게 작동합니다.
*/
:where(p, span) {}
:where(.class, p, #id) {}
:where(#id, .classs) {}
알아두세요!
:where()
은 :is()
와 동일한 구문과 기능을 가지지만, :is()
와 달리 CSS 선택자의 구체성 값(명시도)의 규칙에서 :where()
자체나 괄호()
안의 선택자 목록의 구체성 값(명시도)이 없습니다. 즉, 구체성 값은 항상 0
입니다.
:where()
은 구체성 값 없이 복잡한 선택자에 활용할 수 있기 때문에 별칭으로 'The Specificity-adjustment Pseudo-class(구체성 값 조정 가상 클래스)'라고 부릅니다.
예제
여러 예제를 통해서 :where()
함수형 가상 클래스 선택자의 사용법에 대해 알아보겠습니다.
정말 간단한 예제
다음은 :where()
함수형 가상 클래스 선택자의 사용법의 이해를 위한 정말 간단한 예제입니다.
<!-- h4, h5, p 태그들은 서로 다른 요소입니다. -->
<h4>나는 h4 요소입니다.</h4>
<h5>나는 h5 요소입니다.</h5>
<p>나는 p 요소입니다.</p>
/*
:where(h5) 선택자는 괄호 안의 선택자 목록과 일치하는 h5 요소에만 스타일을 적용합니다.
이 규칙은 h5 요소의 글자 색상을 빨간색으로 설정합니다.
*/
:where(h5) {
color: red; /* h5 요소의 글자 색상은 빨간색으로 변경됩니다. */
}
/*
:where(h4, p)는 괄호 안의 선택자 목록과 일치하는 h4와 p 요소에 스타일을 적용합니다.
이 규칙은 h4와 p 요소의 배경색을 yellowgreen으로 설정합니다.
*/
:where(h4, p) {
background-color: yellowgreen; /* h4와 p 요소의 배경색을
yellowgreen으로 설정합니다. */
}
나는 h4 요소입니다.
나는 h5 요소입니다.
나는 p 요소입니다.
:where()
를 사용하는 가장 유용한 예제 💖
CSS 선택자의 구체성 값(명시도)의 규칙에서 :where()
자체나 괄호()
안의 선택자 목록의 구체성 값(명시도)이 없습니다. 즉, 구체성 값은 항상 0
입니다.
:where()
은 선택자의 구체성 값에 아무런 영향을 주지 않기 때문에, 기본 스타일(일명 CSS 리셋)을 설정할 때 매우 유용합니다.
:where()
를 사용해 기본 스타일을 지정하면, 이후 더 구체적인 선택자로 쉽게 스타일을 덮어쓸 수 있습니다. 덮어쓰기를 쉽게 할 수 있습니다.
어떤 경우에는 선택자의 구체성 값의 규칙때문에 예상과 다르게 스타일이 적용되지 않는 경우가 있습니다.
예를 들어, 특정 링크가 :hover
상태가 아닐 때 밑줄을 없애고 싶지만, nav a
에 다시 밑줄을 적용하려고 하면 스타일이 덮어씌워지지 않는 문제가 발생할 수 있습니다. 다음과 같은 상황에서 말이죠.
구체성 문제 발생
<nav>
<ul>
<li><a href="">링크 텍스트</a></li>
</ul>
</nav>
a:not(:hover) { /* 구체성 값: 0, 0, 1, 1 */
text-decoration: none;
}
nav a { /* 구체성 값: 0, 0, 0, 2 */
/* 적용되지 않음 */
text-decoration: underline;
}
코드 부연설명
:not(selectorX)
함수형 가상 클래스 선택자는 인수로 취하는 selectorX
와 일치하지 않는 요소를 선택합니다.
코드 부연설명
:hover()
가상 클래스 선택자는 요소에 마우스 커서를 올려 놓았을 동안 해당 요소를 선택합니다.
a:not(:hover)
의 구체성 값이nav a
보다 높아서,nav a
가text-decoration: underline
을 적용하려 해도 덮어씌우지 못함.
:where()
을 활용하면 이러한 구체성 문제를 쉽게 해결할 수 있습니다.
:where()
를 활용한 해결 방법
a:where(:not(:hover)) { /* 구체성 값: 0, 0, 0, 1 */
text-decoration: none;
}
nav a { /* 구체성 값: 0, 0, 0, 2 */
/* 정상적으로 적용됨 */
text-decoration: underline;
}
:where(:not(:hover))
를:where()
자체나 괄호()
안의 선택자 목록의 구체성 값이 없어서,a:where(:not(:hover))
선택자 전체의 구체성이 매우 낮음.- 따라서,
nav a
가 높은 우선순위를 가져서 밑줄이 적용된 스타일이 정상적으로 적용됨.
예제를 통해 알 수 있듯이 :where()
함수형 가상 클래스 선택자는 기본 스타일(일명 CSS 리셋)을 설정할 때 매우 유용합니다.
:where()
과 :is()
비교
:where()
과 :is()
선택자는 동일한 구문과 기능을 가지지만, 중요한 차이점이 있습니다.
이 두 선택자의 차이점은 다음과 같습니다.
:where() |
:where() 자체나 괄호 안의 선택자 목록의 구체성 값과는 상관없이 항상 0,0,0,0의 구체성 값을 가집니다. 즉 구체성 값도 없고 아무런 영향을 주지 않습니다. |
---|---|
:is()
|
:is() 자체는 구체성 값이 없으나, 괄호 안의 선택자 목록에서 가장 구체성이 높은 선택자의 구체성 값을 그대로 따릅니다. |
주의할 점
:where()
은 :is()
와 마찬가지로 괄호 안의 선택자 목록에는 가상 요소 선택자(예:
::before
,
::after
,
::marker
,
::placeholder
,
::selection
등)를 사용할 수 없습니다.
따라서, 다음의 예제는 유효하지 않습니다.
selector:where(::before, ::after) {
/* ...*/
}
대신 다음과 같이 다중 선택자를 대신 사용하세요.
selector::before,
selector::after {
/* ...*/
}
활용 예제
:where()
함수형 가상 클래스 선택자는 CSS 선택자를 크게 단순화하고, 코드를 간결하게 할 수 있습니다.
특히 반복적인 계층 구조를 가지는 HTML의 섹션과 제목을 다루면서 구체성 값에 아무런 영향을 주지 않기 때문에, 기본 스타일(일명 CSS 리셋)을 설정할 때 매우 유용합니다.
예를 들어 특정 섹션의 제목 요소들의 타일을 지정하는 것은 아주 반복적이고, 코드의 양도 많을 수 있습니다. 다음과 같은 경우가 해당됩니다.
article h2,
article h3,
article h4,
article h5,
article h6,
aside h2,
aside h3,
aside h4,
aside h5,
aside h6,
section h2,
section h3,
section h4,
section h5,
section h6 {
color: blue;
font-weight: 500;
}
:where()
함수형 가상 클래스 선택자를 활용하면 코드를 짧고 이해하기 쉽게 유지하는 데 유리하고, 훨씬 간단합니다.
:where(article, section, aside) :where(h2, h3, h4, h5, h6) {
color: blue;
font-weight: 500;
}
브라우저 호환성
선택자 |
데스크탑 Chrome
|
데스크탑데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
---|---|---|---|---|
:where()
|
88 | 88 | 82 | 14 |
명세서
명세서 사양 | |
---|---|
:where()
|
Selectors Level 4 #zero-matches |