한국어

부모 요소 선택의 판도를 바꾸는 CSS :has() 선택자를 탐색해 보세요. 실용적인 적용 사례, 브라우저 호환성, 고급 기술을 배워 CSS 스타일링을 혁신하세요.

CSS :has() 선택자 마스터하기: 강력한 부모 요소 선택 기능 활용

수년간 CSS 개발자들은 자식 요소를 기반으로 부모 요소를 선택할 수 있는 간단하고 효과적인 방법을 갈망해왔습니다. 이제 그 기다림이 끝났습니다! :has() 의사 클래스가 드디어 등장하여 우리가 CSS를 작성하는 방식을 혁신하고 있습니다. 이 강력한 선택자를 사용하면 특정 자식 요소를 포함하는 부모 요소를 타겟팅할 수 있어, 동적이고 반응적인 스타일링의 무한한 가능성을 열어줍니다.

:has() 선택자란 무엇인가?

:has() 의사 클래스는 선택자 목록을 인수로 받는 CSS 관계형 의사 클래스입니다. 이 선택자 목록의 선택자 중 하나라도 해당 요소의 하위 요소 중 하나 이상과 일치하면 그 요소를 선택합니다. 간단히 말해, 부모 요소가 특정 자식을 가지고 있는지(has) 확인하고, 만약 그렇다면 그 부모 요소가 선택됩니다.

기본 구문은 다음과 같습니다:

parent:has(child) { /* CSS 규칙 */ }

이는 parent 요소가 하나 이상의 child 요소를 포함할 경우에만 해당 parent 요소를 선택합니다.

:has()가 왜 중요한가?

전통적으로 CSS는 자식 요소를 기반으로 부모 요소를 선택하는 능력에 한계가 있었습니다. 이러한 제약 때문에 동적 스타일링을 구현하기 위해 복잡한 JavaScript 솔루션이나 우회 방법이 필요한 경우가 많았습니다. :has() 선택자는 이러한 번거로운 방법의 필요성을 없애고, 더 깨끗하고 유지보수하기 쉬우며 성능이 좋은 CSS 코드를 작성할 수 있게 해줍니다.

:has()가 판도를 바꾸는 이유는 다음과 같습니다:

:has() 선택자의 기본 예제

:has() 선택자의 강력함을 보여주는 몇 가지 간단한 예제부터 시작하겠습니다.

예제 1: 이미지 유무에 따라 부모 Div 스타일링하기

<div> 요소가 <img> 요소를 포함할 경우에만 테두리를 추가하고 싶다고 가정해 봅시다:

div:has(img) { border: 2px solid blue; }

이 CSS 규칙은 하나 이상의 <img> 요소를 포함하는 모든 <div>에 파란색 테두리를 적용합니다.

예제 2: Span 유무에 따라 리스트 아이템 스타일링하기

항목 리스트가 있고, 특정 클래스를 가진 <span> 요소를 포함하는 리스트 아이템을 강조하고 싶다고 가정해 봅시다:

li:has(span.highlight) { background-color: yellow; }

이 CSS 규칙은 클래스가 "highlight"인 <span>을 포함하는 모든 <li>의 배경색을 노란색으로 변경합니다.

예제 3: 입력 유효성에 따라 폼 레이블 스타일링하기

:has()를 사용하여 연결된 입력 필드가 유효한지 또는 유효하지 않은지에 따라 폼 레이블의 스타일을 지정할 수 있습니다 (:invalid 의사 클래스와 결합):

label:has(+ input:invalid) { color: red; font-weight: bold; }

이 코드는 바로 뒤따르는 입력 필드가 유효하지 않을 경우 레이블을 빨간색과 굵은 글씨로 만듭니다.

:has() 선택자의 고급 활용법

:has() 선택자는 다른 CSS 선택자 및 의사 클래스와 결합될 때 더욱 강력해집니다. 몇 가지 고급 사용 사례는 다음과 같습니다:

예제 4: 특정 자식이 없는 요소 타겟팅

:not() 의사 클래스를 :has()와 함께 사용하여 특정 자식을 *갖지 않는* 요소를 타겟팅할 수 있습니다. 예를 들어, 이미지를 포함하지 *않는* div의 스타일을 지정하려면 다음과 같이 합니다:

div:not(:has(img)) { background-color: #f0f0f0; }

이 코드는 <img> 요소를 포함하지 않는 모든 <div>에 밝은 회색 배경을 적용합니다.

예제 5: 복잡한 레이아웃 생성하기

:has() 선택자는 컨테이너의 내용에 따라 동적 레이아웃을 만드는 데 사용될 수 있습니다. 예를 들어, 그리드 셀 내에 특정 유형의 요소가 있는지 여부에 따라 그리드의 레이아웃을 변경할 수 있습니다.

.grid-container { display: grid; grid-template-columns: repeat(3, 1fr); } .grid-item:has(img) { grid-column: span 2; }

이 코드는 그리드 아이템이 이미지를 포함할 경우 두 개의 열에 걸쳐 표시되도록 합니다.

예제 6: 동적 폼 스타일링

:has()를 사용하여 폼 요소의 상태(예: 포커스, 채워짐, 유효함)에 따라 동적으로 스타일을 지정할 수 있습니다.

.form-group:has(input:focus) { box-shadow: 0 0 5px rgba(0, 0, 255, 0.5); } .form-group:has(input:valid) { border-color: green; } .form-group:has(input:invalid) { border-color: red; }

이 코드는 입력이 포커스될 때 파란색 그림자 효과를 추가하고, 입력이 유효하면 녹색 테두리를, 유효하지 않으면 빨간색 테두리를 추가합니다.

예제 7: 자식 요소 수에 기반한 스타일링

:has()가 직접적으로 자식의 수를 세지는 않지만, 다른 선택자 및 CSS 속성과 결합하여 유사한 효과를 얻을 수 있습니다. 예를 들어, :only-child를 사용하여 부모가 특정 유형의 자식을 하나만 가질 경우 스타일을 지정할 수 있습니다.

div:has(> p:only-child) { background-color: lightgreen; }

이 코드는 단일 <p> 요소를 직계 자식으로 포함하는 <div>에만 연두색 배경을 적용합니다.

크로스 브라우저 호환성 및 폴백(Fallbacks)

2023년 말 기준으로, :has() 선택자는 크롬, 파이어폭스, 사파리, 엣지를 포함한 최신 브라우저에서 훌륭한 지원을 받고 있습니다. 하지만, 특히 구형 브라우저를 지원해야 하는 경우 프로덕션 환경에 배포하기 전에 Can I use에서 호환성을 확인하는 것이 중요합니다.

호환성 고려 사항에 대한 분석은 다음과 같습니다:

폴백 제공하기

구형 브라우저를 지원해야 하는 경우 폴백을 제공해야 합니다. 몇 가지 전략은 다음과 같습니다:

기능 쿼리를 사용하는 예는 다음과 같습니다:

.parent { /* 모든 브라우저를 위한 기본 스타일링 */ border: 1px solid black; } @supports selector(:has(img)) { .parent:has(img) { /* :has()를 지원하는 브라우저를 위한 향상된 스타일링 */ border: 3px solid blue; } }

이 코드는 모든 브라우저에서 .parent 요소에 검은색 테두리를 적용합니다. :has()를 지원하는 브라우저에서는 .parent 요소가 이미지를 포함할 경우 파란색 테두리를 적용합니다.

성능 고려사항

:has()는 상당한 이점을 제공하지만, 특히 광범위하게 사용되거나 복잡한 선택자와 함께 사용될 때 성능에 미칠 수 있는 잠재적 영향을 고려하는 것이 중요합니다. 브라우저는 페이지의 모든 요소에 대해 선택자를 평가해야 하므로, 이는 연산 비용이 많이 들 수 있습니다.

:has()의 성능을 최적화하기 위한 몇 가지 팁은 다음과 같습니다:

피해야 할 일반적인 실수

:has() 선택자로 작업할 때 예상치 못한 결과를 초래할 수 있는 실수를 하기 쉽습니다. 피해야 할 몇 가지 일반적인 함정은 다음과 같습니다:

:has() 사용을 위한 모범 사례

:has() 선택자의 이점을 극대화하고 잠재적인 문제를 피하려면 다음 모범 사례를 따르세요:

실제 사례 및 사용 예시

:has() 선택자를 사용하여 일반적인 디자인 문제를 해결하는 방법에 대한 몇 가지 실제 예시를 살펴보겠습니다.

예제 8: 반응형 내비게이션 메뉴 만들기

:has()를 사용하여 특정 메뉴 항목의 유무에 따라 다른 화면 크기에 적응하는 반응형 내비게이션 메뉴를 만들 수 있습니다.

사용자가 로그인했는지 여부에 따라 다른 내비게이션 메뉴를 표시하려는 시나리오를 상상해 보세요. 로그인한 경우 프로필 및 로그아웃 작업을 표시할 수 있고, 그렇지 않은 경우 로그인/회원가입을 표시할 수 있습니다.

nav:has(.user-profile) { /* 로그인한 사용자를 위한 스타일 */ } nav:not(:has(.user-profile)) { /* 로그아웃한 사용자를 위한 스타일 */ }

예제 9: 카드 컴포넌트 스타일링

:has() 선택자는 내용에 따라 카드 컴포넌트의 스타일을 지정하는 데 사용될 수 있습니다. 예를 들어, 카드에 이미지가 포함된 경우에만 그림자를 추가할 수 있습니다.

.card:has(img) { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); }

예제 10: 동적 테마 구현

:has()를 사용하여 사용자 기본 설정이나 시스템 설정에 따라 동적 테마를 구현할 수 있습니다. 예를 들어, 사용자가 다크 모드를 활성화했는지 여부에 따라 페이지의 배경색을 변경할 수 있습니다.

body:has(.dark-mode) { background-color: #333; color: #fff; }

이러한 예들은 :has() 선택자의 다양성과 광범위한 디자인 문제를 해결할 수 있는 능력을 보여줍니다.

CSS의 미래: 다음은 무엇일까?

:has() 선택자의 도입은 CSS 발전의 중요한 한 걸음을 의미합니다. 이를 통해 개발자들은 JavaScript에 대한 의존도를 줄이면서 더 동적이고 반응적이며 유지보수하기 쉬운 스타일시트를 만들 수 있게 되었습니다. :has()에 대한 브라우저 지원이 계속 증가함에 따라, 이 강력한 선택자의 더욱 혁신적이고 창의적인 사용법을 보게 될 것으로 기대됩니다.

앞으로 CSS 워킹 그룹은 CSS의 기능을 더욱 확장할 다른 흥미로운 기능과 개선 사항을 탐색하고 있습니다. 여기에는 다음이 포함됩니다:

최신 CSS 개발 동향을 파악하고 :has()와 같은 새로운 기능을 수용함으로써 개발자들은 CSS의 잠재력을 최대한 발휘하고 진정으로 뛰어난 웹 경험을 만들 수 있습니다.

결론

:has() 선택자는 CSS 툴박스에 추가된 강력한 기능으로, 부모 요소 선택을 가능하게 하고 동적이고 반응적인 스타일링의 새로운 가능성을 열어줍니다. 브라우저 호환성 및 성능 영향을 고려하는 것이 중요하지만, 더 깨끗하고 유지보수하기 쉬우며 성능 좋은 CSS 코드를 위해 :has()를 사용하는 이점은 부인할 수 없습니다. 이 판도를 바꾸는 선택자를 받아들이고 오늘 여러분의 CSS 스타일링을 혁신하세요!

접근성을 고려하고 구형 브라우저를 위한 폴백 메커니즘을 제공하는 것을 잊지 마세요. 이 가이드에 설명된 모범 사례를 따르면 :has() 선택자의 잠재력을 최대한 활용하고 전 세계 사용자에게 진정으로 뛰어난 웹 경험을 제공할 수 있습니다.