관계 선택자 (Relation Selectors)

Atomic CSS의 가장 강력한 기능입니다. 부모-자식, 형제 관계를 활용해 특정 상태에서 다른 요소의 스타일을 변경할 수 있습니다. JavaScript 없이 호버 카드, 아코디언, 커스텀 체크박스 등 인터랙티브한 UI를 구현할 수 있습니다.

구문 (Syntax)

관계 선택자는 5개의 파트를 하이픈으로 연결합니다.

trigger-pseudo-relation-target-class
<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">파트설명예시
trigger부모/트리거 요소에 부여하는 클래스명card, nav, wrapper
pseudo트리거 요소의 상태 (의사 클래스)hover, checked, focus
relationCSS 결합자를 결정하는 키워드child, children, next, siblings
target스타일을 적용할 대상 요소의 태그명 또는 클래스명img, label, title, panel
class대상에 적용할 Atomic CSS 클래스ofc, db, c6366F1, ts1-1

구문 분석 예시

card-hover-child-img-ofc.card:hover > img { object-fit: cover }
checkbox-checked-next-label-c6366F1.checkbox:checked + label { color: #6366F1 }
wrapper-hover-children-link-cFFFFFF.wrapper:hover link { color: #FFFFFF }

관계 키워드 (Combinators)

4가지 CSS 결합자를 지원합니다. 키워드가 곧 결합자를 결정합니다.

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">키워드CSS 결합자선택 범위설명
child>직접 자식 (1단계)트리거의 바로 아래 자식 요소만 선택합니다
children(공백)모든 후손 (모든 깊이)트리거 하위의 모든 깊이의 후손 요소를 선택합니다
next+인접 형제 (1개)트리거 바로 다음에 오는 형제 요소 하나를 선택합니다
siblings~일반 형제 (전부)트리거 뒤에 오는 모든 형제 요소를 선택합니다

키워드별 상세

child> (직접 자식)

가장 많이 사용하는 관계 선택자입니다. 트리거 요소의 직접 자식만 선택합니다. 중첩된 자손은 영향을 받지 않습니다. 카드 호버, 네비게이션 드롭다운 등에 적합합니다.

예시 클래스

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">클래스생성 CSS설명
card-hover-child-img-ts1-1.card:hover > img { transform: scale(1.1) }카드 호버 시 이미지 확대
card-hover-child-title-c6366F1.card:hover > .title { color: #6366F1 }카드 호버 시 제목 색상 변경
nav-hover-child-dropdown-db.nav:hover > .dropdown { display: block }네비 호버 시 드롭다운 표시
card-hover-child-overlay-o100.card:hover > .overlay { opacity: 1 }카드 호버 시 오버레이 표시
btn-hover-child-icon-ttx4px.btn:hover > .icon { transform: translateX(4px) }버튼 호버 시 아이콘 이동
<!-- Card hover: image zoom + title color change -->
<div class="card-hover-child-img-ts1-1 card-hover-child-title-c6366F1 oh br8px">
  <img class="img w100p h20rem ofc tall300msease" src="photo.jpg" />
  <div class="p2rem">
    <h3 class="title cFAFAFA tall200msease">Title</h3>
    <p class="c71717A">Description Text</p>
  </div>
</div>
<!-- Generated CSS:
  .card:hover > .img { transform: scale(1.1) }
  .card:hover > .title { color: #6366F1 }
-->

<!-- Navigation dropdown -->
<li class="nav-hover-child-dropdown-db pr">
  <a href="#">Menu</a>
  <ul class="dropdown dn pa t100p l0 bg18181B br8px p16px">
    <li>Submenu 1</li>
    <li>Submenu 2</li>
  </ul>
</li>
<!-- Generated CSS: .nav:hover > .dropdown { display: block } -->

인터랙티브 데모 — 카드에 호버해 보세요

🏔

카드 제목

카드에 호버하면 이미지가 확대되고, 제목 색상이 변경되며, 이 설명 텍스트가 밝아집니다.

🌊

다른 카드

동일한 관계 선택자 패턴이지만 다른 색상 클래스를 사용합니다. 호버해 보세요.

children(공백) 후손 선택자

트리거 요소 하위의 모든 깊이의 후손을 선택합니다. 중첩 구조에서 깊이에 상관없이 모든 대상 요소에 스타일을 적용할 때 사용합니다.

child vs children

child는 직접 자식(1단계)만 선택하고, children은 모든 깊이의 후손을 선택합니다. 범위를 좁히고 싶다면 child를 사용하세요.

예시 클래스

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">클래스생성 CSS설명
wrapper-hover-children-link-cFFFFFF.wrapper:hover link { color: #FFFFFF }래퍼 호버 시 모든 후손 링크 색상 변경
wrapper-hover-children-p-cFAFAFA.wrapper:hover p { color: #FAFAFA }래퍼 호버 시 모든 후손 p 태그 색상 변경
container-hover-children-icon-c6366F1.container:hover icon { color: #6366F1 }컨테이너 호버 시 모든 후손 아이콘 색상 변경
<!-- Change color of all p tags at every depth on hover -->
<div class="wrapper-hover-children-p-cFFFFFF">
  <p>Direct child — applied</p>
  <div>
    <p>2nd level descendant — also applied</p>
    <div>
      <p>3rd level descendant — also applied</p>
    </div>
  </div>
</div>
<!-- Generated CSS: .wrapper:hover p { color: #FFFFFF } -->

<!-- Comparison with child -->
<div class="card-hover-child-p-cFFFFFF">
  <p>Direct child — applied</p>
  <div>
    <p>2nd level descendant — not applied because of child!</p>
  </div>
</div>
<!-- Generated CSS: .card:hover > p { color: #FFFFFF } (direct children only) -->

next+ (인접 형제)

트리거 요소 바로 다음에 오는 형제 하나만 선택합니다. input + label 조합에서 가장 자주 사용합니다. 체크박스 커스터마이징, 포커스 힌트 표시 등에 적합합니다.

예시 클래스

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">클래스생성 CSS설명
checkbox-checked-next-label-c6366F1.checkbox:checked + label { color: #6366F1 }체크 시 인접 라벨 색상 변경
checkbox-checked-next-label-fw700.checkbox:checked + label { font-weight: 700 }체크 시 인접 라벨 볼드
input-focus-next-hint-db.input:focus + .hint { display: block }인풋 포커스 시 힌트 표시
field-focus-next-hint-o100.field:focus + .hint { opacity: 1 }인풋 포커스 시 힌트 투명도 변경
toggle-checked-next-panel-db.toggle:checked + .panel { display: block }토글 체크 시 패널 표시
<!-- Checkbox: label color change -->
<div class="df aic gap8px">
  <input type="checkbox" id="agree"
    class="checkbox-checked-next-label-c6366F1 checkbox-checked-next-label-fw700" />
  <label for="agree" class="label cA1A1AA tall200msease">
    I agree to the terms
  </label>
</div>
<!-- Generated CSS:
  .checkbox:checked + label { color: #6366F1 }
  .checkbox:checked + label { font-weight: 700 }
-->

<!-- Input focus: show hint -->
<div>
  <input type="email" placeholder="Email"
    class="input-focus-next-hint-db" />
  <p class="hint dn fs12px c6366F1 mt4px">
    Please enter a valid email format
  </p>
</div>
<!-- Generated CSS: .input:focus + .hint { display: block } -->

인터랙티브 데모 — 체크박스를 클릭해 보세요

siblings~ (일반 형제)

트리거 요소 뒤에 오는 모든 형제를 선택합니다. next가 바로 다음 하나만 선택하는 반면, siblings는 뒤에 오는 모든 형제를 선택합니다. 아코디언, 토글 패널 등에 적합합니다.

예시 클래스

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">클래스생성 CSS설명
toggle-checked-siblings-panel-db.toggle:checked ~ .panel { display: block }토글 체크 시 모든 형제 패널 표시
toggle-checked-siblings-div-db.toggle:checked ~ div { display: block }토글 체크 시 모든 형제 div 표시
trigger-hover-siblings-item-o100.trigger:hover ~ .item { opacity: 1 }호버 시 모든 형제 아이템 표시
<!-- Accordion: toggle multiple panels with checkbox -->
<div>
  <input type="checkbox" id="acc-1"
    class="toggle-checked-siblings-panel-db dn" />
  <label for="acc-1" class="db py12px px16px bg18181B br8px cp cFAFAFA">
    Accordion title (click to open)
  </label>
  <div class="panel dn p16px c71717A lh1-7">
    This is the accordion body content. When the checkbox is checked,
    this panel and all .panel siblings below will be shown.
  </div>
</div>
<!-- Generated CSS: .toggle:checked ~ .panel { display: block } -->

<!-- Difference from next: next targets only the immediate next one, siblings targets all following -->
<input type="checkbox" class="trigger-checked-siblings-item-db dn" id="t1" />
<label for="t1">Toggle</label>
<div class="item dn">Sibling 1 — shown</div>
<div class="item dn">Sibling 2 — also shown</div>
<div class="item dn">Sibling 3 — also shown</div>
<!-- Generated CSS: .trigger:checked ~ .item { display: block } -->

의사 요소와의 조합

관계 선택자는 ::before, ::after 의사 요소와도 조합할 수 있습니다. 타겟 위치에 before 또는 after를 사용합니다.

<tr> <th class="tal py12px px16px bg18181B bb2pxsolid27272A cA1A1AA fw600 ttu fs12px ls0-05em">클래스생성 CSS
card-hover-child-before-o100.card:hover > ::before { opacity: 1 }
card-hover-child-after-w100p.card:hover > ::after { width: 100% }
link-hover-child-after-ts1.link:hover > ::after { transform: scale(1) }
<!-- Underline animation on hover (using ::after) -->
<a class="link-hover-child-after-w100p pr tdn cFAFAFA">
  <!-- Create underline with ::after, set width to 100% on hover -->
  Link text
</a>

<!-- Show overlay on hover (using ::before) -->
<div class="card-hover-child-before-o100 pr oh">
  <!-- Use ::before as overlay, opacity: 1 on hover -->
  <img src="photo.jpg" class="w100p" />
</div>

실전 패턴

관계 선택자를 활용한 실제 UI 패턴입니다. JavaScript 없이 순수 CSS로 구현됩니다.

패턴 1 호버 카드 (이미지 줌 + 텍스트 변경)

카드에 호버하면 이미지가 확대되고 텍스트 색상이 변경됩니다. childhover를 조합합니다.

<!-- Hover card: image zoom + title color + description brightness change -->
<div class="card-hover-child-img-ts1-1
            card-hover-child-title-c6366F1
            card-hover-child-desc-cFAFAFA
            bg0F0F17 b1pxsolid27272A br8px oh cp">
  <div class="oh">
    <img class="img w100p h20rem ofc tall300msease" src="photo.jpg" />
  </div>
  <div class="p2rem">
    <h3 class="title cA1A1AA fs16px fw700 mb4px tall200msease">
      Project title
    </h3>
    <p class="desc c71717A fs14px lh1-6 tall200msease">
      On card hover, the image zooms in and the title and description colors change.
    </p>
  </div>
</div>

패턴 2 아코디언 (체크박스 + siblings)

숨겨진 체크박스를 토글 트리거로 사용하고, siblings로 패널을 표시합니다. JavaScript 없이 작동합니다.

<!-- Pure CSS accordion -->
<div class="df fdc gap4px">
  <!-- Item 1 -->
  <div>
    <input type="checkbox" id="acc-1"
      class="toggle-checked-siblings-panel-maxh50rem dn" />
    <label for="acc-1"
      class="db py12px px16px bg18181B br8px cp cFAFAFA fw600 hover-bg27272A">
      Section 1: What are relation selectors?
    </label>
    <div class="panel maxh0 oh tall300msease p0 lh1-7 c71717A">
      <div class="p16px">
        Relation selectors are a unique feature of Atomic CSS,
        leveraging parent-child relationships to implement
        style changes based on state.
      </div>
    </div>
  </div>

  <!-- Item 2 -->
  <div>
    <input type="checkbox" id="acc-2"
      class="toggle-checked-siblings-panel-maxh50rem dn" />
    <label for="acc-2"
      class="db py12px px16px bg18181B br8px cp cFAFAFA fw600 hover-bg27272A">
      Section 2: What keywords are available?
    </label>
    <div class="panel maxh0 oh tall300msease p0 lh1-7 c71717A">
      <div class="p16px">
        Four keywords are supported: child, children, next, siblings.
        They correspond to CSS combinators >, (space), +, ~ respectively.
      </div>
    </div>
  </div>
</div>

패턴 3 커스텀 체크박스 + 라벨 스타일링

체크박스 상태에 따라 인접 라벨의 스타일을 변경합니다. nextchecked를 조합합니다.

<!-- Custom checkbox + label styling -->
<div class="df fdc gap12px">
  <div class="df aic gap12px">
    <input type="checkbox" id="opt-1"
      class="checkbox-checked-next-label-c6366F1
             checkbox-checked-next-label-fw700" />
    <label for="opt-1" class="label cA1A1AA cp tall200msease">
      Premium plan
    </label>
  </div>

  <div class="df aic gap12px">
    <input type="checkbox" id="opt-2"
      class="checkbox-checked-next-label-c34D399
             checkbox-checked-next-label-fw700" />
    <label for="opt-2" class="label cA1A1AA cp tall200msease">
      Newsletter subscription
    </label>
  </div>

  <div class="df aic gap12px">
    <input type="checkbox" id="opt-3"
      class="checkbox-checked-next-label-cF87171
             checkbox-checked-next-label-fw700
             checkbox-checked-next-label-tdu" />
    <label for="opt-3" class="label cA1A1AA cp tall200msease">
      Agree to terms (required)
    </label>
  </div>
</div>

패턴 4 드롭다운 메뉴

네비게이션 호버 시 드롭다운을 표시합니다. childhover를 사용합니다.

<!-- Hover dropdown menu -->
<nav class="df gap2rem">
  <div class="nav-hover-child-dropdown-db pr">
    <a href="#" class="cFAFAFA tdn py8px db">Products</a>
    <div class="dropdown dn pa t100p l0 bg18181B b1pxsolid27272A br8px p8px minw16rem zi10">
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Features</a>
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Pricing</a>
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Case studies</a>
    </div>
  </div>

  <div class="nav-hover-child-dropdown-db pr">
    <a href="#" class="cFAFAFA tdn py8px db">Resources</a>
    <div class="dropdown dn pa t100p l0 bg18181B b1pxsolid27272A br8px p8px minw16rem zi10">
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Docs</a>
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Blog</a>
      <a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">Community</a>
    </div>
  </div>
</nav>

패턴 5 인풋 포커스 힌트

인풋에 포커스하면 힌트 메시지가 나타납니다. nextfocus를 조합합니다.

<!-- Show hint message on input focus -->
<div class="df fdc gap16px">
  <div>
    <input type="email" placeholder="Email address"
      class="field-focus-next-hint-db
             w100p py8px px12px bg18181B b1pxsolid27272A br6px cFAFAFA fs14px" />
    <p class="hint dn fs12px c6366F1 mt4px">
      Please enter a valid email address
    </p>
  </div>

  <div>
    <input type="password" placeholder="Password"
      class="field-focus-next-hint-db
             w100p py8px px12px bg18181B b1pxsolid27272A br6px cFAFAFA fs14px" />
    <p class="hint dn fs12px c34D399 mt4px">
      At least 8 characters, combination of letters + numbers recommended
    </p>
  </div>
</div>

인터랙티브 데모 — 인풋을 클릭해 보세요

유효한 이메일 주소를 입력하세요

8자 이상, 영문+숫자 조합

사용 가능한 의사 클래스

관계 선택자의 pseudo 위치에 사용할 수 있는 의사 클래스입니다.

인터랙션

hoverfocusfocus-withinfocus-visibleactive

입력 상태

checkeddisabledenabledindeterminate

폼 검증

validinvalidrequiredoptionalin-rangeout-of-range

기타

placeholder-shownemptyread-onlytargetvisitedany-link

팁 & 주의사항

trigger는 클래스, target은 태그명 또는 클래스명

trigger는 부모 요소에 부여하는 클래스명입니다. target은 자식 요소의 태그명(img, p, span 등)이나 클래스명을 사용합니다.

하나의 트리거에 여러 관계 클래스 사용 가능

같은 요소에 card-hover-child-img-ts1-1card-hover-child-title-c6366F1을 동시에 사용할 수 있습니다. 호버 한 번으로 여러 자식의 스타일을 변경합니다.

트랜지션과 함께 사용하세요

타겟 요소에 tall200msease 같은 트랜지션 클래스를 함께 사용하면 부드러운 전환 효과를 얻을 수 있습니다.

가독성을 유지하세요

관계 선택자는 매우 강력하지만, 클래스명이 길어질 수 있습니다. 하나의 요소에 관계 선택자를 3~4개 이상 사용하면 읽기 어려워질 수 있습니다. 복잡한 인터랙션은 JavaScript를 고려하세요.

next vs siblings 선택 기준

바로 다음 형제 하나만 제어하면 next, 여러 형제를 동시에 제어하면 siblings를 사용하세요. 대부분의 경우 next가 더 정확합니다.