CSS의 :where() 의사 클래스 함수
이번 포스팅에서는 CSS에 비교적 최근에 추가된 의사 클래스(pseudo class) 함수인 :where()
에 대해서 알아보겠습니다.
기본 문법
:where()
의사 클래스 함수는 인자로 여러 개의 선택자를 쉼표(,
)로 구분하여 넘길 수 있습니다.
:where(선택자1, 선택자2, 선택자3, ...) {
/* 속성명1: 속성값1 */
/* 속성명2: 속성값2 */
/* 속성명3: 속성값3 */
/* ... */
}
위와 같은 CSS 규칙은 마치 아래와 같이 CSS 코드를 작성한 효과가 발생하게 되는데요.
선택자1,
선택자2,
선택자3,
... {
/* 속성명1: 속성값1 */
/* 속성명2: 속성값2 */
/* 속성명3: 속성값3 */
/* ... */
}
여기까지만 보면 뭐하러 굳이 :where()
함수를 사용해야될까 싶죠? 😅
지금부터 사례를 통해서 :where()
를 사용하면 어떠한 이점이 있는지 살펴보겠습니다.
여러 상태 스타일링
:where()
를 활용할 수 있는 가장 간단한 사례로 여러 개의 상태에 동일한 스타일을 적용할 때를 들 수 있는데요.
예를 들어, 버튼이 포커스를 받거나 버튼 위로 마우스 커서가 오거나 버튼을 누르고 있는 상태에서 배경을 파란색으로 바꾸고 싶다면 대개 다음과 같이 CSS 코드를 작성할 것입니다.
button:focus,
button:hover,
button:active {
background: blue;
}
동일한 CSS 규칙을 :where()
를 이용하면 button
을 3번 반복하지 않고 좀 더 간결하게 작성할 수 있습니다.
button:where(:focus, :hover, :active) {
background: blue;
}
여러 요소 스타일링
HTML에서 버튼은 다음과 같이 다양한 방식으로 마크업할 수가 있는데요.
<button>버튼 1</button>
<input type="button" value="버튼 2" />
<input type="reset" value="초기화" />
<input type="submit" value="제출" />
이 4가지 버튼을 일관적으로 스타일하기 위해서는 다음과 같은 CSS 규칙이 필요하겠죠?
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
appearance: none;
cursor: pointer;
margin: 0;
border: none;
border-radius: 1em;
padding: 0.5em 1em;
color: white;
font-weight: bold;
background: royalblue;
}
:where()
는 이렇게 여러 요소에 동일한 스타일을 적용할 때도 사용할 수 있습니다.
:where(
button,
input[type="button"],
input[type="reset"],
input[type="submit"]
) {
appearance: none;
cursor: pointer;
margin: 0;
border: none;
border-radius: 1em;
padding: 0.5em 1em;
color: white;
font-weight: bold;
background: royalblue;
}
:where()
의 장점은 CSS 코드를 작성할 때 발생할 수 있는 실수에 대해 좀 더 너그럽다는 것인데요.
예를 들어, 첫 번째 선택자에 오타를 내서 button
대신에 :button
라고 썼다면 어땠을까요?
:button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
/* 스타일 */
}
이와 같이 여러 개의 선택자를 나열했을 때 그 중에서 하나라도 잘못되었다면 그 CSS 규칙이 몽땅 날라가게 되는데요. 따라서 4가지 버튼 모두 전혀 스타일이 적용되지 않게 됩니다. 🙁
하지만 다음과 같이 :where()
를 쓰게 되면, 문제가 있는 첫 번째 선택자를 제외한 나머지 선택자에는 여전히 스타일이 적용됩니다.
:where(
:button,
input[type="button"],
input[type="reset"],
input[type="submit"]
) {
/* 스타일 */
}
여러 요소와 상태 스타일링
사실 :where()
의 진정한 위력은 다른 선택자와 조합해서 사용할 때 극대화 됩니다.
방금 살펴본 4가지 요소에, 처음 다뤘던 3가지 상태를 조합하면 무려 12가지 선택자가 필요한데요. 이 모든 선택자를 대상으로 동일한 스타일을 적용해볼까요? 🤮
button:focus,
button:hover,
button:active,
input[type="button"]:focus,
input[type="button"]:hover,
input[type="button"]:active,
input[type="reset"]:focus,
input[type="reset"]:hover,
input[type="reset"]:active,
input[type="submit"]:focus,
input[type="submit"]:hover,
input[type="submit"]:active {
background: blue;
}
동일한 CSS 규칙을 이번에는 :where()
를 활용해서 작성해볼께요.
:where(
button,
input[type="button"],
input[type="reset"],
input[type="submit"]
):where(:focus, :hover, :active) {
background: blue;
}
:where()
를 두 번 연속해서 사용했더니 필요한 선택자를 대폭 줄어 들었네요! 👍
CSS 명시도
CSS의 의사 클래스(pseudo class) 함수 중에서는 :where()
와 형제 뻘인 :is()
라는 녀석도 있는데요.
지금까지 작성한 예제 코드에서 :where()
를 :is()
로 대체해보시면 아무런 차이가 발생하지 않을 것입니다.
이 두 개의 함수 중에 무엇을 쓰든 무방한 경우가 많지만, 사실 CSS 명시도(specificity) 측면에서 큰 차이가 있는데요.
:where()
함수는 CSS 명시도가 0이라서, :where()
이 사용된 CSS 규칙은 다른 선택자를 통해서 덮어쓰기가 용이합니다.
반면에 :is()
함수의 CSS 명시도는 인자로 넘어온 선택자 중에서 가장 명시도가 큰 것이 되기 때문에 다른 선택자로 덮어쓰기를 방지하고자 할 때 더 적합합니다.
그래서 저는 개인적으로는 아직 이 두 함수에 익숙하지 않으시다면 :where()
를 사용하는 것을 먼저 고려하시고, 꼭 필요한 경우에만 :is()
를 사용하시라고 추천드리고 싶습니다.
이 부분에 대해서는 추후 기회가 되면 :is()
에 대해서 다룰 때 좀 더 자세히 살펴보도록 하겠습니다.
마치면서
지금까지 CSS에 추가된 매우 유용한 의사 클래스(pseudo class) 함수인 :where()
을 간단한 실습을 통해서 살펴보았습니다.
:where()
를 잘 활용하셔서 좀 더 깔끔하고 읽기 편한 CSS 코드를 작성하실 수 있으셨으면 좋겠습니다.