가상 셀렉터에는 크게 가상 클래스 셀렉터(Pseudo-Class Selector)와 가상 요소 셀렉터(Pseudo-Element Selector)가 있다.
빠르게 어떤 역할인지만 보고 싶으면 바로 밑의 `테이블로 전체 빠르게 보기`만 보면 된다. 테이블들은 오른쪽 링크를 참고했다. 🔗테이블 내용 참고한 링크 그 밑에서는 그냥 CSS 게임을 통해 알게 된 내용과 예제들이다.
1. 테이블로 전체 빠르게 보기
1. 가상 클래스(Pseudo classes)
가상 클래스는 요소의 특정 상태에 따라 스타일을 정의할 때 사용된다.
가상 클래스는 한 개의 콜론(:)을 사용한다.
링크 셀렉터(Link pseudo-classes), 동적 셀렉터(User action pseudo-classes)
| 이름 | 설명 |
| :link | 사용자가 방문하지 않은 링크를 선택 |
| :visited | 사용자가 방문했던 링크를 선택 |
| :hover | 마우스 커서가 링크위에 올라와 있는 요소를 선택 |
| :active | 클릭된 상태일 때 선택 |
| :focus | 포커스가 들어와 있을 때 선택 |
UI 요소 상태 셀렉터(UI element states pseudo-classes)
| 이름 | 설명 |
| :checked | 셀렉터가 체크 상태일 때 |
| :enabled | 셀렉터가 사용 가능한 상태일 때 |
| :disabled | 셀렉터가 사용 불가능한 상태일 때 |
구조 가상 클래스 셀렉터(Structural pseudo-classes)
| 이름 | 설명 |
| :nth-child(n) | n번째 위치에 있는 자식 요소를 선택. n은 0부터 시작하는 모든 양의 정수이다. |
| :nth-child(An+B) | A와 B는 정수이다. A는 정수 인덱스 증감량을 결정한다. 예를 들어 2n+1이런 식으로 넣어줄 수 있다. |
| :nth-child(even) 또는 :nth-child(2n) | 짝수 번째 위치에 있는 자식 요소를 선택 |
| :nth-child(odd) 또는 :nth-child(2n+1) | 홀수 번째 위치에 있는 자식 요소를 선 |
| :first-child | 셀렉터에 해당하는 모든 요소 중 첫번째 자식인 요소를 선택한다. |
| :last-child | 셀렉터에 해당하는 모든 요소 중 마지막 자식인 요소를 선택한다. |
| :nth-last-child(n) | 셀렉터에 해당하는 모든 요소 중 뒤에서 n번째 자식인 요소를 선택한다. |
| 글의 마지막에서 다룬 `:nth-child()`와 `:nth-of-type()` 차이점에 대해서 꼭 읽어야 한다. | |
| :first-of-type | 셀렉터에 해당하는 요소의 부모 요소의 자식 요소 중 첫번째 등장하는 요소를 선택한다. |
| :last-of-type | 셀렉터에 해당하는 요소의 부모 요소의 자식 요소 중 마지막에 등장하는 요소를 선택한다. |
| :nth-of-type(n) | 셀렉터에 해당하는 요소의 부모 요소의 자식 요소 중 앞에서 n번째에 등장하는 요소를 선택한다. |
| :nth-last-of-type(n) | 셀렉터에 해당하는 요소의 부모 요소의 자식 요소 중 뒤에서 n번째에 등장하는 요소를 선택한다. |
파라미터 n은 0부터 시작하는 정수이다.

0과 음수는 생략되기 때문에 2n+1과 2n-1, 3n-2와 3n+1은 결과적으로 같은 수열을 생성한다.
🚨주의할 점이 한 가지가 있는데
부모 요소에 nth-child()를 주는 것이 아니라 (내 몇 번째 자식한테 줘라~ 이게 아닌)
ul {
&:nth-child(odd) {
color: red;
}
}
ul:nth-child(odd) {}
자식 요소에 줘야 한다는 점이다. 이 점이 처음에 헷갈렸다. (난 몇 번째 자식이야 ~ 이거다.)
ul > li:nth-child(odd) {
color: red;
}
li {
&:nth-child(odd) {
color: red;
}
&:nth-child(even) {
color: blue;
}
}
부정 셀렉터(Negation pseudo-class)
| 이름 | 설명 |
| :not(셀렉터) | `셀렉터`에 해당하지 않는 모든 요소를 선택한다. |
/* div 요소 중에서 4번째 이후 등장하는 요소가 아닌 요소만을 선택 */
div:not(:nth-of-type(n+4)) {
margin-bottom: 2%;
}
정합성 체크 셀렉터(validity pseudo-class)
| 이름 | 설명 |
| :valid(셀렉터) | 정합성 검증이 성공한 input 요소 또는 form 요소를 선택한다. |
| :invalid(셀렉터) | 정합성 검증이 실패한 input 요소 또는 form 요소를 선택한다. |
<!DOCTYPE html>
<html>
<head>
<style>
input[type="text"]:valid {
background-color: greenyellow;
}
input[type="text"]:invalid {
background-color: red;
}
</style>
</head>
<body>
<label>입력값이 반드시 필요
<input type="text" required>
</label>
<br>
<label>특수문자를 포함하지 않는 4자리 문자 또는 숫자
<input type="text" value="ab1!"
pattern="[a-zA-Z0-9]{4}" required>
</label>
<br>
<label>핸드폰 번호 형식
<input type="text" value="010-1111-2222"
pattern="^\d{3}-\d{3,4}-\d{4}$" required>
</label>
</body>
</html>
See the Pen validity pseudo-class by Olimjo (@OLIMJO) on CodePen.
2. 가상 요소 셀렉터 (Pseudo-Element Selector)
가상 요소는 요소의 특정 부분에 스타일을 적용하기 위하여 사용된다.
예를 들어 요소 콘텐츠의 첫 글자 또는 첫 줄, 요소 콘텐츠의 앞 또는 뒤
가상 요소에는 두개의 콜론(::)을 사용한다.
의사 요소(Pseudo elements)
| 이름 | 설명 | 코멘트 |
| ::before | 특정 요소의 시작부분에 콘텐츠를 추가한다. | 일반적으로 content 프로퍼티와 함께 사용된다. |
| ::after | 특정 요소의 끝부분에 콘텐츠를 추가한다. | 일반적으로 content 프로퍼티와 함께 사용된다. |
| ::first-line | 요소의 텍스트 첫 줄을 선택한다. | |
| ::first-letter | 요소의 첫 글자를 선택한다. | |
| ::selection | 드래그한 콘텐츠를 선택한다. iOS Safari 등 일부 브라우저에서 동작 않는다. |
2. CSS Diner 라는 게임으로 알게된 예제와 기능들
여기 밑에서는 아래 게임을 통해 직접 알게된 기능들을 정리해본다.
CSS Diner
A fun game to help you learn and practice CSS selectors.
flukeout.github.io
1. :nth-child(number)
<div class="table">
<plate />
<plate />
<plate />
<plate id="fancy" />
</div>
여기서 3 번째 plate를 선택하려면,
plate:nth-child(3)
을 해주면 된다!
✔ 1-1. :nth-last-child(number)
이건 뒤에서 부터 카운팅을 한다!
<div class="table">
<plate />
<bento />
<plate>
<orange />
<orange />
<orange />
</plate>
<bento />
</div>
여기서 2번 째 bento를 고르려면?
bento:nth-last-child(3)
bento이기는한데 형제 요소들 중 뒤에서 3번째인 녀석을 골라라! 라는 뜻
2. :first-child, :only-child ,:last-child
이 중에서 :last-child 기억할 만한 문제 하나를 가져왔다
까먹을 것 같아서 가져왔다.
<div class="table">
<plate id="fancy">
<apple class="small" />
</plate>
<plate />
<plate>
<orange class="small" />
<orange />
</plate>
<pickle class="small" />
</div>
여기서 첫 번째 apple과 마지막 pickle을 고르려면?
.small:last-child 를 해주면 된다!
small 이라는 클래스를 가진 요소들 중에서 자기자신이 형제 요소들 중에서 마지막 요소라면 골라준다!
3. :first-of-type
특정 요소중에서 첫 번째 타입을 고름.
<div class="table">
<orange class="small" />
<apple />
<apple class="small" />
<apple />
<apple class="small" />
<plate>
<orange class="small" />
<orange />
</plate>
</div>
여기서 첫 번째 apple 요소를 고르고 싶다면?
apple:first-of-type
4. nth-of-type(number)
<div class="table">
<plate />
<plate />
<plate />
<plate />
<plate id="fancy" />
<plate />
</div>
여기서 짝수 번째 plate만 고르고 싶다면?
plate:nth-of-type(even) 혹은
plate:nth-of-type(2), plate:nth-of-type(4), plate:nth-of-type(6) 을 해주면 된다.
당연히 홀수 번째는 plate:nth-of-type(odd) 이다.
5. :nth-of-type(An+3)
그냥 밑의 예시 보는게 이해가 가장 빠를 것이다.
<div class="table">
<plate />
<plate>
<pickle class="small" />
</plate>
<plate>
<apple class="small" />
</plate>
<plate />
<plate>
<apple />
</plate>
<plate />
</div>
컴퓨터가 n을 0부터 시작하여 대입해본다. 0, 1, 2, ...
뒤에 +3 은 시작점을 잡아주는 것이다.
2*0+3은 3이므로 3부터 시작한다.
2*0+3, 2*1+3 , 2*2+3
3, 5, 7 번째를 고른다.
문제에서는 apple이 담긴 plate를 골라야 한다.
plate:nth-of-type(2n+3)
6. :empty
요소 중에서 자식이 없는 요소를 고름
<div class="table">
<bento />
<bento>
<pickle class="small" />
</bento>
<plate />
<bento />
</div>
첫 번째 bento와 마지막 bento를 고르려면?
bento:empty
7. [attribute] / ele[attribute="value"]
<div class="table">
<bento>
<apple class="small" />
</bento>
<apple for="Ethan" />
<plate for="Alice">
<pickle />
</plate>
<bento for="Clara">
<orange />
</bento>
<pickle />
</div>
예시로)
a[href] 는 href라는 속성을 가진 모든 a태그를 선택한다.
[type]는 type라는 속성을 가진 모든 요소를 선택한다.
a[href="value"]는 a 태그 중에서 href의 속성값이 value인 것들을 선택한다.
위 코드에서 [for] 을 입력하면 for 속성을 가진 모든 것을 선택한다.
주의해야 할 점이 있다
style 속성으로 선택한다면 마지막에 세미콜론(;)은 쓰면 안 된다. 그러면 선택이 안 된다. (경험담이다.)
세미콜론 없이 따옴표로 닫아야 한다. ...start']
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
<title>Document</title>
<style>
span[style='color: #333333; text-align: start'] {
color: yellow !important;
}
</style>
</head>
<body>
<div>
<span style="color: #333333; text-align: start">speedy</span>
</div>
</body>
</html>
8. A.classname
small orange들만 뽑으려면 요소.클래스명을 해주면 된다.
주의할 점은 띄어쓰기를 하면 안 된다. orange.small
<div class="table">
<apple />
<apple class="small" />
<bento>
<orange class="small" />
</bento>
<plate>
<orange />
</plate>
<plate>
<orange class="small" />
</plate>
</div>
9. :not() 셀렉터
간단하다.
h2:not(:first-of-type) 은 첫 번째 요소가 아닌 h2 요소들을 전부 선택한다.
code 스타일을 고칠 때 `:not` 부정 선택자를 활용했었는데 `code:not(figure code):not(pre code)` 이와 같이 code를 선택하되 figure태그 밑의 code나 pre태그 밑의 code태그는 선택하지 않도록 하여 스타일을 수정했었다.
10. nth-child() 와 nth-of-type()의 차이점
얼핏 보면 사용법이 비슷해서 역할이 헷갈릴 수 있다.
두 선택자의 차이점은 type 조건의 만족 여부이다.
nth-child의 경우 모든 자식 중 순서만 맞다면 해당 요소를 선택한다.- 반면
nth-of-type의 경우 부모 요소의 모든 자식 요소 중 type 조건을 만족하고, 순서를 만족하는 대상을 선택한다.
예시로 이해하면 빠르다.
<div>
<h1>Heading1</h1>
<p>Lorem</p>
<p>ipsum</p>
<p>dolor</p>
</div>
p:nth-child(2)
부모 요소를 기준으로 그냥 두 번째 자식 요소를 선택하기 때문에 Lorem의 색깔이 변경된다.

See the Pen p:nth-child(2) by Olimjo (@OLIMJO) on CodePen.
p:nth-of-type(2)
부모 요소를 기준으로 자식 요소들 중 p에 해당하는 엘리먼트들을 찾아 그중에서 두 번째에 해당하는 요소를 선택한다. 그래서 ipsum이 선택된 모습을 볼 수 있다.

See the Pen p:nth-of-type(2) by hogni-seoul (@hogni-seoul) on CodePen.
11. 기타
:only-of-type
:last-of-type
:empty
등 여기서 전부 다루기에는 너무 많은 가상 selector들이 있다.
