유효하지 않은 CSS 선택자를 작성하면 어떻게 됩니까? (나쁜 것들)

7652 단어
나는 당신이 그것에 대해 모르거나 잊어버리면 골칫거리를 일으킬 수 있는 매우 특정한 CSS 동작에 대해 이야기하고 싶습니다.

버튼을 만들어 봅시다:

<button>Click me</button>


이 버튼을 눌렀을 때 색상이 바뀌길 원합니다. :active 의사 클래스를 사용하면 쉽습니다.

button:active {
  background-color: black;
  color: white;
}




여태까지는 그런대로 잘됐다.

접근성을 향상시키기 위해 키보드나 보조 기술로 버튼이 포커스되었을 때 동일한 효과를 적용하고 싶습니다.

이것은 새로운:focus-visible 의사 클래스 덕분에 가능합니다. 작성 당시에는 Chrome and Edge 에 의해 접두어 없이 지원됩니다.

button:active,
button:focus-visible {
  background-color: black;
  color: white;
}




Chrome 또는 Edge를 사용 중인 경우 탭 키를 사용하여 버튼에 초점을 맞추면 :focus-visible 스타일이 표시됩니다.


이것은 마우스를 사용하지 않는 경우 훌륭한 시각적 도움말입니다.

여기 캐치가 있습니다



다른 브라우저에서는 어떤 일이 일어날지 짐작할 수 있습니까? 분명히 :focus-visible 스타일은 표시되지 않지만 부작용이 있습니까?
:active 스타일도 사라졌습니다!


브라우저가 :active 선택자를 완벽하게 이해하고 있음에도 불구하고 :active 스타일은 Firefox에 표시되지 않습니다. 너무 슬퍼.

이 문제가 발생하는 이유를 이미 알고 있다면 문제가 명백해 보일 수 있지만 훨씬 더 복잡한 CSS 파일에서 이 문제를 디버깅해야 했을 때 몇 분 동안 당황했습니다. 그리고 초보자들 사이에서는 잘 알려진 사실이 아닌 것 같습니다.

어떻게 넣을까요?

선택기의 일부가 실패하면 전체 선택기가 실패합니다.



즉, 브라우저가 :focus-within 선택기에 대해 알지 못하는 경우 :active 부분을 포함하여 전체 CSS 규칙을 폐기합니다.

CSS가 약간 취약하다고 말할 수 있습니다. 피자에 올린 올리브 종류가 마음에 들지 않으면 먹을 생각조차 하지 않습니다.


CSS는 미친 선택기로 낭비할 시간이 없습니다.

다음은 W3Cspecification입니다.

When interpreting a list of declarations, unknown syntax at any point causes the parser to throw away whatever declaration it’s currently building, and seek forward until it finds a semicolon (or the end of the block). It then starts fresh, trying to parse a declaration again.


따라서 사용해야 할 수정 사항은 다음과 같습니다. "안전한 스타일"과 미친 스타일을 분리합니다.

button:active {
  background-color: black;
  color: white;
}

button:focus-visible {
  background-color: black;
  color: white;
}




이제 :focus-visible가 실패할 수 있지만 :active 선택기는 방해하지 않습니다.

그런데 왜 이런 행동을 할까요?



Not really resilient for a language that should adapt itself to many environments, is it?


CSS is broken! JavaScript is our only savior!


음, 실제로 이에 대한 타당한 이유가 있습니다. 이는 이전 문서인 CSS 2.1 specification에 설명되어 있습니다.

CSS 2.1 gives a special meaning to the comma (,) in selectors. However, since it is not known if the comma may acquire other meanings in future updates of CSS, the whole statement should be ignored if there is an error anywhere in the selector, even though the rest of the selector may look reasonable in CSS 2.1.


CSS 디자이너는 여기서 큰 기대를 보였습니다. 실제로 조만간 사용할 수 있는 CSS 선택기가 있습니다(어떤 경우에는 이미 사용하고 있습니다).

.title:is(h1, h2, h3) {} /* h1.title, h2.title, h3.title */
.title:not(h1, h2) {} /* multiple exclusions */
section:has(img, figure) {} /* parent selector */


이러한 선택기는 쉼표를 포함하지만 이러한 쉼표는 첫 번째 수준 선택기를 구분하지 않습니다.

브라우저가 이해하지 못하고:is 첫 번째 예를 분리하려고 하면 다음과 같은 결과가 나타날 수 있습니다.

.title:is(h1 /* What is this? Ignore */
h2 /* Style all the h2, even without the .title class! */
h3) /* Wut?*/



CSS 전기톱 학살

대신 브라우저는 신중합니다. 이는 2013년에 다시 논의되었으며 동일한 방식으로 유지되었습니다"due to Web-compat concerns" .

해킹



일부 개발자는 이것을 특정 브라우저를 구별하기 위한 해킹으로 사용하기도 했습니다.

IE를 제외한 모든 브라우저에 특정 스타일을 적용하고 싶습니까? IE가 규칙을 무시하도록 하는 유일한 목적으로 최신 선택기를 추가하기만 하면 됩니다.

.covfefe:not(div), h1 {
  color: red;
}


브라우저가 h1를 이해하는 경우에만 :not가 빨간색으로 표시됩니다.

선택기의 올바른 조합을 사용하여 특정 브라우저 버전을 대상으로 지정하거나 제외할 수 있습니다. 물론 매우 더럽고 더 이상 필요하지 않기를 바랍니다 🙏

좋은 웹페이지 즐겨찾기