Menu

CSS 가상 클래스: nth-child, not, first-child, focus

가상 클래스는 위치나 상태로 요소를 골라요. :nth-child(), :first-child, :not(), :focus, :checked, :has() 등이 있어요. 문법, 실시간 테스터로 보는 an+b 공식, nth-child와 nth-of-type의 차이를 알아봐요.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

가상 클래스란

가상 클래스는 콜론 뒤에 오는 키워드로, 문서 안의 위치나 상태로 요소를 골라요. 일반 선택자에 붙여 써요. li:first-child, input:focus, a:hover처럼요.

링크와 마우스의 상태 가상 클래스(:hover, :active, :visited)는 CSS hover 페이지에서 따로 다뤄요.

:nth-child()와 an+b 공식

:nth-child()는 숫자, 키워드, 또는 an+b 공식을 받아요. 브라우저는 n = 0, 1, 2, ...를 차례로 넣어 보고 공식이 만드는 모든 위치와 일치시켜요(위치는 1부터 시작해요).

공식일치하는 위치뜻
33세 번째 자식
odd 또는 2n+11, 3, 5, ...홀수 행
even 또는 2n2, 4, 6, ...짝수 행
3n3, 6, 9, ...세 개마다 하나
n+44, 5, 6, ...네 번째부터
-n+31, 2, 3처음 세 개
3n+11, 4, 7, ...첫 번째부터 세 개마다 하나

공식을 입력하고 어떤 항목이 일치하는지 보세요.

odd, even, 4, n+7, -n+5, 2n+3을 입력해 보세요. 잘못된 공식은 아무것도 고르지 않아요.

끝에서부터 세는 짝은 :nth-last-child()예요. li:nth-last-child(-n+2)는 마지막 두 항목을 골라요.

nth-child와 nth-of-type 비교

:nth-child()는 태그와 상관없이 모든 형제 요소를 센 다음에야 선택자의 나머지를 확인해요. :nth-of-type()은 같은 태그의 형제만 세요. 형제가 섞여 있으면 바로 차이가 드러나요.

양 끝에도 같은 짝이 있어요. :first-child / :first-of-type, :last-child / :last-of-type, :only-child / :only-of-type.

:not(), :is(), :where()

가상 클래스예시일치하는 것
:not(X)li:not(.done)X와 일치하지 않는 요소
:is(X, Y):is(h1, h2, h3) a목록 중 하나와 일치하는 요소
:where(X, Y):where(ul, ol) li:is()와 같지만 명시도가 0
:has(X)li:has(> input:checked)X와 일치하는 것을 포함한 요소

매일 쓰는 건 :not()이에요. 예를 들어 항목 사이에 구분선을 넣되 마지막 항목 뒤에는 넣지 않을 때요.

상태 가상 클래스: focus, checked, disabled, invalid

가상 클래스일치하는 것
:focus키보드나 마우스 포커스를 가진 요소
:focus-visible포커스를 가졌고, 브라우저가 링을 보여 줘야 한다고 판단할 때(보통 키보드 포커스)
:focus-within포커스를 가진 요소를 포함한 요소
:checked체크된 체크박스, 라디오, 선택된 <option>
:disabled / :enabled비활성화된(또는 활성화된) 폼 컨트롤
:required / :optionalrequired가 있는(또는 없는) 입력 요소
:invalid / :valid값이 검증을 통과하지 못한(또는 통과한) 입력 요소
:user-invalid유효하지 않지만, 사용자가 조작한 뒤에만
:placeholder-shown지금 placeholder를 보여 주는 입력 요소
:empty자식이 없는 요소, 텍스트도 없어야 해요
:targetid가 URL의 #fragment와 일치하는 요소

이메일 필드를 클릭해 보세요. :focus-within 덕분에 label이 파란색으로 바뀌어요. 이메일이 아닌 값을 입력하고 필드를 벗어나면 :user-invalid가 테두리를 주황색으로 바꿔요. 그냥 :invalid였다면 필수 입력인 빈 필드를 건드리기도 전에 주황색으로 표시했을 거예요.

:focus로 무엇을 하든 포커스가 눈에 보이게 유지하세요. 대체 스타일 없이 outline을 지우면 키보드 사용자는 자기가 어디 있는지 알 수 없어요.

:has(), 부모 선택자

:has()는 요소가 무엇을 포함하는지로 일치 여부를 판단해요. 오랫동안 요청되어 온 "부모 선택자"이고, 최신 Chrome, Firefox, Safari에서 동작해요.

다른 요금제를 골라 보세요. JavaScript 없이 카드 전체가 라디오 버튼을 따라가요.

자주 하는 실수

  • 콜론 앞에 공백 넣기. li :first-child는 "li 안의 첫 번째 자식"이라는 뜻이에요. li:first-child로 쓰세요.
  • p:nth-child(1)을 "첫 번째 p"로 생각하기. "첫 번째 자식인데, 그게 p라면"이라는 뜻이에요. 첫 번째 p에는 :first-of-type을 쓰세요.
  • 0부터 세기. 위치는 1부터 시작해요. :nth-child(0)은 아무것도 고르지 않아요.
  • 포커스 outline 지우기. 대체 스타일 없는 :focus { outline: none }은 키보드 탐색을 망가뜨려요.
  • :와 :: 헷갈리기. :before는 가상 요소 ::before의 옛 표기이고, 가상 클래스는 항상 콜론 하나를 써요.

자주 묻는 질문

CSS에서 가상 클래스란 무엇인가요?

콜론 뒤에 오는 키워드로, 이름이 아니라 상태나 위치로 요소를 골라요. a:hover, li:first-child, input:focus 같은 것들이에요. 일반 선택자에 붙여 쓰고, 대부분의 가상 클래스는 명시도에서 클래스처럼 계산돼요(:where()는 0이에요).

CSS에서 nth-child는 어떻게 동작하나요?

:nth-child(an+b)는 n = 0, 1, 2 등에 대해 형제 사이의 위치가 a×n+b인 요소와 일치해요. 위치는 1부터 세요. :nth-child(3)은 세 번째 자식, :nth-child(odd)나 2n+1은 홀수 번째 전부, :nth-child(n+4)는 네 번째부터 끝까지예요.

nth-child와 nth-of-type은 무엇이 다른가요?

:nth-child()는 모든 형제 요소를 센 다음 선택자의 나머지를 확인하고, :nth-of-type()은 같은 종류의 형제만 세요. h2 뒤에 문단이 이어지는 목록에서 p:nth-child(1)은 아무것도 고르지 않지만 p:nth-of-type(1)은 첫 번째 문단을 골라요.

CSS에서 :not()은 어떻게 쓰나요?

제외할 선택자를 괄호 안에 넣어요. li:not(.done)은 done 클래스가 없는 모든 목록 항목과 일치해요. 목록도 받아요. input:not([type="checkbox"], [type="radio"])

가상 클래스와 가상 요소는 무엇이 다른가요?

가상 클래스(콜론 하나, :hover)는 어떤 상태에 있는 기존 요소 전체를 골라요. 가상 요소(콜론 두 개, ::before)는 요소의 일부를 대상으로 하거나 생성된 콘텐츠를 만들어요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기