관계 선택자 (Relation Selectors)
Atomic CSS의 가장 강력한 기능입니다. 부모-자식, 형제 관계를 활용해 특정 상태에서 다른 요소의 스타일을 변경할 수 있습니다. JavaScript 없이 호버 카드, 아코디언, 커스텀 체크박스 등 인터랙티브한 UI를 구현할 수 있습니다.
구문 (Syntax)
관계 선택자는 5개의 파트를 하이픈으로 연결합니다.
trigger-pseudo-relation-target-class| 파트 | 설명 | 예시 |
|---|---|---|
| trigger | 부모/트리거 요소에 부여하는 클래스명 | card, nav, wrapper |
| pseudo | 트리거 요소의 상태 (의사 클래스) | hover, checked, focus |
| relation | CSS 결합자를 결정하는 키워드 | 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 결합자를 지원합니다. 키워드가 곧 결합자를 결정합니다.
| 키워드 | CSS 결합자 | 선택 범위 | 설명 |
|---|---|---|---|
child | > | 직접 자식 (1단계) | 트리거의 바로 아래 자식 요소만 선택합니다 |
children | (공백) | 모든 후손 (모든 깊이) | 트리거 하위의 모든 깊이의 후손 요소를 선택합니다 |
next | + | 인접 형제 (1개) | 트리거 바로 다음에 오는 형제 요소 하나를 선택합니다 |
siblings | ~ | 일반 형제 (전부) | 트리거 뒤에 오는 모든 형제 요소를 선택합니다 |
키워드별 상세
child> (직접 자식)
가장 많이 사용하는 관계 선택자입니다. 트리거 요소의 직접 자식만 선택합니다. 중첩된 자손은 영향을 받지 않습니다. 카드 호버, 네비게이션 드롭다운 등에 적합합니다.
예시 클래스
| 클래스 | 생성 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) } | 버튼 호버 시 아이콘 이동 |
<!-- 카드 호버 → 이미지 확대 + 제목 색상 변경 -->
<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">제목</h3>
<p class="c71717A">설명 텍스트</p>
</div>
</div>
<!-- 생성 CSS:
.card:hover > .img { transform: scale(1.1) }
.card:hover > .title { color: #6366F1 }
-->
<!-- 네비게이션 드롭다운 -->
<li class="nav-hover-child-dropdown-db pr">
<a href="#">메뉴</a>
<ul class="dropdown dn pa t100p l0 bg18181B br8px p16px">
<li>서브메뉴 1</li>
<li>서브메뉴 2</li>
</ul>
</li>
<!-- 생성 CSS: .nav:hover > .dropdown { display: block } -->인터랙티브 데모 — 카드에 호버해 보세요
카드 제목
카드에 호버하면 이미지가 확대되고, 제목 색상이 변경되며, 이 설명 텍스트가 밝아집니다.
다른 카드
동일한 관계 선택자 패턴이지만 다른 색상 클래스를 사용합니다. 호버해 보세요.
children(공백) 후손 선택자
트리거 요소 하위의 모든 깊이의 후손을 선택합니다. 중첩 구조에서 깊이에 상관없이 모든 대상 요소에 스타일을 적용할 때 사용합니다.
child vs children
child는 직접 자식(1단계)만 선택하고, children은 모든 깊이의 후손을 선택합니다. 범위를 좁히고 싶다면 child를 사용하세요.
예시 클래스
| 클래스 | 생성 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 } | 컨테이너 호버 시 모든 후손 아이콘 색상 변경 |
<!-- 호버하면 모든 깊이의 p 태그 색상 변경 -->
<div class="wrapper-hover-children-p-cFFFFFF">
<p>직접 자식 — 적용됨</p>
<div>
<p>2단계 후손 — 이것도 적용됨</p>
<div>
<p>3단계 후손 — 이것도 적용됨</p>
</div>
</div>
</div>
<!-- 생성 CSS: .wrapper:hover p { color: #FFFFFF } -->
<!-- child와의 차이 비교 -->
<div class="card-hover-child-p-cFFFFFF">
<p>직접 자식 — 적용됨</p>
<div>
<p>2단계 후손 — child이므로 적용 안 됨!</p>
</div>
</div>
<!-- 생성 CSS: .card:hover > p { color: #FFFFFF } (직접 자식만) -->next+ (인접 형제)
트리거 요소 바로 다음에 오는 형제 하나만 선택합니다. input + label 조합에서 가장 자주 사용합니다. 체크박스 커스터마이징, 포커스 힌트 표시 등에 적합합니다.
예시 클래스
| 클래스 | 생성 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 } | 토글 체크 시 패널 표시 |
<!-- 체크박스 → 라벨 색상 변경 -->
<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">
이용약관에 동의합니다
</label>
</div>
<!-- 생성 CSS:
.checkbox:checked + label { color: #6366F1 }
.checkbox:checked + label { font-weight: 700 }
-->
<!-- 인풋 포커스 → 힌트 표시 -->
<div>
<input type="email" placeholder="이메일"
class="input-focus-next-hint-db" />
<p class="hint dn fs12px c6366F1 mt4px">
유효한 이메일 형식으로 입력하세요
</p>
</div>
<!-- 생성 CSS: .input:focus + .hint { display: block } -->인터랙티브 데모 — 체크박스를 클릭해 보세요
siblings~ (일반 형제)
트리거 요소 뒤에 오는 모든 형제를 선택합니다. next가 바로 다음 하나만 선택하는 반면, siblings는 뒤에 오는 모든 형제를 선택합니다. 아코디언, 토글 패널 등에 적합합니다.
예시 클래스
| 클래스 | 생성 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 } | 호버 시 모든 형제 아이템 표시 |
<!-- 아코디언: 체크박스로 여러 패널 토글 -->
<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">
아코디언 제목 (클릭하여 열기)
</label>
<div class="panel dn p16px c71717A lh1-7">
아코디언 본문 내용입니다. 체크박스가 체크되면
이 패널과 아래의 모든 .panel 형제가 표시됩니다.
</div>
</div>
<!-- 생성 CSS: .toggle:checked ~ .panel { display: block } -->
<!-- next와의 차이: next는 바로 다음 1개만, siblings는 뒤의 전부 -->
<input type="checkbox" class="trigger-checked-siblings-item-db dn" id="t1" />
<label for="t1">토글</label>
<div class="item dn">형제 1 — 표시됨</div>
<div class="item dn">형제 2 — 이것도 표시됨</div>
<div class="item dn">형제 3 — 이것도 표시됨</div>
<!-- 생성 CSS: .trigger:checked ~ .item { display: block } -->의사 요소와의 조합
관계 선택자는 ::before, ::after 의사 요소와도 조합할 수 있습니다. 타겟 위치에 before 또는 after를 사용합니다.
| 클래스 | 생성 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) } |
<!-- 호버 시 밑줄 애니메이션 (::after 활용) -->
<a class="link-hover-child-after-w100p pr tdn cFAFAFA">
<!-- ::after로 밑줄을 만들고, 호버 시 width를 100%로 -->
링크 텍스트
</a>
<!-- 호버 시 오버레이 표시 (::before 활용) -->
<div class="card-hover-child-before-o100 pr oh">
<!-- ::before를 오버레이로 사용, 호버 시 opacity: 1 -->
<img src="photo.jpg" class="w100p" />
</div>실전 패턴
관계 선택자를 활용한 실제 UI 패턴입니다. JavaScript 없이 순수 CSS로 구현됩니다.
패턴 1 호버 카드 (이미지 줌 + 텍스트 변경)
카드에 호버하면 이미지가 확대되고 텍스트 색상이 변경됩니다. child와 hover를 조합합니다.
<!-- 호버 카드: 이미지 줌 + 제목 색상 + 설명 밝기 변경 -->
<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">
프로젝트 제목
</h3>
<p class="desc c71717A fs14px lh1-6 tall200msease">
카드에 호버하면 이미지가 확대되고, 제목과 설명의 색상이 변합니다.
</p>
</div>
</div>패턴 2 아코디언 (체크박스 + siblings)
숨겨진 체크박스를 토글 트리거로 사용하고, siblings로 패널을 표시합니다. JavaScript 없이 작동합니다.
<!-- 순수 CSS 아코디언 -->
<div class="df fdc gap4px">
<!-- 아이템 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">
섹션 1: 관계 선택자란?
</label>
<div class="panel maxh0 oh tall300msease p0 lh1-7 c71717A">
<div class="p16px">
관계 선택자는 Atomic CSS의 고유 기능으로,
부모-자식 관계를 활용해 상태 변화에 따른
스타일 변경을 구현합니다.
</div>
</div>
</div>
<!-- 아이템 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">
섹션 2: 어떤 키워드가 있나요?
</label>
<div class="panel maxh0 oh tall300msease p0 lh1-7 c71717A">
<div class="p16px">
child, children, next, siblings 4가지 키워드를 지원합니다.
각각 CSS의 >, (공백), +, ~ 결합자에 대응됩니다.
</div>
</div>
</div>
</div>패턴 3 커스텀 체크박스 + 라벨 스타일링
체크박스 상태에 따라 인접 라벨의 스타일을 변경합니다. next와 checked를 조합합니다.
<!-- 커스텀 체크박스 + 라벨 스타일링 -->
<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">
프리미엄 플랜
</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">
뉴스레터 구독
</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">
약관 동의 (필수)
</label>
</div>
</div>패턴 4 드롭다운 메뉴
네비게이션 호버 시 드롭다운을 표시합니다. child와 hover를 사용합니다.
<!-- 호버 드롭다운 메뉴 -->
<nav class="df gap2rem">
<div class="nav-hover-child-dropdown-db pr">
<a href="#" class="cFAFAFA tdn py8px db">제품</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">기능 소개</a>
<a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">가격 정책</a>
<a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">고객 사례</a>
</div>
</div>
<div class="nav-hover-child-dropdown-db pr">
<a href="#" class="cFAFAFA tdn py8px db">리소스</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">문서</a>
<a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">블로그</a>
<a href="#" class="db py8px px12px cA1A1AA tdn hover-cFAFAFA hover-bg27272A br4px">커뮤니티</a>
</div>
</div>
</nav>패턴 5 인풋 포커스 힌트
인풋에 포커스하면 힌트 메시지가 나타납니다. next와 focus를 조합합니다.
<!-- 인풋 포커스 시 힌트 메시지 표시 -->
<div class="df fdc gap16px">
<div>
<input type="email" placeholder="이메일 주소"
class="field-focus-next-hint-db
w100p py8px px12px bg18181B b1pxsolid27272A br6px cFAFAFA fs14px" />
<p class="hint dn fs12px c6366F1 mt4px">
유효한 이메일 주소를 입력하세요
</p>
</div>
<div>
<input type="password" placeholder="비밀번호"
class="field-focus-next-hint-db
w100p py8px px12px bg18181B b1pxsolid27272A br6px cFAFAFA fs14px" />
<p class="hint dn fs12px c34D399 mt4px">
8자 이상, 영문+숫자 조합을 권장합니다
</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-1과 card-hover-child-title-c6366F1을 동시에 사용할 수 있습니다. 호버 한 번으로 여러 자식의 스타일을 변경합니다.
트랜지션과 함께 사용하세요
타겟 요소에 tall200msease 같은 트랜지션 클래스를 함께 사용하면 부드러운 전환 효과를 얻을 수 있습니다.
가독성을 유지하세요
관계 선택자는 매우 강력하지만, 클래스명이 길어질 수 있습니다. 하나의 요소에 관계 선택자를 3~4개 이상 사용하면 읽기 어려워질 수 있습니다. 복잡한 인터랙션은 JavaScript를 고려하세요.
next vs siblings 선택 기준
바로 다음 형제 하나만 제어하면 next, 여러 형제를 동시에 제어하면 siblings를 사용하세요. 대부분의 경우 next가 더 정확합니다.