가상 클래스(Pseudo-class)와 가상 요소(Pseudo-element)라는 것이 있는데 별도로 이름을 지정하지 않아도 마치 클래스나 요소가 있는 것처럼 사용할 수 있는 스타일 규칙이라고 볼 수 있다.
가상 클래스(Pseudo-class)란?
CSS에서 요소의 특정 상태나 조건을 기반으로 스타일을 적용하는 선택자이다.
별도로 class를 지정하지 않고도 class를 지정한 것처럼 요소를 선택할 수 있다.
의사 클래스라고도 부른다.
주요 가상 클래스 종류 및 예시
:hover (마우스 오버)
마우스 포인터가 요소 위에 올라갔을 때 스타일을 적용한다.
button:hover {
background-color: blue;
cursor: pointer;
}
위 코드는 button 요소에 마우스 포인터를 올리면 배경색이 파란색으로 변경되고, 커서가 포인터 모양으로 바뀐다.
(버튼의 기본 모양은 저번 글에서 설정한 CSS 디자인 형식을 따랐다)
:active (활성화)
요소가 활성화되었을 때(마우스 버튼을 누르고 있는 동안) 스타일을 적용한다.
button:active {
background-color: orange;
}
위 코드는 button 요소를 클릭하고 있는 동안 배경색이 주황색으로 변경된다.
:focus (포커스):
요소가 포커스를 받았을 때(입력 양식에 커서가 위치했을 때) 스타일을 적용한다.
<body>
<input type="text">
</body>
input:focus {
border: 10px solid red;
}
위 코드는 input 요소에 포커스가 맞춰지면 빨간색 테두리가 표시된다.
:visited (방문한)
사용자가 방문한 링크에 스타일을 적용한다.
<body>
<a href="https://www.naver.com">네이버 홈페이지</a>
</body>
a:visited {
color: red;
}
위 코드는 사용자가 방문한 a 요소(링크)의 글자색을 빨간색으로 변경한다.
:first-child (첫 번째 자식)
부모 요소의 첫 번째 자식 요소에 스타일을 적용한다.
<body>
<p>1번</p>
<p>2번</p>
<p>3번</p>
</body>
p:first-child {
color: red;
font-weight: bold;
}
위 코드는 부모 요소의 첫 번째 <p> 자식 요소의 글자를 굵게, 빨간색으로 표시한다.
별도로 부모 태그가 없는 것처럼 보이지만 실제로는 <body> 태그를 부모 태그로 취급해서 1번째 <p>태그만 적용이 된 모습이다.
여기서 잠깐 부모 태그와 자식 태그가 정확히 무엇인지 한번 더 짚고 넘어가겠다.
부모 태그와 자식 태그란?
- 부모 태그 : 다른 태그를 포함하는 태그
- 자식 태그 : 다른 태그에 의해 포함되는 태그
그렇다면 아래와 같은 코드가 있다면 어떨까?
<body>
<p>1번</p>
<p>2번</p>
<p>3번</p>
<div>
<p>1번</p>
<p>2번</p>
<p>3번</p>
</div>
</body>
그렇다면 이처럼 <body> 태그의 1번째 자식인 1번이 스타일 적용을 받는 것을 볼 수 있다.
또한 <div> 태그의 첫번째 자식인 4번 또한 스타일 적용을 받는 것을 볼 수 있다.
:last-child (마지막 자식)
부모 요소의 마지막 자식 요소에 스타일을 적용한다.
p:last-child {
font-style: italic;
}
위 코드는 부모 요소의 마지막 <p> 자식 요소의 글자를 기울여 표시한다.
위의 설정을 그대로 유지한 채로 해당 스타일을 추가한다면 마지막 자식인 6번만이 스타일 적용을 받아서 기울임 효과를 받는 것을 알 수 있다.
위에서 나온 태그들은 모두 1번째 혹은 마지막 자식 태그만을 변경하기 때문에 사실상 제약이 너무 크다. 그렇기 때문에 원하는 자식 태그를 변경 시킬 수 있는 태그를 사용해야하는데 그것이 바로 :nth-child(n)이라는 가상 클래스다.
:nth-child(n) (n번째 자식)
부모 요소의 n번째 자식 요소에 스타일을 적용한다.
:nth-child(n)는 다양한 사용법이 있다.
1. 숫자 사용
<ul>
<li>항목 1</li>
<li>항목 2</li>
<li>항목 3</li>
<li>항목 4</li>
<li>항목 5</li>
</ul>
li:nth-child(3) {
color: red;
}
위 코드는 <ul> 요소의 3번째 <li> 자식 요소에 빨간색 글씨 스타일을 적용한다.

:nth-child(n)의 장점은 n에 다양한 수치를 넣을 수 있다는 점이다. 그 중 하나는 키워드를 사용하는 방법이다.
2. 키워드 사용
- even : 짝수 번째 자식 요소를 선택한다.
- odd : 홀수 번째 자식 요소를 선택한다.
HTML
<table>
<tr>
<td>1행 1열</td>
<td>1행 2열</td>
</tr>
<tr>
<td>2행 1열</td>
<td>2행 2열</td>
</tr>
<tr>
<td>3행 1열</td>
<td>3행 2열</td>
</tr>
<tr>
<td>4행 1열</td>
<td>4행 2열</td>
</tr>
</table>
tr:nth-child(even) {
background-color: lightgray;
}
이처럼 짝수 요소만 선택해서 스타일을 적용하게 할 수도 있고 반대로 홀수 요소만 선택할 수도 있을 것이다.
만약에 css에서 스타일을 적용할 대상을 <tr>에서 <td>로 바꾼다면 행이 아닌 열에 스타일을 적용할 수 있다.
td:nth-child(even) {
background-color: lightgray;
}
table 태그에 대해서
<table>: 표 전체를 정의한다.
<tr>: 표의 행(가로줄)을 정의한다.
<td>: 표의 일반 셀(열)을 정의하고 데이터를 입력한다.
또한 수식을 사용해서 특정한 순서의 태그에만 스타일을 적용하는 것도 가능하다.
3. 수식 사용
- an + b 형태의 수식을 사용하여 특정 패턴의 자식 요소를 선택한다.
- a : 반복되는 패턴의 간격
- b : 시작 위치
<ul>
<li>항목 1</li>
<li>항목 2</li>
<li>항목 3</li>
<li>항목 4</li>
<li>항목 5</li>
<li>항목 6</li>
<li>항목 7</li>
<li>항목 8</li>
<li>항목 9</li>
</ul>
li:nth-child(3n + 1) {
font-weight: bold; color: red;
}
위 코드는 <ul> 요소의 3n+1 번째 <li> 자식 요소(1, 4, 7번째 항목)에 굵은 글씨와 붉은색 색상 스타일을 적용한다.
그렇다면 다음과 같은 경우 어떻게 적용 될까?
<body>
<ol>
<li>목록 1 - 항목 1</li>
<li>목록 1 - 항목 2</li>
</ol>
<p>일반 문단</p>
<ol>
<li>목록 2 - 항목 1</li>
<li>목록 2 - 항목 2</li>
</ol>
<ol>
<li>목록 3 - 항목 1</li>
<li>목록 3 - 항목 2</li>
</ol>
</body>
ol:nth-child(2n) {
background-color: lightblue;
}
<ol> 태그를 사용해서 순서가 있는 목록을 작성했고 중간에 <p> 태그를 사용해서 1개의 단락을 추가했다.
css에서는 nth-child(2n) 가상 클래스를 사용해서 2n 즉 짝수 단위에만 스타일이 적용되도록 설정했다.
결과는 다음과 같다.
목록 3에만 스타일이 적용된 것을 볼 수 있다.
짝수 단위인데 왜 목록 3에 스타일이 적용되는지 궁금할 수 있을 것이다.
그것은 바로 :nth-child(n) 가상 클래스가 오직 순서만을 기준으로 적용되기 때문이다.
실제로 해당 코드의 태그는 총 4가지이다.
- 목록1
- 일반 문단
- 목록2
- 목록3
(X) 보다시피 목록1은 홀수이기 때문에 적용이 안되기 때문에 그대로이고
(X) 일반 문단은 짝수이지만 <p>태그이기 때문에 <ol> 스타일의 적용이 안되기 때문에 다음으로 넘어간다.
(X) 목록2는 <ol> 태그이지만 홀수이기 때문에 적용이 안되기 때문에 그대로이다.
(O) 마지막 목록3은 <ol> 태그인 동시에 짝수 이기 떄문에 홀로 스타일이 적용되는 것이다.
이처럼 :nth-child(n)라는 가상 클래스는 오직 순서만을 기준으로 적용되기 때문에 실제로 <ol> 태그를 가진 목록은 3개임에도 불구하고 목록2가 아닌 4번째(짝수) 순서에 있는 목록3에만 스타일이 적용되게 되는 것이다.
만약에 코드의 순서를 바꾸어 다음과 같이 코드를 수정한다면
<body>
<ol>
<li>목록 1 - 항목 1</li>
<li>목록 1 - 항목 2</li>
</ol>
<ol>
<li>목록 2 - 항목 1</li>
<li>목록 2 - 항목 2</li>
</ol>
<p>일반 문단</p>
<ol>
<li>목록 3 - 항목 1</li>
<li>목록 3 - 항목 2</li>
</ol>
</body>
목록 2와 3이 모두 짝수이며 <ol>태그이기 때문에 스타일의 적용을 받게 된다.
그렇다면 :nth-child(n) 처럼 순서만을 기준으로 스타일을 적용하는 것이 아니라 <특정 태그>를 기준으로만 순서를 따져서 스타일을 적용하는 방법은 없을까?
그럴 경우 사용하는 것이 바로 :nth-of-type(n)라는 가상 클래스이다.
:nth-child(n)와의 차이점
:nth-child(n)
- 부모 요소의 모든 자식 요소를 대상으로 순서를 계산한다.
- 따라서 특정 태그뿐만 아니라 다른 태그들도 순서 계산에 포함된다.
:nth-of-type(n)
- 부모 요소의 자식 요소 중에서 특정 태그만을 대상으로 순서를 계산한다.
- 따라서 특정 태그만을 선택하여 스타일을 적용할 수 있다.
<div>
<p>문단 1</p>
<span>스팬 1</span>
<p>문단 2</p>
<span>스팬 2</span>
<p>문단 3</p>
</div>
p:nth-of-type(2) {
color: blue;
}
이처럼 <p> 태그를 가진 내용 중 2번째에 있는 문단2만이 스타일의 적용을 받는 것을 알 수 있다.
스타일을 2가 아니라 3n을 적용 시킨다면
p:nth-of-type(3n){
color: blue;
}
이처럼 3번째마다 스타일이 적용되어 문단3만 스타일의 적용을 받는 것을 알 수 있다.
그렇다면 좀 더 복잡하게 복합적으로 스타일을 적용하면 어떻게 될까?
p:nth-of-type(n){
font-size: 30px;
}
p:nth-of-type(3n){
color: blue;
}
span:nth-of-type(2n){
background-color: aquamarine;
}
이런식으로 원하는 순서의 태그에 각각 스타일을 적용할 수 있게 된다.
위에서 언급한 child 가상 클래스 외에도 다양한 child 계통의 가상 클래스가 존재한다. 아래는 주요 목록이다.
1. :first-child
- 부모 요소의 첫 번째 자식 요소를 선택합니다.
- 자식 요소의 타입(태그 이름)에 관계없이 첫 번째 위치에 있는 요소에 스타일을 적용합니다.
- 예시: p:first-child { color: red; } (부모 요소의 첫 번째 <p> 요소에 빨간색 글씨 스타일 적용)
2. :last-child
- 부모 요소의 마지막 자식 요소를 선택합니다.
- 자식 요소의 타입(태그 이름)에 관계없이 마지막 위치에 있는 요소에 스타일을 적용합니다.
- 예시: li:last-child { border-bottom: none; } (부모 요소의 마지막 <li> 요소에 아래쪽 테두리 제거)
3. :nth-child(n)
- 부모 요소의 자식 요소 중 n번째 요소에 스타일을 적용합니다.
- n은 숫자, 키워드(even, odd), 수식을 사용하여 다양한 패턴으로 자식 요소를 선택할 수 있습니다.
- 예시:
- li:nth-child(3): 세 번째 <li> 요소에 스타일 적용
- tr:nth-child(even): 짝수 번째 <tr> 요소에 스타일 적용
- li:nth-child(3n + 1): 3n+1 번째 <li> 요소에 스타일 적용
4. :nth-last-child(n)
- 부모 요소의 자식 요소 중 뒤에서부터 n번째 요소에 스타일을 적용합니다.
- :nth-child(n)와 반대로 뒤에서부터 순서를 계산합니다.
- 예시:
- li:nth-last-child(1): 마지막 <li> 요소에 스타일 적용
- tr:nth-last-child(even): 뒤에서부터 짝수 번째 <tr> 요소에 스타일 적용
5. :only-child
- 부모 요소의 유일한 자식 요소에 스타일을 적용합니다.
- 부모 요소 안에 자식 요소가 단 하나만 존재할 때 스타일이 적용됩니다.
- 예시: p:only-child { font-style: italic; } (부모 요소 안에 <p> 요소가 하나만 있을 때 기울임꼴 스타일 적용)
6. :first-of-type
- 부모 요소의 자식 요소 중 특정 타입(태그 이름)의 첫 번째 요소에 스타일을 적용합니다.
- 특정 타입의 요소들 중에서 첫 번째 요소에 스타일을 적용합니다.
- 예시: p:first-of-type { font-weight: bold; } (부모 요소의 첫 번째 <p> 요소에 굵은 글씨 스타일 적용)
7. :last-of-type
- 부모 요소의 자식 요소 중 특정 타입(태그 이름)의 마지막 요소에 스타일을 적용합니다.
- 특정 타입의 요소들 중에서 마지막 요소에 스타일을 적용합니다.
- 예시: p:last-of-type { color: blue; } (부모 요소의 마지막 <p> 요소에 파란색 글씨 스타일 적용)
8. :nth-of-type(n)
- 부모 요소의 자식 요소 중 특정 타입(태그 이름)의 n번째 요소에 스타일을 적용합니다.
- :nth-child(n)와 달리 특정 타입의 요소만을 대상으로 순서를 계산합니다.
- 예시:
- p:nth-of-type(2): 두 번째 <p> 요소에 스타일 적용
- li:nth-of-type(odd): 홀수 번째 <li> 요소에 스타일 적용
9. :nth-last-of-type(n)
- 부모 요소의 자식 요소 중 특정 타입의 뒤에서부터 n번째 요소에 스타일을 적용합니다.
- :nth-of-type(n)와 마찬가지로 특정 타입의 요소만을 대상으로 순서를 계산합니다.
- 예시:
- p:nth-last-of-type(1): 마지막 <p> 요소에 스타일 적용
- li:nth-last-of-type(odd): 뒤에서부터 홀수 번째 <li> 요소에 스타일 적용
'프로그래밍 > css 기초' 카테고리의 다른 글
CSS 기초 공부(9) - 텍스트 스타일 (0) | 2025.03.11 |
---|---|
CSS 기초 공부(8) - 가상 요소(Pseudo-element)란? (0) | 2025.03.10 |
CSS 기초 공부(6) - class란? (0) | 2025.03.10 |
CSS 기초 공부(5) - 박스 모델 (0) | 2025.03.10 |
CSS 기초 공부(4) - 수치를 표현하는 방법 (0) | 2025.03.09 |