한 줄 요약 - CSS :has()는 부모가 안에 든 자식의 상태를 보고 스스로 스타일을 바꾸는 선택자입니다. 예전엔 JS로만 하던 '입력이 맞으면 칸 전체를 초록으로' 같은 일을 CSS 한 줄로 처리합니다.
무슨 일이에요?
CSS 선택자는 늘 위에서 아래(부모에서 자식)로만 흘렀습니다. 자식의 상태를 보고 부모를 바꿀 방법이 없어서, 폼 검증 색 같은 건 onChange 이벤트를 듣고 부모에 클래스를 붙였다 떼는 자바스크립트가 필요했어요. :has()는 그 방향을 뒤집어, 부모가 자식(:valid, :checked, 이미지 유무 등)을 보고 반응하게 합니다. 주요 브라우저에 모두 들어와 안심하고 쓸 수 있는 단계(Baseline)입니다.
왜 좋아요?
폼 검증, 체크 강조, 이미지 유무에 따른 레이아웃 전환을 JS 이벤트 없이 처리합니다.
상태가 바뀔 때 리렌더가 없어 가볍고, 마크업도 깔끔해집니다.
주의할 점
:invalid 대신 :user-invalid를 쓰면 사용자가 입력하기 전부터 빨갛게 뜨는 문제를 막을 수 있어요. 또 body:has(...)처럼 너무 넓게 걸면 느려질 수 있으니 필요한 부모에만 좁게 거는 게 좋습니다. 실제 동작은 아래 관련 데모에서 직접 만져볼 수 있습니다.
