새로 지원되는 최신 CSS 의사 클래스 선택기 가이드

게시 됨: 2022-03-10
빠른 요약 ↬ CSS Working Group Editor's Draft for Selectors Level 4에는 대부분의 최신 브라우저에서 이미 제안 후보가 있는 여러 유사 클래스 선택기가 포함되어 있습니다. 이 가이드는 현재 최고의 지원을 받고 있는 것들과 지금 바로 사용을 시작할 수 있는 방법을 보여주는 예제를 다룰 것입니다!

의사 클래스 선택자는 콜론 문자 " : "로 시작하고 현재 요소의 상태 에 따라 일치하는 선택자입니다. 상태는 문서 트리와 관련되거나 :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입니다.

Stephanie Eckles의 Pen [Testing application of :focus-visible](https://codepen.io/smashingmag/pen/MWJZbew)을 참조하십시오.

Stephanie Eckles의 :focus-visible의 펜 테스트 응용 프로그램을 참조하십시오.

:focus-within

:focus-within pseudo-class는 모든 최신 브라우저에서 지원되며 거의 부모 선택기처럼 작동하지만 매우 특정한 조건에서만 작동합니다. 포함 요소에 연결되고 자식 요소가 :focus 와 일치하면 포함 요소 및/또는 컨테이너 내의 다른 요소에 스타일을 추가할 수 있습니다.

이 동작을 사용하기 위한 실용적인 개선 사항은 연결된 입력에 포커스가 있을 때 양식 레이블의 스타일 을 지정하는 것입니다. 이것이 작동하려면 레이블과 입력을 컨테이너에 래핑한 다음 해당 컨테이너에 :focus-within with 를 첨부하고 레이블을 선택합니다.

 .form-group:focus-within label { color: blue; }

그 결과 입력에 포커스가 있을 때 레이블이 파란색으로 바뀝니다.

이 CodePen 데모에는 .form-group 컨테이너에 직접 개요를 추가하는 것도 포함됩니다.

Stephanie Eckles의 Pen [Testing application of :focus-within](https://codepen.io/smashingmag/pen/xxgmREq)을 참조하십시오.

Stephanie Eckles의 :focus-within의 Pen Testing 응용 프로그램을 참조하십시오.

:is()

"모든 것과 일치" 의사 클래스라고도 하는 :is() 는 일치를 시도할 선택기 목록을 사용할 수 있습니다. 예를 들어, 제목 스타일을 개별적으로 나열하는 대신 :is(h1, h2, h3) 선택기 아래에 그룹화할 수 있습니다.

:is() 선택기 목록에 대한 몇 가지 고유한 동작:

  • 나열된 선택기가 유효하지 않은 경우 규칙은 계속해서 유효한 선택기와 일치합니다. 주어진 :is(-ua-invalid, article, p) 규칙은 articlep 와 일치합니다.
  • 계산된 특이성은 가장 높은 특이성을 가진 전달된 선택기와 동일합니다. 예를 들어 :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() 를 추가로 테스트할 수 있습니다.

Stephanie Eckles의 Pen [Testing `:where()` 특이성](https://codepen.io/smashingmag/pen/jOyXVMg)을 참조하십시오.

Stephanie Eckles의 Pen Testing :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 의 자손이 아닌 링크를 선택하여 이 기능을 보여줍니다.

Stephanie Eckles의 Pen [Testing :not() with a 자손 선택기](https://codepen.io/smashingmag/pen/BapvQQv)을 참조하십시오.

Stephanie Eckles의 자손 선택자를 사용한 Pen Testing :not()을 참조하십시오.

보너스 : 이전 데모에는 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은 제공된 선택기의 일부를 분해하고 설명하는 선택기 설명 도구를 만들었습니다.