Pseudo-classes

Apply state-based styles by prepending pseudo-class prefixes to Atomic CSS classes. Supports 32 pseudo-classes in the format {pseudo}-{class}.

Syntax

Connect the prefix and class with a hyphen (-). Prefixes match CSS pseudo-class names.

Pattern

{pseudo}-{atomic-class}
hover-bg333333:hover { background-color: #333333 }
focus-bc6366F1:focus { border-color: #6366F1 }
disabled-o50:disabled { opacity: 0.5 }
checked-bg6366F1:checked { background-color: #6366F1 }
<!-- hover: change background color on mouse over -->
<button class="bg6366F1 hover-bg4F46E5 cFFFFFF tall200msease cp">
  Hover button
</button>

<!-- focus: emphasize border on focus -->
<input class="b1pxsolid27272A focus-bc6366F1 focus-bw2px" />

<!-- disabled: transparent + block clicks when disabled -->
<button class="bg6366F1 disabled-o50 disabled-pen" disabled>
  Disabled
</button>

Interaction

Pseudo-classes that respond to user interaction. Most commonly used.

PrefixCSSExampleDescription
hover-:hoverhover-bg333333On mouse hover
focus-:focusfocus-bc6366F1On focus (click, tab)
focus-within-:focus-withinfocus-within-bc6366F1When a child element receives focus
focus-visible-:focus-visiblefocus-visible-bc6366F1On keyboard navigation focus
active-:activeactive-bg000000While clicking (pressing)

Input Element States

Responds to input element enabled/disabled and checked states.

PrefixCSSDescription
disabled-:disabledDisabled form element
enabled-:enabledEnabled form element
checked-:checkedCheckbox/radio in selected state
indeterminate-:indeterminateIndeterminate state (checkbox mid-state)

Form Validation

Responds to HTML5 form validation states. Used with required, pattern, min/max, etc.

PrefixCSSDescription
valid-:validInput element that passed validation
invalid-:invalidInput element that failed validation
required-:requiredrequired input element
optional-:optionalselection input element
in-range-:in-rangeValue within min/max range
out-of-range-:out-of-rangeValue outside min/max range

Child Position

Applies styles based on position among sibling elements.

PrefixCSSDescription
first-child-:first-childFirst child of parent
last-child-:last-childLast child of parent
nth-child-:nth-childNth child (requires special syntax)
only-child-:only-childOnly child element
first-of-type-:first-of-typeFirst of its tag type
last-of-type-:last-of-typeLast of its tag type

Responds to link visit status and target state.

PrefixCSSDescription
link-:linkUnvisited link
visited-:visitedVisited link
any-link-:any-linkAll links with href
target-:targetElement matching URL hash

Others

Applies styles based on element state or conditions.

PrefixCSSDescription
placeholder-shown-:placeholder-shownPlaceholder is visible
empty-:emptyEmpty element with no children
read-only-:read-onlyread-only element
fullscreen-:fullscreenFullscreen state

Category Details

hover-:hover

The most frequently used pseudo-class. Can change background color, text color, opacity, size, etc. on hover. Combine with transitions like tall200msease for smooth effects.

Interactive Demo

Hover over each element.

Background color change

bg6366F1 hover-bg4F46E5

Text color change

Hover mec71717A hover-cFAFAFA

Opacity change

Hover me
o60 hover-o100

Scale change

Hover me
hover-ts1-05

Common Combinations

hover-bg333333 tall200mseaseSmooth background color transition (buttons, cards)
hover-cFFFFFF tall200mseaseText color brightens (links, menus)
hover-o80 tall200mseaseSlightly transparent (images, icons)
hover-ts1-05 tall200mseaseSlightly enlarged (cards, buttons)
hover-bg6366F1 hover-cFFFFFFBackground + text color change simultaneously
<!-- Default Hover button -->
<button class="bg6366F1 hover-bg4F46E5 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease">
  Button
</button>

<!-- Text color change link -->
<a class="c71717A hover-cFAFAFA tdn tall200msease" href="#">
  Link text
</a>

<!-- Change opacity -->
<div class="o60 hover-o100 tall200msease">
  Becomes clearer on hover
</div>

<!-- Scale effect card -->
<div class="bg18181B p2rem br8px hover-ts1-05 tall200msease cp">
  Slightly enlarged on hover
</div>

<!-- Combined hover: background + text color + shadow -->
<button class="bg18181B hover-bg6366F1 c71717A hover-cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
  Combined effect
</button>

focus-:focus

Changes styles when a form element receives focus. Mainly used to highlight input field border colors.

Interactive Demo

Click on the input field.

Focus border highlight

b1pxsolid27272A focus-bc6366F1 focus-bw2px

focus vs focus-visible

focus- responds to all focus (click, tab). focus-visible- responds only to keyboard navigation. For accessibility, use focus-visible- for keyboard-only styles.

<!-- Default focus style -->
<input
  class="w100p bg18181B cFAFAFA b1pxsolid27272A focus-bc6366F1 focus-bw2px py12px px16px br8px tall200msease"
  type="text"
  placeholder="Border emphasized on focus"
/>

<!-- focus-within: change parent style when child receives focus -->
<div class="b1pxsolid27272A focus-within-bc6366F1 br8px p16px tall200msease">
  <label class="cA1A1AA fs12px db mb4px">Name</label>
  <input class="w100p bg18181B cFAFAFA bn py8px fs14px" type="text" />
</div>

<!-- focus-visible: keyboard focus only -->
<button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp focus-visible-bw2px focus-visible-bcFFFFFF">
  Border shown on Tab focus
</button>

disabled-:disabled

Applies styles to disabled form elements. Combining disabled-o50 and disabled-pen clearly indicates the disabled state visually.

Interactive Demo

active button

disabled button

<!-- Disabled button -->
<button
  class="bg6366F1 hover-bg4F46E5 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease disabled-o50 disabled-pen"
  disabled
>
  Disabled button
</button>

<!-- Disabled input field -->
<input
  class="w100p bg18181B cFAFAFA b1pxsolid27272A py12px px16px br8px disabled-o50"
  type="text"
  placeholder="Not editable"
  disabled
/>

<!-- Active/Disabled Comparison -->
<div class="df gap16px">
  <button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp disabled-o50 disabled-pen">
    Active
  </button>
  <button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp disabled-o50 disabled-pen" disabled>
    Disabled
  </button>
</div>

checked-:checked

Applies styles when checkboxes or radio buttons are selected. Useful for building custom checkbox/radio UIs.

<!-- Custom checkbox style -->
<label class="df aic gap8px cp">
  <input type="checkbox" class="w16px h16px checked-bg6366F1" />
  <span class="cFAFAFA fs14px">Option 1</span>
</label>

<!-- Custom radio button -->
<label class="df aic gap8px cp">
  <input type="radio" name="option" class="w16px h16px checked-bg6366F1" />
  <span class="cFAFAFA fs14px">Choice A</span>
</label>
<label class="df aic gap8px cp">
  <input type="radio" name="option" class="w16px h16px checked-bg6366F1" />
  <span class="cFAFAFA fs14px">Choice B</span>
</label>

invalid-:invalid

Applies styles to elements that fail HTML5 form validation. Used with required, type="email", pattern, etc.

Interactive Demo

Check the invalid styles in empty state.

Email validation

b1pxsolid27272A invalid-bcEF4444 focus-bc6366F1
<!-- Email validation -->
<input
  type="email"
  required
  placeholder="Enter your email"
  class="w100p bg18181B cFAFAFA b1pxsolid27272A invalid-bcEF4444 valid-bc34D399 py12px px16px br8px tall200msease"
/>

<!-- Pattern validation (numbers only) -->
<input
  type="text"
  pattern="[0-9]+"
  required
  placeholder="Numbers only"
  class="w100p bg18181B cFAFAFA b1pxsolid27272A invalid-bcEF4444 py12px px16px br8px tall200msease"
/>

<!-- Range validation -->
<input
  type="number"
  min="1"
  max="100"
  placeholder="1-100"
  class="w100p bg18181B cFAFAFA b1pxsolid27272A in-range-bc34D399 out-of-range-bcEF4444 py12px px16px br8px tall200msease"
/>

first-child-last-child-

Applies styles only to the first or last child element. Commonly used to remove separators or apply rounded corners on first/last list items.

Demo - Remove last item border

항목 1
항목 2
항목 3
항목 4 (마지막 - 테두리 없음)
<!-- Remove border on last item -->
<ul class="lsn m0 p0 bg18181B br8px oh">
  <li class="py12px px16px bb1pxsolid27272A last-child-bb0">Item 1</li>
  <li class="py12px px16px bb1pxsolid27272A last-child-bb0">Item 2</li>
  <li class="py12px px16px bb1pxsolid27272A last-child-bb0">Item 3</li>
  <li class="py12px px16px bb1pxsolid27272A last-child-bb0">Item 4</li>
</ul>

<!-- Emphasize first item -->
<div class="df fdc">
  <div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">First (emphasized)</div>
  <div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">Second</div>
  <div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">Third</div>
</div>

Combining with Media Queries

Append pseudo-class prefixes after media query prefixes to apply responsive + state styles simultaneously.

Pattern

{media}-{pseudo}-{class}
sm-hover-bg333333@media (max-width: 768px) { :hover { background-color: #333333 } }
md-focus-bc6366F1@media (max-width: 1024px) { :focus { border-color: #6366F1 } }
<!-- Hover effect on desktop only (removed on mobile) -->
<button class="bg6366F1 hover-bg4F46E5 sm-hover-bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
  Desktop-only hover
</button>

<!-- Responsive hover background -->
<div class="bg18181B hover-bg27272A sm-hover-bg18181B p2rem br8px tall200msease">
  No hover effect at 768px and below
</div>

<!-- Responsive focus style -->
<input
  class="b1pxsolid27272A focus-bc6366F1 md-focus-bc34D399 py12px px16px br8px tall200msease"
  placeholder="Green focus on tablet"
/>

Multiple Pseudo-class Combinations

Multiple pseudo-classes can be applied to the same element. Assigning different styles per state enables rich interactions.

Demo

<!-- hover + focus + active Combination -->
<button class="bg6366F1 hover-bg4F46E5 focus-bg818CF8 active-bg3730A3 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease">
  Multi-state button
</button>

<!-- hover + focus + disabled Combination -->
<button class="bg6366F1 hover-bg4F46E5 focus-bc818CF8 disabled-o50 disabled-pen cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
  Active Status
</button>
<button class="bg6366F1 hover-bg4F46E5 focus-bc818CF8 disabled-o50 disabled-pen cFFFFFF py12px px2-4rem br8px bn cp tall200msease" disabled>
  Disabled Status
</button>

<!-- Link: hover + focus-visible + active + visited -->
<a href="#" class="c6366F1 hover-c818CF8 focus-visible-tdu active-c3730A3 tdn tall200msease">
  Multi-state link
</a>
StateClassEffect
기본bg6366F1인디고 배경
hoverhover-bg4F46E5진한 인디고
focusfocus-bg818CF8밝은 인디고
activeactive-bg3730A3가장 진한 인디고

Tips & Notes

Always use transition with hover

Adding tall200msease or tall300ms smooths state transitions. Using hover without transition can feel abrupt.

Prefer focus-visible over focus

Use focus-visible- for keyboard accessibility only. focus- responds to mouse clicks too, which may show unnecessary outlines on buttons.

Make disabled visually clear

Applying disabled-o50 and disabled-pen (pointer-events: none) together makes the disabled state visually obvious.

Hover on mobile

Hover may not work as expected on touch devices. Do not rely solely on hover for important interactions -- design for click/tap accessibility as well.