요약

  • W3C의 2018년 11월 Selectors Level 4 초안은 자식이나 뒤따르는 형제를 기준으로 요소를 고르는 :has()를 설명했지만, 당시의 실시간 CSS 선택 프로필에서는 제외했다.
  • 2022년 5월 초안은 프로필 구분을 없애고 :has()를 선택적이고 위험 표시가 붙은 기능으로 두었다. 11월 개정은 :has()의 중첩과 일반 의사 요소를 인자 안에서 제한했다.

신문 첫 화면에는 사진이 딸린 기사 카드도 있고 제목과 한 줄 소개만 있는 카드도 있다. 사진이 들어온 카드에는 넓은 여백이 어울린다. CSS가 카드 안의 사진을 찾아 꾸미는 것은 오래된 일이다. 사진이 있다는 이유로 카드 자체를 고르려면 별도 심부름이 필요했다. 템플릿이 클래스를 하나 더 달거나, 스크립트가 자식 요소를 세거나, 이미 문서에 있는 사실을 다시 장부에 적었다. 사진은 거실 한가운데 있는데 현관은 입주 신고서를 기다리는 셈이다.

2018년 11월 21일 W3C 초안에는 이미 질문의 문장이 있었다. a:has(> img)는 이미지를 직접 자식으로 가진 링크를 고른다. 선택되는 대상은 링크이고, 이미지는 그 조건을 입증한다. dt:has(+ dt)는 바로 뒤에 또 다른 정의 용어가 오는 정의 용어를 고른다. 흔히 말하는 “부모 선택자”라는 별명은 첫 사례에는 어울리지만 두 번째에는 좁다. :has()는 자식뿐 아니라 바로 옆 이웃과의 관계도 묻는다.

그런데 2018년 문서에서는 이 질문에 출입 제한이 있었다. 초안은 선택자를 실시간 프로필과 스냅숏 프로필로 나눴다. 실시간 프로필은 브라우저의 계속 변하는 CSS 선택에 적합하고, 스냅숏 프로필은 어느 시점의 정적인 문서 나무를 확인하는 데 알맞다. querySelector()가 후자의 예로 등장했다. :has()는 스냅숏에 들어가고 실시간 프로필에서는 빠졌다. 검사 도구는 카드 안의 사진을 물을 수 있어도, 살아 있는 스타일시트는 당시 초안의 규칙대로라면 그 질문을 쓸 수 없었다. 문서가 구현자에게 이 구분을 검토해 달라고 한 까닭이다. 편지는 써 놓고 우체통 앞에 줄을 세웠다.

2022년 5월 7일 초안은 우체통을 바꿨다. 변경 기록에 따르면 프로필 구분을 없애고 :has()를 선택적이며 at-risk인 기능으로 표시했다. 정적인 조회는 되고 실시간 CSS는 안 된다는 선이 사라졌다. 이 초안에서 지원 여부는 각 구현이 선택한다. 규칙은 편지의 배달 경로를 열었고, 브라우저는 수신 여부를 정하게 되었다.

기호 하나가 누구를 조사할지 정한다. a:has(> img)의 >는 직접 자식을 뜻한다. dt:has(+ dt)의 +는 바로 다음 형제를 가리킨다. 콜론 앞에는 선택할 요소가 있고, 괄호 안에는 그 요소를 기준으로 검사할 관계가 있다. 카드는 자기 안에 사진이 있으면 여백을 넓힐 수 있고, 나란히 선 두 용어는 짝처럼 보이게 할 수 있다. 문서 나무에 새 주민을 들일 필요는 없다. 원래 있던 관계를 확인하면 된다.

2022년 5월 초안은 편집자를 시험할 만한 괄호 문제도 보여 준다. section:not(:has(h1, h2, h3, h4, h5, h6))은 하위에 제목이 없는 구역을 찾는다. section:has(:not(h1, h2, h3, h4, h5, h6))은 제목이 아닌 하위 요소가 하나라도 있는 구역을 찾는다. 제목이 멀쩡하게 있고 평범한 문단도 있으면 두 번째 조건에 맞을 수 있다. 괄호 자리를 바꿨을 뿐인데 질문의 대상이 달라졌다. 조그만 문장 부호가 기사 카드의 운명을 결정한다.

2022년 11월 11일 개정은 호기심에 경계선을 그었다. :has() 안에 또 :has()를 넣을 수 없고, 의사 요소도 대체로 인자로 넣을 수 없다. 어떤 의사 요소는 조상의 스타일에 따라 생긴다. 조상이 자기 스타일이 만들어 낸 결과를 근거로 다시 자기 스타일을 정하면 순환이 일어난다. 가족회의가 다음 가족회의를 낳고, 그 회의가 첫 회의의 참가자 명단을 바꾸는 일은 여기서 끝낸 것이다.

W3C 발행 이력은 2018년과 2022년 초안의 위치를 보여 준다. 한때 정적인 검사 쪽에서만 허용된 관계 질문이, 프로필 구분을 벗어난 선택적 CSS 기능으로 자리 잡아 갔다. 브라우저는 문서 나무의 관계를 판정한다. 발행자는 어떤 관계가 화면을 바꿀 가치가 있는지 정한다. 사진이 있는 카드라면 사진에 자리를 내준다. 연속된 용어라면 함께 읽히게 만든다. 현관은 집 안의 일을 알기 위해 매번 새 출입 명부를 요구할 필요가 없다.

부모가 드디어 편지를 읽었다. 바로 옆집에서도 소식이 왔다.