모던 CSS 완벽 가이드: JS 없이 구현하는 마법, Nesting과 :has()

2026. 2. 23. 11:16Programming

반응형

UI 상태 하나 바꾸겠다고 오늘도 useStateonMouseEnter를 번갈아 가며 자바스크립트 코드를 짜셨나요?

혹은 복잡한 CSS 계층 구조를 잡기 위해 프로젝트 시작부터 습관적으로 Sass(SCSS) 환경부터 세팅하고 계시진 않나요?

 

이제 무거운 자바스크립트 연산과 외부 전처리기에서 벗어날 때가 되었습니다.

2026년 현재, 순수 네이티브 CSS만으로도 우리가 JS로 힘들게 구현했던 수많은 로직들을 단 몇 줄의 코드로 우아하게 처리할 수 있는 시대가 열렸습니다.

 

불필요한 렌더링을 줄이고 프론트엔드의 성능과 가독성을 한 단계 끌어올려 줄 모던 CSS의 두 가지 마법.

이제는 선택이 아닌 필수가 될 수도 있는 Nesting:has() 선택자의 진짜 위력을 실무 예제와 함께 살펴보겠습니다.

 

CSS Nesting 심화: 명시도(Specificity)의 이해

과거에는 중첩된 HTML 구조를 스타일링하기 위해 클래스명을 길게 나열하거나 전처리기를 꼭 써야 했습니다.

이제는 네이티브 CSS만으로 계층 구조를 직관적으로 표현할 수 있죠.

하지만 단순히 코드가 깔끔해지는 것을 넘어, 실무에 적용할 때 반드시 알아야 할 점은 바로 명시도(Specificity)의 작동 방식입니다.

내부적으로 Nesting:is() 의사 클래스로 감싸진 것처럼 동작합니다.

/* 작성한 CSS */
.card {
  h2, .title {
    color: red;
  }
}

/* 브라우저가 해석하는 방식 */
.card :is(h2, .title) {
  color: red;
}

 

:is()는 괄호 안의 선택자 중 가장 높은 명시도를 따릅니다. 따라서 위 예시에서 h2에만 스타일을 주더라도

.title의 명시도(클래스 선택자)가 반영되어 예상보다 우선순위가 높아질 수 있으므로 구조 설계 시 이 점을 반드시 유의해야 합니다.

 

:has() 선택자 심화: 관계형 선택자의 진가

그동안 CSS의 가장 큰 한계 중 하나는 자식 요소의 상태에 따라 부모 요소의 스타일을 변경할 수 없다는 것이었습니다.

:has() 의사 클래스는 이 문제를 완벽하게 해결합니다.

하지만 :has()를 '부모 선택자'로만 부르는 것은 이 기능의 절반만 이해한 것입니다. 부모뿐만 아니라 이전 형제(Previous Sibling) 요소전체 컨텍스트의 상태를 스타일링할 수 있는 진정한 의미의 '관계형 선택자'입니다.

 

실전 예제: JS 없는 형제 요소 하이라이트 효과 (Hover Spotlight) 특정 카드에 마우스를 올렸을 때, 주변의 다른 카드들은 흐리게 만드는 효과를 오직 CSS만으로 구현할 수 있습니다.

/* .grid 컨테이너 안에 마우스가 올라간 .card가 '하나라도 있다면' */
.grid:has(.card:hover) .card:not(:hover) {
  opacity: 0.5;
  filter: blur(2px);
  transition: all 0.3s ease;
}

/* 마우스가 올라간 본인 요소 */
.card:hover {
  transform: scale(1.05);
  box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}

 

과거라면 요소마다 마우스 이벤트를 걸고 React 상태로 관리하여 전체 리렌더링을 유발해야 했던 효과를 이렇게 단 몇 줄로 끝낼 수 있습니다.

 

성능 고려사항 (Performance Considerations)

'DOM 트리를 역추적하거나 복잡하게 탐색하면 렌더링 성능이 떨어지지 않을까?' 하는 걱정이 드실 수 있습니다.

하지만 최신 브라우저 엔진은 캐싱 및 무효화(Invalidation) 휴리스틱을 극도로 고도화하여 :has()의 성능을 매우 최적화했습니다.

극단적으로 깊고 복잡한 DOM 구조가 아니라면, 오히려 JS로 상태를 관리하며 리렌더링 파이프라인을 가동하는 것보다

브라우저 네이티브 단에서 처리하는 것이 성능 면에서 훨씬 효율적입니다.

 

마무리하며: 이제는 다시 '바닐라 CSS'를 돌아볼 때

수많은 프레임워크와 CSS-in-JS 라이브러리들이 쏟아지는 와중에도, 웹 표준은 묵묵히, 그리고 아주 강력하게 발전해 왔습니다.

Nesting과 :has()는 그 발전의 정점이라 할 수 있죠. 이 두 가지만 잘 활용해도 우리가 습관적으로 작성하던 불필요한 자바스크립트 코드의 절반은 덜어낼 수 있습니다.

여러분은 현재 프로젝트에서 어떤 CSS 방식을 주로 사용하고 계신가요? 여전히 Sass나 Styled-components의 강력함에 기대고 계신가요, 아니면 점진적으로 모던 순수 CSS나 Tailwind 같은 유틸리티 클래스로 넘어가고 계신가요?

반응형