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
PartDescriptionExample
triggerClass name assigned to the parent/trigger elementcard, nav, wrapper
pseudoTrigger element state (pseudo-class)hover, checked, focus
relationKeyword that determines the CSS combinatorchild, children, next, siblings
targetTag name or class name of the target element to styleimg, label, title, panel
classAtomic CSS class to apply to the targetofc, 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.

KeywordCSS CombinatorSelection ScopeDescription
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

ClassGenerated CSSDescription
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

ClassGenerated CSSDescription
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

ClassGenerated CSSDescription
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

ClassGenerated CSSDescription
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.

ClassGenerated 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-visibleactive

Input states

checkeddisabledenabledindeterminate

Form validation

validinvalidrequiredoptionalin-rangeout-of-range

Others

placeholder-shownemptyread-onlytargetvisitedany-link

Tips & 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.