Relation Selectors
The most powerful feature of Atomic CSS. Use parent-child and sibling relationships to change styles of other elements based on a specific state. Build interactive UI like hover cards, accordions, and custom checkboxes without JavaScript.
Syntax
Relation selectors connect 5 parts with hyphens.
trigger-pseudo-relation-target-class| Part | Description | Example |
|---|---|---|
| trigger | Class name assigned to the parent/trigger element | card, nav, wrapper |
| pseudo | Trigger element state (pseudo-class) | hover, checked, focus |
| relation | Keyword that determines the CSS combinator | child, children, next, siblings |
| target | Tag name or class name of the target element to style | img, label, title, panel |
| class | Atomic CSS class to apply to the target | ofc, db, c6366F1, ts1-1 |
Syntax analysis example
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
Supports 4 CSS combinators. The keyword determines the combinator.
| Keyword | CSS Combinator | Selection Scope | Description |
|---|---|---|---|
child | > | 직접 자식 (1단계) | Selects only the direct child elements of the trigger |
children | (공백) | 모든 후손 (모든 깊이) | Selects all descendant elements at any depth under the trigger |
next | + | 인접 형제 (1개) | Selects the immediately following sibling of the trigger |
siblings | ~ | 일반 형제 (전부) | Selects all following siblings of the trigger |
Keyword Details
child> (직접 자식)
The most commonly used relation selector. Selects only direct children of the trigger element. Nested descendants are not affected. Ideal for card hover, navigation dropdowns, etc.
Example classes
| Class | Generated CSS | Description |
|---|---|---|
card-hover-child-img-ts1-1 | .card:hover > img { transform: scale(1.1) } | Scale up image on card hover |
card-hover-child-title-c6366F1 | .card:hover > .title { color: #6366F1 } | Change title color on card hover |
nav-hover-child-dropdown-db | .nav:hover > .dropdown { display: block } | Show dropdown on nav hover |
card-hover-child-overlay-o100 | .card:hover > .overlay { opacity: 1 } | Show overlay on card hover |
btn-hover-child-icon-ttx4px | .btn:hover > .icon { transform: translateX(4px) } | Move icon on button hover |
<!-- 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 } -->Interactive demo -- hover over the card
Card Title
When you hover the card, the image zooms in, the title color changes, and this description text brightens.
Another Card
Same relation selector pattern but with different color classes. Try hovering.
children(공백) 후손 선택자
Selects all descendants at any depth under the trigger element. Used to apply styles to all target elements regardless of nesting depth.
child vs children
child selects direct children (1 level) only, while children selects all descendants at any depth. Use child to narrow the scope.
Example classes
| Class | Generated CSS | Description |
|---|---|---|
wrapper-hover-children-link-cFFFFFF | .wrapper:hover link { color: #FFFFFF } | Change all descendant link colors on wrapper hover |
wrapper-hover-children-p-cFAFAFA | .wrapper:hover p { color: #FAFAFA } | Change all descendant p tag colors on wrapper hover |
container-hover-children-icon-c6366F1 | .container:hover icon { color: #6366F1 } | Change all descendant icon colors on container hover |
<!-- 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+ (인접 형제)
Selects only the immediately following sibling of the trigger element. Most commonly used with input + label combinations. Ideal for checkbox customization, focus hint display, etc.
Example classes
| Class | Generated CSS | Description |
|---|---|---|
checkbox-checked-next-label-c6366F1 | .checkbox:checked + label { color: #6366F1 } | Change adjacent label color on check |
checkbox-checked-next-label-fw700 | .checkbox:checked + label { font-weight: 700 } | Bold adjacent label on check |
input-focus-next-hint-db | .input:focus + .hint { display: block } | Show hint on input focus |
field-focus-next-hint-o100 | .field:focus + .hint { opacity: 1 } | Change hint opacity on input focus |
toggle-checked-next-panel-db | .toggle:checked + .panel { display: block } | Show panel on toggle check |
<!-- 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 } -->Interactive demo -- click the checkbox
siblings~ (일반 형제)
Selects all following siblings of the trigger element. While next selects only the immediately next one, siblings selects all following siblings. Ideal for accordions, toggle panels, etc.
Example classes
| Class | Generated CSS | Description |
|---|---|---|
toggle-checked-siblings-panel-db | .toggle:checked ~ .panel { display: block } | Show all sibling panels on toggle check |
toggle-checked-siblings-div-db | .toggle:checked ~ div { display: block } | Show all sibling divs on toggle check |
trigger-hover-siblings-item-o100 | .trigger:hover ~ .item { opacity: 1 } | Show all sibling items on hover |
<!-- 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 } -->Combining with Pseudo-elements
Relation selectors can also be combined with ::before and ::after pseudo-elements. Use before or after in the target position.
| Class | Generated 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>Practical Patterns
Real UI patterns using relation selectors. Implemented with pure CSS, no JavaScript.
Pattern 1 Hover Card (Image Zoom + Text Change)
On card hover, the image zooms in and text color changes. Combines child and hover.
<!-- 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>Pattern 2 Accordion (Checkbox + siblings)
Uses a hidden checkbox as a toggle trigger and shows the panel with siblings. Works without 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>Pattern 3 Custom Checkbox + Label Styling
Changes the adjacent label style based on checkbox state. Combines next and checked.
<!-- 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>Pattern 4 Dropdown Menu
Shows a dropdown on navigation hover. Uses child and hover.
<!-- 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>Pattern 5 Input Focus Hint
Shows a hint message on input focus. Combines next and focus.
<!-- 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>Interactive demo -- click the input
Enter a valid email address
8+ characters, alphanumeric combination
Available Pseudo-classes
Pseudo-classes available for the pseudo position in relation selectors.
Interaction
hoverfocusfocus-withinfocus-visibleactiveInput states
checkeddisabledenabledindeterminateForm validation
validinvalidrequiredoptionalin-rangeout-of-rangeOthers
placeholder-shownemptyread-onlytargetvisitedany-linkTips & Notes
trigger is a class, target is a tag name or class name
trigger is the class name assigned to the parent element. target uses the child element's tag name (img, p, span, etc.) or class name.
Multiple relation classes on one trigger
You can use card-hover-child-img-ts1-1 and card-hover-child-title-c6366F1 on the same element simultaneously. One hover changes multiple children's styles.
Use with transitions
Adding transition classes like tall200msease to target elements produces smooth transition effects.
Maintain readability
Relation selectors are very powerful, but class names can get long. Using more than 3-4 relation selectors on a single element can reduce readability. Consider JavaScript for complex interactions.
next vs siblings selection criteria
Use next to control just the immediately next sibling, siblings to control multiple siblings simultaneously. In most cases, next is more precise.