새로 지원되는 최신 CSS 의사 클래스 선택기 가이드
게시 됨: 2022-03-10 의사 클래스 선택자는 콜론 문자 " :
"로 시작하고 현재 요소의 상태 에 따라 일치하는 선택자입니다. 상태는 문서 트리와 관련되거나 :hover
또는 :checked
와 같은 상태 변경에 대한 응답일 수 있습니다.
:any-link
Selectors Level 4에 정의되어 있지만 이 의사 클래스는 꽤 오랫동안 브라우저 간 지원을 해왔습니다. any-link
의사 클래스는 href
가 있는 한 앵커 하이퍼링크와 일치합니다. :link
및 :visited
를 동시에 일치시키는 것과 동일한 방식으로 일치합니다. 기본적으로, 방문 상태에 관계없이 모든 링크에 적용하려는 color
과 같은 기본 속성을 추가하는 경우 하나의 선택기로 스타일을 줄일 수 있습니다.
:any-link { color: blue; text-underline-offset: 0.05em; }
특이성에 대한 중요한 참고 사항은 :any-link
가 클래스의 특이성을 가지고 있기 때문에 캐스케이드에서 더 낮게 배치되더라도 선택자 a
승리 a
것입니다. 다음 예에서 링크는 보라색이 됩니다.
:any-link { color: purple; } a { color: red; }
따라서 :any-link
를 도입하면 의 인스턴스가 a
성을 놓고 경쟁하게 될 경우 선택기로 이를 포함해야 합니다.
:focus-visible
웹에서 가장 일반적인 접근성 위반 중 하나는 링크, 버튼 및 :focus
상태에 대한 양식 입력과 같은 대화형 요소의 outline
을 제거하는 것입니다. 이 outline
의 주요 목적 중 하나는 탐색에 주로 키보드를 사용하는 사용자를 위한 시각적 표시기 역할을 하는 것입니다. 가시적인 초점 상태는 사용자가 인터페이스를 탭핑하고 대화형 요소를 강화하는 데 도움이 되는 길 찾기 도구로서 매우 중요 합니다. 특히 가시적인 초점은 WCAG 적합 기준 2.4.11: 초점 모양(최소)에서 다룹니다.
:focus-visible
의사 클래스는 사용자 에이전트가 휴리스틱을 통해 볼 수 있어야 한다고 결정할 때만 포커스 링을 표시하기 위한 것입니다. 다시 말해서 브라우저는 입력 방법, 요소 유형 및 상호 작용 컨텍스트와 같은 항목에 따라 :focus-visible
을 적용할 시기를 결정합니다. 키보드 및 마우스 입력이 있는 데스크탑 컴퓨터를 통한 테스트 목적을 위해 대화형 요소에 탭할 때 표시되는 :focus-visible
스타일이 표시되어야 하지만 클릭할 때는 표시되지 않습니다. 단, 텍스트 입력 및 표시되어야 하는 텍스트 영역은 예외입니다 :focus-visible
모든 초점 입력 유형에 대해 :focus-visible
됩니다.
참고 : 자세한 내용은 :focus-visible
사양의 작업 초안을 검토하세요.
최신 버전의 Firefox 및 Chromium 브라우저는 UA가 :focus-visible
:focus
스타일을 제거해야 한다는 사양에 따라 양식 입력에서 :focus-visible
을 처리하는 것으로 보입니다. Safari는 아직 :focus-visible
을 지원하지 않으므로 접근성에 대한 outline
제거를 피하기 위해 :focus
스타일이 폴백으로 포함되도록 해야 합니다.
다음 스타일 세트로 버튼과 텍스트 입력이 주어지면 어떤 일이 일어나는지 봅시다.
input:focus, button:focus { outline: 2px solid blue; outline-offset: 0.25em; } input:focus-visible { outline: 2px solid transparent; border-color: blue; } button:focus:not(:focus-visible) { outline: none; } button:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px blue; }
크롬과 파이어폭스
-
input
마우스 입력을 통해 요소에 초점을 맞출 때:focus-visible
을 사용하여border-color
을 변경하고 키보드 입력에서outline
을 숨길 때:focus
스타일을 올바르게 제거합니다. -
button
::focus
의 외곽선을 제거하는button:focus:not(:focus-visible)
에 대한 추가 규칙 없이:focus-visible
을 사용할 뿐만 아니라 키보드 입력에서만box-shadow
의 가시성을 허용합니다.
원정 여행
-
input
:focus
스타일만 계속 사용 -
button
이것은 이제 클릭 시:focus
스타일을 숨김으로써 버튼에서:focus-visible
의 의도를 부분적으로 존중하는 것으로 보이지만 여전히 키보드 상호 작용 시:focus
스타일을 표시합니다.
따라서 현재로서는 :focus
스타일을 계속 포함하고 데모 코드에서 허용하는 :focus-visible
을 사용하도록 점진적으로 향상하는 것이 좋습니다. 다음은 계속 테스트할 수 있는 CodePen입니다.
:focus-within
:focus-within
pseudo-class는 모든 최신 브라우저에서 지원되며 거의 부모 선택기처럼 작동하지만 매우 특정한 조건에서만 작동합니다. 포함 요소에 연결되고 자식 요소가 :focus
와 일치하면 포함 요소 및/또는 컨테이너 내의 다른 요소에 스타일을 추가할 수 있습니다.
이 동작을 사용하기 위한 실용적인 개선 사항은 연결된 입력에 포커스가 있을 때 양식 레이블의 스타일 을 지정하는 것입니다. 이것이 작동하려면 레이블과 입력을 컨테이너에 래핑한 다음 해당 컨테이너에 :focus-within
with 를 첨부하고 레이블을 선택합니다.
.form-group:focus-within label { color: blue; }
그 결과 입력에 포커스가 있을 때 레이블이 파란색으로 바뀝니다.
이 CodePen 데모에는 .form-group
컨테이너에 직접 개요를 추가하는 것도 포함됩니다.
:is()
"모든 것과 일치" 의사 클래스라고도 하는 :is()
는 일치를 시도할 선택기 목록을 사용할 수 있습니다. 예를 들어, 제목 스타일을 개별적으로 나열하는 대신 :is(h1, h2, h3)
선택기 아래에 그룹화할 수 있습니다.
:is()
선택기 목록에 대한 몇 가지 고유한 동작:
- 나열된 선택기가 유효하지 않은 경우 규칙은 계속해서 유효한 선택기와 일치합니다. 주어진
:is(-ua-invalid, article, p)
규칙은article
및p
와 일치합니다. - 계산된 특이성은 가장 높은 특이성을 가진 전달된 선택기와 동일합니다. 예를 들어
:is(#id, p)
는#id
— 1.0.0 —의 특이성을 갖는 반면:is(p, a)
는 0.0.1의 특이성을 갖습니다.
잘못된 선택자를 무시하는 첫 번째 동작은 주요 이점입니다. 하나의 선택기가 유효하지 않은 그룹에서 다른 선택기를 사용할 때 브라우저는 전체 규칙을 폐기합니다. 이것은 벤더 접두사가 여전히 필요한 몇 가지 경우에 적용되며 접두사가 붙은 선택기와 접두사가 붙지 않은 선택기를 그룹화하면 모든 브라우저에서 규칙이 실패합니다. :is()
를 사용하면 해당 스타일을 안전하게 그룹화할 수 있으며 일치하면 적용되고 일치하지 않으면 무시됩니다.
나에게 앞서 언급한 것처럼 제목 스타일을 그룹화 하는 것은 이 선택기로 이미 큰 승리입니다. 다음과 같이 중요하지 않은 스타일을 적용할 때 대체 없이 편안하게 사용할 수 있는 규칙 유형이기도 합니다.
:is(h1, h2, h3) { line-height: 1.2; } :is(h2, h3):not(:first-child) { margin-top: 2em; }
이 예제(내 프로젝트 SmolCSS의 문서 스타일에서 가져옴)에서 기본 스타일에서 상속된 더 큰 line-height
를 가지거나 margin-top
이 없는 것은 지원하지 않는 브라우저에서 실제로 문제가 되지 않습니다. 그것은 단순히 이상적이지 않습니다. 아직 :is()
를 사용하고 싶지 않은 것은 인터페이스를 크게 제어하는 Grid 또는 Flex와 같은 중요한 레이아웃 스타일 입니다.
또한 다른 선택기에 연결되어 있을 때 기본 선택기가 :is()
내의 하위 선택기와 일치하는지 테스트할 수 있습니다. 예를 들어 다음 규칙은 기사의 직계 자손인 단락만 선택합니다. 범용 선택기는 p
기본 선택기에 대한 참조로 사용됩니다.
p:is(article > *)
최상의 현재 지원을 위해 사용을 시작하려면 :-webkit-any()
및 :matches()
를 사용하여 중복 규칙을 포함하여 스타일 을 이중화할 수도 있습니다. 이러한 개별 규칙을 만들지 않으면 지원하는 브라우저에서도 이를 폐기할 것임을 기억하십시오! 즉, 다음을 모두 포함합니다.
:matches(h1, h2, h3) { } :-webkit-any(h1, h2, h3) { } :is(h1, h2, h3) { }
이 시점에서 언급할 가치는 새로운 선택자 자체와 함께 @supports selector
@supports
의 업데이트된 변형이 있다는 것입니다. 이것은 @supports not selector
로도 사용할 수 있습니다.
참고 : 현재(최신 브라우저 중) Safari만 이 at-규칙을 지원하지 않습니다.
다음과 같이 :is()
지원을 확인할 수 있지만 Safari는 :is()
를 지원하지만 @supports selector
는 지원하지 않기 때문에 실제로 Safari를 지원하지 못하게 됩니다.
@supports selector(:is(h1)) { :is(h1, h2, h3) { line-height: 1.1; } }
:where()
의사 클래스 :where()
는 한 가지 중요한 차이점을 제외하고 :is()
와 거의 동일합니다. 이것은 프레임워크, 테마 및 디자인 시스템을 구축하는 사람들에게 놀라운 의미를 갖습니다. :where()
를 사용하여 작성자는 기본값을 설정할 수 있고 다운스트림 개발자는 특이성 충돌 없이 재정의 또는 확장을 포함할 수 있습니다.
다음 img
스타일 세트를 고려하십시오. :where()
를 사용하면 더 높은 특이성 선택기를 사용하더라도 특이성은 0으로 유지됩니다. 다음 예에서 이미지의 테두리 색상은 무엇이라고 생각합니까?
:where(article img:not(:first-child)) { border: 5px solid red; } :where(article) img { border: 5px solid green; } img { border: 5px solid orange; }
첫 번째 규칙은 전체가 :where()
내에 포함되어 있으므로 특이성이 0입니다. 따라서 두 번째 규칙에 대해 직접적으로 두 번째 규칙이 승리합니다. 마지막 규칙으로 img
요소 전용 선택기를 도입하면 캐스케이드로 인해 승리할 것입니다. 이는 :where()
부분이 특이성을 증가시키지 않기 때문에 :where(article) img
규칙과 동일한 특이도로 계산되기 때문입니다.
폴백과 함께 :where()
를 사용하는 것은 비특이성 기능 때문에 조금 더 어렵습니다. 왜냐하면 그 기능이 당신이 :is()
보다 그것을 사용하기를 원하는 이유일 가능성이 높기 때문입니다. 그리고 폴백 규칙을 추가하면 그 특성 때문에 :where()
를 능가할 가능성이 높습니다. 그리고 @supports selector
보다 전반적인 지원 이 더 우수하므로 이를 사용하여 대체를 작성하려고 하면 많은 이득(있는 경우)을 제공할 가능성이 없습니다. 기본적으로 :where()
에 대한 폴백을 올바르게 생성할 수 없음을 인식하고 고유한 대상에 대해 사용을 시작하는 것이 안전한지 확인하기 위해 자신의 데이터를 주의 깊게 확인하십시오.
위에서 img
선택기를 사용하는 다음 CodePen으로 :where()
를 추가로 테스트할 수 있습니다.
향상된 :not()
기본 :not()
선택기는 Internet Explorer 9부터 지원되었습니다. 그러나 선택기 레벨 4는 :is()
및 :where()
처럼 선택기 목록을 사용할 수 있도록 하여 :not()
을 향상시킵니다.
다음 규칙은 지원 브라우저에서 동일한 결과를 제공합니다.
article :not(h2):not(h3):not(h4) { margin-bottom: 1.5em; } article :not(h2, h3, h4) { margin-bottom: 1.5em; }
선택자 목록을 허용하는 :not()
의 기능은 최신 브라우저를 지원합니다.
:is()
에서 보았듯이 향상된 :not()
은 *
를 사용하여 기본 선택자에 대한 참조를 자손으로 포함할 수도 있습니다. 이 CodePen은 nav
의 자손이 아닌 링크를 선택하여 이 기능을 보여줍니다.
보너스 : 이전 데모에는 h2
또는 h3
요소의 인접 형제가 아닌 이미지를 선택하기 위해 :not()
및 :is()
를 연결하는 예도 포함되어 있습니다.
제안되었지만 "위험" — :has()
매우 흥미로운 제안이지만 실험적인 방법으로도 이를 구현하는 현재 브라우저가 없는 마지막 의사 클래스는 :has()
입니다. 실제로 Selector Level 4 Editor's Draft에 "at-risk"로 나열되어 있는데, 이는 구현을 완료하는 데 어려움이 있는 것으로 인식되어 권장 사항에서 제외 될 수 있음을 의미합니다.
구현된 경우 :has()
는 본질적으로 많은 CSS 사용자가 사용할 수 있기를 갈망했던 "부모 선택기"가 됩니다. 이것은 자손 선택자와 함께 :focus-within
및 :is()
의 조합과 유사한 논리로 작동합니다. 여기서 자손의 존재를 찾고 있지만 적용된 스타일은 상위 요소에 적용됩니다.
다음 규칙이 주어지면 탐색에 버튼이 포함된 경우 탐색의 상단 및 하단 패딩이 감소합니다.
nav { padding: 0.75rem 0.25rem; nav:has(button) { padding-top: 0.25rem; padding-bottom: 0.25rem; }
다시 말하지만, 이것은 현재 실험적으로도 어떤 브라우저에서도 구현 되지 않습니다 . 하지만 생각하는 것은 재미있습니다! Robin Rendle은 CSS-Tricks에서 이 미래 선택기에 대한 추가 통찰력을 제공했습니다.
레벨 3의 가작: :empty
Selectors Level 3에서 놓쳤을 수 있는 유용한 의사 클래스는 텍스트 노드를 포함하여 자식 요소가 없을 때 요소와 일치하는 :empty
입니다.
p:empty
규칙은 <p></p>
와 일치하지만 <p>Hello</p>
는 일치하지 않습니다.
:empty
를 사용할 수 있는 한 가지 방법은 JavaScript로 채워진 동적 콘텐츠의 자리 표시자일 수 있는 요소를 숨기는 것입니다. 아마도 검색 결과를 수신할 div가 있고 채워질 때 테두리와 약간의 패딩이 있을 것입니다. 그러나 아직 결과가 없으므로 페이지에서 공간을 차지하는 것을 원하지 않습니다. :empty
를 사용하여 다음과 같이 숨길 수 있습니다.
.search-results:empty { display: none; }
빈 상태의 메시지를 추가하는 것에 대해 생각하고 의사 요소와 content
을 추가하고 싶은 유혹을 받을 수 있습니다. 여기서 함정은 content
에 액세스할 수 있는지 여부에 일관성이 없는 보조 기술 사용자가 메시지를 사용할 수 없다는 것입니다. 즉, "결과 없음" 유형의 메시지에 액세스할 수 있는지 확인 하려면 이를 단락과 같은 실제 요소로 추가하고 싶을 것입니다( aria-label
은 숨겨진 div에 대해 더 이상 액세스할 수 없습니다).
선택자 학습을 위한 리소스
CSS에는 의사 클래스를 포함하여 더 많은 선택기가 있습니다. 사용 가능한 항목에 대해 자세히 알아볼 수 있는 몇 가지 추가 장소는 다음과 같습니다.
- MDN CSS 선택기 문서에는 포괄적인 분류 목록이 포함되어 있습니다.
- 고급 CSS 선택기에 대한 두 부분으로 구성된 가이드를 작성했습니다. 첫 번째 부분부터 시작할 수 있습니다.
- CSS Diner 게임으로 CSS 선택기에 대해 재미있게 배우십시오.
- Kitty Giraudel은 제공된 선택기의 일부를 분해하고 설명하는 선택기 설명 도구를 만들었습니다.