[CSS] 근접, 자식요소에 따라 부모요소를 제어할 때 :has()

:has() 선택자는 언제 필요한가요?

코드를 작성하다보면 근접요소, 자식요소에 따라 특정 엘리먼트의 디자인을 제어해야 할 때가 있습니다. 그동안의 CSS는 근접요소, 자식요소만 컨트롤이 가능했습니다. 부모/상위 요소를 제어하기 위해서는 자바스크립트를 이용해야만 했습니다. 이제는 상위에 있는 요소를 제어할 수 있는 방법이 생겼습니다.

 

예를 들어서 제목+본문으로 된 구성과 제목+부연설명+본문으로 구성된 박스가 혼용된 디자인을 만들어보겠습니다. 

<h2> 제목 아래에 margin을 20픽셀로 주었습니다. 그런데 인접한 p태그에 부연설명이 들어간다면 <h2> 태그 아래의 마진은 5픽셀, 부연설명 <p> 태그의 마진을 20픽셀 주어야 합니다.

:has()를 위한 디자인 예시

 

해결책은 여러 가지가 있습니다. <h2>에는 여백을 주지 않고 본문용 <p> 태그 상단에 여백을 주는 것이 가장 안전한 방법이겠지만 지금은 :has() 선택자를 활용한 예제이니 선택자를 이용해 해결해보겠습니다.

 

:has() 선택자 활용 예시

:has()는 단어 뜻 그대로 '가지고 있다'로 이해하면 됩니다. 어떤 '조건 값'을 '가지고 있을 때' 특정 엘리먼트에 대한 속성이지요.

h2:has( + p.info ) {...} 는 "h2 태그에 p.info가 근접해있을 때 ...를 적용해라"라는 의미로 해석할 수 있습니다. 

div.wrap {
    display:flex; gap:10px; width:1100px; margin:0 auto;
    div.item { 
        flex:1; padding:30px; border:1px solid #ddd; 
        h2 { padding: 0; margin-bottom:20px; }
        h2:has( + p.info ) { margin-bottom:5px; }
        p.info { margin-bottom:20px; font-size:13px; color:#999; }
    }
}

 

부연설명이 있을 때와 없을 때 margin 비교화면

 

조건이 둘 이상일 때는 아래와 같이 콤마로 여러 조건을 넣을 수 있습니다. h2 태그 근접해서 p.info 또는(OR) p.warning을 가지고 있을 때 h2의 글자색을 어두운 파란색으로 지정하는 코드입니다.

h2:has(+p.info, +p.warning) { color:darkblue; }

 

그렇다면 AND 방식으로 조건을 모두 만족했을 때 제어하려면 어떻게 해야 할까요? 

h2태그와 p 태그가 인접해있고 && 클래스명이 .info인 요소인 경우에만 h2의 margin-bottom:5px가 적용됩니다. 결국 +p.info와 동일한 효과를 갖게 되지요. h2와 인접한 요소가 span.info라면 마진은 여전히 20픽셀로 유지됩니다.

h2 { margin-bottom:20px; }
h2:has(+p):has(+.info) { margin-bottom:5px; }
p.info { color:#333; }
span.info { color:crimson; }

 

브라우저 호환성

이 기능은 2023년 12월 이후 릴리즈된 최신 브라우저에서만 호환됩니다. 지금은 실무에서 사용하기 어려운 선택자이지만 향후 몇년 이내에 안정화가 되지 않을까 기대하고 있습니다.

has()의 브라우저 호환성

'HTML&CSS' 카테고리의 다른 글

CSS :where() 선택자  (0) 2024.09.26
CSS :not() 선택자 (~이 아닐 때)  (0) 2024.09.25
CSS의 중첩 (CSS nesting)  (0) 2024.09.16
CSS의 변수(Variables)  (0) 2024.09.15
티스토리 제목(h2, h3, h4) 글자크기 바꾸는 방법  (0) 2024.09.15