Pseudo-classes
의사 클래스 프리픽스를 Atomic CSS 클래스 앞에 붙여 상태별 스타일을 적용합니다. {pseudo}-{class} 형식으로 32개의 의사 클래스를 지원합니다.
문법
프리픽스와 클래스를 하이픈(-)으로 연결합니다. 프리픽스는 CSS 의사 클래스 이름과 동일합니다.
패턴
{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: 마우스 올렸을 때 배경색 변경 -->
<button class="bg6366F1 hover-bg4F46E5 cFFFFFF tall200msease cp">
호버 버튼
</button>
<!-- focus: 포커스 시 테두리 강조 -->
<input class="b1pxsolid27272A focus-bc6366F1 focus-bw2px" />
<!-- disabled: 비활성 시 투명 + 클릭 차단 -->
<button class="bg6366F1 disabled-o50 disabled-pen" disabled>
비활성
</button>인터랙션
사용자 상호작용에 반응하는 의사 클래스입니다. 가장 자주 사용됩니다.
| 프리픽스 | CSS | 예시 | 설명 |
|---|---|---|---|
hover- | :hover | hover-bg333333 | 마우스를 올렸을 때 |
focus- | :focus | focus-bc6366F1 | 포커스를 받았을 때 (클릭, 탭) |
focus-within- | :focus-within | focus-within-bc6366F1 | 자식 요소가 포커스를 받았을 때 |
focus-visible- | :focus-visible | focus-visible-bc6366F1 | 키보드 탐색으로 포커스를 받았을 때 |
active- | :active | active-bg000000 | 클릭(누르는) 중일 때 |
입력 요소 상태
입력 요소의 활성/비활성, 체크 상태에 반응합니다.
| 프리픽스 | CSS | 설명 |
|---|---|---|
disabled- | :disabled | 비활성 상태의 폼 요소 |
enabled- | :enabled | 활성 상태의 폼 요소 |
checked- | :checked | 체크박스/라디오가 선택된 상태 |
indeterminate- | :indeterminate | 불확정 상태 (체크박스 중간 상태) |
폼 검증
HTML5 폼 검증 상태에 반응합니다. required, pattern, min/max 등과 함께 사용합니다.
| 프리픽스 | CSS | 설명 |
|---|---|---|
valid- | :valid | 검증을 통과한 입력 요소 |
invalid- | :invalid | 검증에 실패한 입력 요소 |
required- | :required | 필수 입력 요소 |
optional- | :optional | 선택 입력 요소 |
in-range- | :in-range | min/max 범위 안의 값 |
out-of-range- | :out-of-range | min/max 범위 밖의 값 |
자식 위치
형제 요소 중 순서에 따라 스타일을 적용합니다.
| 프리픽스 | CSS | 설명 |
|---|---|---|
first-child- | :first-child | 부모의 첫 번째 자식 |
last-child- | :last-child | 부모의 마지막 자식 |
nth-child- | :nth-child | n번째 자식 (특수 구문 필요) |
only-child- | :only-child | 유일한 자식 요소 |
first-of-type- | :first-of-type | 같은 태그 중 첫 번째 |
last-of-type- | :last-of-type | 같은 태그 중 마지막 |
링크 상태
링크 요소의 방문 여부와 타겟 상태에 반응합니다.
| 프리픽스 | CSS | 설명 |
|---|---|---|
link- | :link | 방문하지 않은 링크 |
visited- | :visited | 방문한 링크 |
any-link- | :any-link | href가 있는 모든 링크 |
target- | :target | URL 해시와 일치하는 요소 |
기타
요소의 상태나 조건에 따라 스타일을 적용합니다.
| 프리픽스 | CSS | 설명 |
|---|---|---|
placeholder-shown- | :placeholder-shown | placeholder가 보이는 상태 |
empty- | :empty | 자식 요소가 없는 빈 요소 |
read-only- | :read-only | 읽기 전용 요소 |
fullscreen- | :fullscreen | 전체 화면 상태 |
카테고리별 상세
hover-:hover
가장 많이 사용하는 의사 클래스입니다. 마우스를 올렸을 때 배경색, 글자색, 투명도, 크기 등을 변경할 수 있습니다. tall200msease 등 transition과 함께 사용하면 부드러운 효과를 줍니다.
인터랙티브 데모
각 요소에 마우스를 올려보세요.
배경색 변경
bg6366F1 hover-bg4F46E5글자색 변경
Hover mec71717A hover-cFAFAFA투명도 변경
o60 hover-o100스케일 변경
hover-ts1-05자주 쓰는 조합
hover-bg333333 tall200msease | 부드러운 배경색 전환 (버튼, 카드) |
hover-cFFFFFF tall200msease | 글자색 밝아짐 (링크, 메뉴) |
hover-o80 tall200msease | 살짝 투명해짐 (이미지, 아이콘) |
hover-ts1-05 tall200msease | 살짝 확대 (카드, 버튼) |
hover-bg6366F1 hover-cFFFFFF | 배경 + 글자색 동시 변경 |
<!-- 기본 호버 버튼 -->
<button class="bg6366F1 hover-bg4F46E5 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease">
버튼
</button>
<!-- 글자색 변경 링크 -->
<a class="c71717A hover-cFAFAFA tdn tall200msease" href="#">
링크 텍스트
</a>
<!-- 투명도 변경 -->
<div class="o60 hover-o100 tall200msease">
호버하면 선명해짐
</div>
<!-- 스케일 효과 카드 -->
<div class="bg18181B p2rem br8px hover-ts1-05 tall200msease cp">
호버하면 살짝 확대
</div>
<!-- 복합 호버: 배경 + 글자색 + 그림자 -->
<button class="bg18181B hover-bg6366F1 c71717A hover-cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
복합 효과
</button>focus-:focus
폼 요소가 포커스를 받았을 때 스타일을 변경합니다. 주로 입력 필드의 테두리 색상을 강조하는 데 사용합니다.
인터랙티브 데모
입력 필드를 클릭해보세요.
focus 테두리 강조
b1pxsolid27272A focus-bc6366F1 focus-bw2pxfocus vs focus-visible
focus-는 모든 포커스(클릭, 탭)에 반응합니다. focus-visible-은 키보드 탐색 시에만 반응합니다. 접근성을 위해 키보드 전용 스타일은 focus-visible-을 사용하세요.
<!-- 기본 포커스 스타일 -->
<input
class="w100p bg18181B cFAFAFA b1pxsolid27272A focus-bc6366F1 focus-bw2px py12px px16px br8px tall200msease"
type="text"
placeholder="포커스 시 테두리 강조"
/>
<!-- focus-within: 자식이 포커스 받으면 부모 스타일 변경 -->
<div class="b1pxsolid27272A focus-within-bc6366F1 br8px p16px tall200msease">
<label class="cA1A1AA fs12px db mb4px">이름</label>
<input class="w100p bg18181B cFAFAFA bn py8px fs14px" type="text" />
</div>
<!-- focus-visible: 키보드 포커스 전용 -->
<button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp focus-visible-bw2px focus-visible-bcFFFFFF">
Tab으로 포커스 시 테두리 표시
</button>disabled-:disabled
비활성 상태의 폼 요소에 스타일을 적용합니다. disabled-o50과 disabled-pen을 조합하면 시각적으로 비활성임을 명확히 알 수 있습니다.
인터랙티브 데모
활성 버튼
비활성 버튼
<!-- 비활성 버튼 -->
<button
class="bg6366F1 hover-bg4F46E5 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease disabled-o50 disabled-pen"
disabled
>
비활성 버튼
</button>
<!-- 비활성 입력 필드 -->
<input
class="w100p bg18181B cFAFAFA b1pxsolid27272A py12px px16px br8px disabled-o50"
type="text"
placeholder="수정 불가"
disabled
/>
<!-- 활성/비활성 비교 -->
<div class="df gap16px">
<button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp disabled-o50 disabled-pen">
활성
</button>
<button class="bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp disabled-o50 disabled-pen" disabled>
비활성
</button>
</div>checked-:checked
체크박스나 라디오 버튼이 선택된 상태일 때 스타일을 적용합니다. 커스텀 체크박스/라디오 UI를 만들 때 유용합니다.
<!-- 커스텀 체크박스 스타일 -->
<label class="df aic gap8px cp">
<input type="checkbox" class="w16px h16px checked-bg6366F1" />
<span class="cFAFAFA fs14px">옵션 1</span>
</label>
<!-- 커스텀 라디오 버튼 -->
<label class="df aic gap8px cp">
<input type="radio" name="option" class="w16px h16px checked-bg6366F1" />
<span class="cFAFAFA fs14px">선택 A</span>
</label>
<label class="df aic gap8px cp">
<input type="radio" name="option" class="w16px h16px checked-bg6366F1" />
<span class="cFAFAFA fs14px">선택 B</span>
</label>invalid-:invalid
HTML5 폼 검증에 실패한 요소에 스타일을 적용합니다. required, type="email", pattern 등과 함께 사용합니다.
인터랙티브 데모
빈 상태에서 유효하지 않은 스타일을 확인하세요.
이메일 검증
b1pxsolid27272A invalid-bcEF4444 focus-bc6366F1<!-- 이메일 검증 -->
<input
type="email"
required
placeholder="이메일을 입력하세요"
class="w100p bg18181B cFAFAFA b1pxsolid27272A invalid-bcEF4444 valid-bc34D399 py12px px16px br8px tall200msease"
/>
<!-- 패턴 검증 (숫자만) -->
<input
type="text"
pattern="[0-9]+"
required
placeholder="숫자만 입력"
class="w100p bg18181B cFAFAFA b1pxsolid27272A invalid-bcEF4444 py12px px16px br8px tall200msease"
/>
<!-- 범위 검증 -->
<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-
첫 번째 또는 마지막 자식 요소에만 스타일을 적용합니다. 리스트의 첫/마지막 항목에서 구분선을 제거하거나 둥근 모서리를 적용하는 데 자주 사용합니다.
데모 - 마지막 항목 테두리 제거
<!-- 마지막 항목 테두리 제거 -->
<ul class="lsn m0 p0 bg18181B br8px oh">
<li class="py12px px16px bb1pxsolid27272A last-child-bb0">항목 1</li>
<li class="py12px px16px bb1pxsolid27272A last-child-bb0">항목 2</li>
<li class="py12px px16px bb1pxsolid27272A last-child-bb0">항목 3</li>
<li class="py12px px16px bb1pxsolid27272A last-child-bb0">항목 4</li>
</ul>
<!-- 첫 번째 항목 강조 -->
<div class="df fdc">
<div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">첫 번째 (강조)</div>
<div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">두 번째</div>
<div class="py12px px16px first-child-fw700 first-child-cFAFAFA c71717A">세 번째</div>
</div>미디어 쿼리와 조합
미디어 쿼리 프리픽스 뒤에 의사 클래스 프리픽스를 이어 붙여 반응형 + 상태 스타일을 동시에 적용할 수 있습니다.
패턴
{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 } }<!-- 데스크탑에서만 호버 효과 (모바일에서는 제거) -->
<button class="bg6366F1 hover-bg4F46E5 sm-hover-bg6366F1 cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
데스크탑 전용 호버
</button>
<!-- 반응형 호버 배경 -->
<div class="bg18181B hover-bg27272A sm-hover-bg18181B p2rem br8px tall200msease">
768px 이하에서는 호버 효과 없음
</div>
<!-- 반응형 포커스 스타일 -->
<input
class="b1pxsolid27272A focus-bc6366F1 md-focus-bc34D399 py12px px16px br8px tall200msease"
placeholder="태블릿에서는 녹색 포커스"
/>복수 의사 클래스 조합
같은 요소에 여러 의사 클래스를 동시에 적용할 수 있습니다. 각 상태별로 다른 스타일을 지정하면 풍부한 인터랙션을 구현할 수 있습니다.
데모
<!-- hover + focus + active 조합 -->
<button class="bg6366F1 hover-bg4F46E5 focus-bg818CF8 active-bg3730A3 cFFFFFF py12px px2-4rem br8px bn cp fs14px tall200msease">
다중 상태 버튼
</button>
<!-- hover + focus + disabled 조합 -->
<button class="bg6366F1 hover-bg4F46E5 focus-bc818CF8 disabled-o50 disabled-pen cFFFFFF py12px px2-4rem br8px bn cp tall200msease">
활성 상태
</button>
<button class="bg6366F1 hover-bg4F46E5 focus-bc818CF8 disabled-o50 disabled-pen cFFFFFF py12px px2-4rem br8px bn cp tall200msease" disabled>
비활성 상태
</button>
<!-- 링크: hover + focus-visible + active + visited -->
<a href="#" class="c6366F1 hover-c818CF8 focus-visible-tdu active-c3730A3 tdn tall200msease">
다중 상태 링크
</a>| 상태 | 클래스 | 효과 |
|---|---|---|
| 기본 | bg6366F1 | 인디고 배경 |
| hover | hover-bg4F46E5 | 진한 인디고 |
| focus | focus-bg818CF8 | 밝은 인디고 |
| active | active-bg3730A3 | 가장 진한 인디고 |
팁 & 주의사항
hover에는 반드시 transition을 함께 사용
tall200msease 또는 tall300ms를 추가하면 상태 전환이 부드러워집니다. transition 없이 hover를 사용하면 즉각적인 변화가 어색할 수 있습니다.
focus보다 focus-visible 우선
키보드 접근성만 강조하려면 focus-visible-을 사용하세요. focus-는 마우스 클릭에도 반응하므로 버튼 등에서 불필요한 outline이 표시될 수 있습니다.
disabled는 시각적으로 명확하게
disabled-o50과 disabled-pen(pointer-events: none)을 함께 적용하면 비활성 상태임을 시각적으로도 명확히 알 수 있습니다.
모바일에서의 hover
터치 디바이스에서는 hover가 예상대로 동작하지 않을 수 있습니다. 중요한 인터랙션은 hover에만 의존하지 말고, 클릭/탭으로도 접근 가능하게 설계하세요.