• 검색어를 입력해 주세요.
  • 검색어를 입력해 주세요.
디자인키트 0
블로그 전체목록
화살표

보고계신 기능이 적용된
템플릿이에요!

HTML소스를 구매하시면
전체 소스를 활용하실 수 있어요!

  • 템플릿을 찾지 못했어요!

400여개 디자인

더 많은 템플릿 보기

CSS :has() 선택자, JavaScript 없이 상태 변화 UI를 만들 수 있을까?

CSS 26.07.10 조회 13



홈페이지에서 체크박스나 입력창을 클릭했을 때, 주변 박스의 색이 바뀌거나 선택한 영역 전체가 강조되는 화면을 자주 볼 수 있습니다. 이런 효과는 사용자가 현재 어떤 항목을 선택했는지 쉽게 알아볼 수 있게 해줍니다.

예전에는 이런 상태 변화 UI를 만들 때 JavaScript로 클래스를 추가하거나 제거하는 방식을 많이 사용했습니다. 하지만 간단한 스타일 변화라면 CSS만으로도 처리할 수 있는 경우가 있습니다. 그때 활용할 수 있는 선택자가 바로 :has()입니다.

CSS :has() 선택자를 사용하면 체크박스가 선택됐을 때 부모 박스를 강조하거나, input에 포커스가 들어왔을 때 폼 영역 전체의 스타일을 바꾸는 식의 표현이 가능합니다.

다만 :has()가 모든 JavaScript 기능을 대신하는 것은 아닙니다. 화면의 간단한 상태 표현은 CSS로 처리할 수 있지만, 데이터 저장, API 요청, 클릭 후 복잡한 동작 실행처럼 기능 제어가 필요한 영역은 JavaScript가 필요합니다.

핵심은 간단한 상태 표현은 CSS :has()로 처리할 수 있지만, 실제 기능 실행까지 모두 대체할 수는 없다는 점입니다.

CSS만으로 부족했던 상태 변화 UI

기존 CSS 선택자는 보통 위에서 아래 방향으로 요소를 선택했습니다. 예를 들어 부모 안에 있는 자식 요소를 꾸미는 것은 쉽지만, 자식 요소의 상태에 따라 부모 요소를 바꾸는 것은 쉽지 않았습니다.

체크박스를 선택했을 때 전체 카드 배경을 바꾸거나, input에 포커스가 들어왔을 때 폼 박스 전체를 강조하려면 JavaScript로 클래스를 추가하는 방식을 자주 사용했습니다.

CSS :has() 선택자는 이런 상황에서 유용합니다. 특정 요소가 내부에 어떤 요소를 가지고 있는지, 그 요소가 어떤 상태인지 확인한 뒤 부모나 주변 요소의 스타일을 바꿀 수 있습니다.

CSS :has() 선택자는 어떻게 사용할까요?

기본 구조는 간단합니다.

.parent:has(.child) {
    border-color: #2563eb;
}

위 코드는 .parent 안에 .child가 있을 때 부모 요소의 스타일을 바꾸는 방식입니다.

상태 선택자와 함께 사용하면 더 실무적인 UI를 만들 수 있습니다.

.form-box:has(input:focus) {
    border-color: #2563eb;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

이 코드는 input에 포커스가 들어왔을 때 input만 강조하는 것이 아니라, input을 감싸고 있는 폼 박스 전체를 강조합니다. 사용자가 현재 어느 입력 영역에 있는지 더 분명하게 보여줄 수 있습니다.

체크박스 선택 상태에 따라 카드 강조하기

서비스 선택, 옵션 선택, 약관 동의처럼 체크 상태를 시각적으로 보여줘야 하는 UI에도 :has()를 적용할 수 있습니다.

<label class="option-card">
    <input type="checkbox">
    <span>프리미엄 옵션 선택</span>
</label>
.option-card {
    display: block;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 12px;
}

.option-card:has(input:checked) {
    border-color: #2563eb;
    background: #f4f8ff;
}

체크박스가 선택되면 카드 전체가 강조됩니다. 사용자는 작은 체크박스만 보는 것이 아니라 선택한 영역 전체를 시각적으로 확인할 수 있습니다.

이런 방식은 가격 옵션, 문의 유형 선택, 예약 항목 선택, 설문 폼 같은 화면에서 활용하기 좋습니다.


입력 상태에 따라 라벨이나 버튼 바꾸기

입력값이 있는지에 따라 스타일을 다르게 보여줄 수도 있습니다.

.input-wrap:has(input:not(:placeholder-shown)) label {
    color: #2563eb;
    font-weight: 600;
}

입력창에 값이 들어가면 라벨을 강조하는 방식입니다. 단순히 예쁘게 보이기 위한 효과가 아니라, 사용자가 어떤 항목을 작성했는지 확인하기 쉽게 만드는 데 도움이 됩니다.

다만 실제 유효성 검사나 제출 가능 여부 판단은 CSS만으로 처리하는 데 한계가 있습니다. 입력값을 서버로 보내거나 오류 메시지를 세밀하게 제어해야 한다면 JavaScript와 함께 구성해야 합니다.

JavaScript 없이 처리하기 좋은 경우

:has()는 화면의 상태를 보여주는 데 적합합니다. 특히 아래와 같은 작업은 CSS만으로도 충분히 처리할 수 있습니다.

  • 체크된 옵션 카드 강조
  • 포커스된 입력 박스 강조
  • 특정 요소가 있을 때 부모 박스 스타일 변경
  • 이미지가 포함된 카드와 텍스트 카드의 레이아웃 구분
  • 선택된 항목에 따라 간단한 배경색·테두리 변경

반대로 클릭 후 데이터를 저장하거나, 팝업을 열고 닫거나, 서버와 통신해야 하는 기능은 JavaScript가 필요합니다. :has()는 기능 구현 도구라기보다 상태에 맞춰 스타일을 바꾸는 CSS 선택자로 보는 것이 정확합니다.

사용할 때 주의할 점

:has()는 편리하지만 너무 넓은 범위에 무분별하게 사용하면 관리가 어려워질 수 있습니다. 예를 들어 body:has()처럼 페이지 전체를 대상으로 조건을 걸면 작은 DOM 변화에도 브라우저가 넓은 범위를 다시 확인해야 할 수 있습니다.

가능하면 특정 컴포넌트나 폼 영역처럼 범위를 좁혀 사용하는 것이 좋습니다.

/* 범위가 너무 넓은 방식 */
body:has(.is-active) {
    background: #f8fafc;
}

/* 범위를 좁힌 방식 */
.tab-box:has(.is-active) {
    background: #f8fafc;
}

실무에서는 “어디까지 CSS로 처리할지”를 먼저 정하는 것이 중요합니다. 단순한 강조 효과는 CSS로 처리하고, 실제 동작은 JavaScript로 분리하면 코드 관리가 더 쉬워집니다.

적용 전 체크리스트

  • 자식 요소의 상태에 따라 부모 스타일을 바꿔야 하는가?
  • 단순한 시각 변화인지, 실제 기능 실행이 필요한 동작인지 구분했는가?
  • body, :root처럼 너무 넓은 범위에 적용하고 있지 않은가?
  • 체크박스, input, 카드, 폼처럼 범위를 좁힐 수 있는 구조인가?
  • CSS만으로 처리했을 때 접근성이나 사용성 문제가 없는가?
  • 지원해야 할 브라우저 환경에서 정상적으로 작동하는가?

:has()는 잘 쓰면 JavaScript 코드를 줄일 수 있지만, 모든 상태 관리를 CSS로 몰아넣는 방식은 좋지 않습니다. 스타일 변화와 기능 실행의 역할을 나눠야 합니다.

자주 묻는 질문

Q. CSS :has() 선택자는 부모 선택자인가요?

부모 요소를 조건에 따라 선택할 수 있어 부모 선택자처럼 활용할 수 있습니다. 다만 정확히는 전달한 조건에 맞는 요소가 있는지 확인해 해당 요소를 선택하는 CSS 의사 클래스입니다.

Q. :has()를 쓰면 JavaScript가 필요 없어지나요?

일부 UI 강조 효과는 JavaScript 없이 만들 수 있습니다. 하지만 데이터 처리, 클릭 이벤트, 서버 요청, 복잡한 상태 관리는 JavaScript가 필요합니다.

Q. 폼 UI에 :has()를 사용해도 괜찮나요?

포커스 표시, 체크 상태 강조, 입력 여부에 따른 스타일 변경에는 유용합니다. 다만 실제 유효성 검사와 오류 처리까지 CSS만으로 해결하려고 하면 한계가 있습니다.

Q. :has()는 성능 문제가 있나요?

범위를 좁혀 사용하면 일반적인 UI에서는 충분히 활용할 수 있습니다. 하지만 너무 넓은 부모 요소에 복잡한 조건을 걸면 성능에 부담이 될 수 있으므로 컴포넌트 단위로 제한하는 것이 좋습니다.

상태 변화 UI는 CSS로도 더 유연해졌습니다

CSS :has() 선택자는 자식 요소의 상태를 기준으로 부모나 주변 UI를 바꿀 수 있게 해줍니다. 체크박스 선택, input 포커스, 카드 구성 차이처럼 화면의 상태를 보여주는 작업에서는 JavaScript 없이도 충분히 깔끔한 처리가 가능합니다.

디자인키트의 HTML 템플릿이나 웹디자인 소스를 참고하거나 수정할 때도 간단한 상태 변화까지 모두 JavaScript로 처리할 필요는 없습니다. CSS로 표현할 수 있는 부분과 JavaScript가 필요한 기능을 구분해서 보면, UI 구조를 더 명확하게 이해하는 데 도움이 됩니다.



블로그 전체목록
디자인키트 카카오상담