CSS 선택자 완벽 가이드: 초보자를 위한 친절한 설명
CSS 선택자의 모든 것을 쉽고 재미있게 배워보세요. 기본 선택자부터 고급 선택자까지 실습 예제와 함께 완벽하게 정리했습니다.
🎨 CSS 선택자 완벽 가이드
안녕하세요! 오늘은 웹페이지를 꾸미는 핵심 도구인 CSS 선택자에 대해 알아보겠습니다. 색칠공부를 할 때 어떤 부분에 어떤 색을 칠할지 정하는 것처럼, CSS 선택자는 웹페이지의 어떤 부분을 꾸밀지 정하는 역할을 합니다.
MDN의 CSS 선택자 문서에 따르면, CSS는 60개 이상의 선택자와 5개의 결합자를 제공하여 HTML 요소를 정교하게 선택할 수 있습니다.
📚 목차
1. CSS 선택자란?
학급에서 특정 학생을 부를 때를 생각해보세요. "안경 쓴 학생", "빨간 옷 입은 학생", "첫 번째 줄에 앉은 학생" 이런 식으로 특징을 말해서 부르잖아요? CSS 선택자도 비슷한 방식으로 작동합니다!
W3C의 Selectors Level 3 명세에 정의된 바와 같이, CSS 선택자는 HTML 문서의 특정 요소들을 선택하여 스타일을 적용하는 패턴입니다.
/* 이게 바로 CSS의 기본 구조입니다 */
선택자 {
꾸미기: 방법;
}
/* 실제 예시 */
p {
color: blue; /* 모든 문단을 파란색으로 만들기 */
}
2. 기본 선택자
🏷️ 태그 선택자 (Type Selector)
HTML 태그 이름을 그대로 사용합니다. 마치 "강아지", "고양이"라고 종류별로 부르는 것과 같습니다. MDN 문서에서는 이를 "Type Selector"라고 정의합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* 모든 제목을 빨간색으로 */
h1 {
color: red;
}
/* 모든 문단을 초록색으로 */
p {
color: green;
}
/* 모든 버튼을 크게 만들기 */
button {
font-size: 20px;
padding: 10px;
}
</style>
</head>
<body>
<h1>빨간색 제목입니다</h1>
<p>초록색 문단입니다</p>
<button>큰 버튼입니다</button>
</body>
</html>
🎯 클래스 선택자 (Class Selector)
클래스는 여러 요소에게 같은 별명을 줄 수 있습니다. 점(.)으로 시작합니다! MDN의 클래스 선택자 문서에 따르면, 하나의 요소는 여러 개의 클래스를 가질 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* 점(.)으로 시작하는 것이 클래스 선택자입니다 */
.pretty {
background-color: pink;
padding: 10px;
}
.big {
font-size: 30px;
}
/* 두 개의 클래스를 가진 요소 */
.pretty.big {
border: 3px solid purple;
}
</style>
</head>
<body>
<p class="pretty">예쁜 분홍 배경입니다</p>
<p class="big">큰 글씨입니다</p>
<p class="pretty big">예쁘고 크고 테두리도 있습니다</p>
</body>
</html>
🆔 ID 선택자 (ID Selector)
ID는 딱 하나의 요소만 가질 수 있는 고유한 이름입니다. 샵(#)으로 시작합니다! MDN 문서에 명시된 대로, HTML 문서 내에서 ID는 고유해야 합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* 샵(#)으로 시작하는 것이 ID 선택자입니다 */
#special {
background-color: gold;
border: 5px dashed blue;
padding: 20px;
}
#main-title {
text-align: center;
font-size: 40px;
color: navy;
}
</style>
</head>
<body>
<h1 id="main-title">특별한 제목입니다</h1>
<p id="special">금색 배경의 특별한 문단입니다</p>
</body>
</html>
✨ 전체 선택자 (Universal Selector)
별표(*)는 "모든 요소"를 의미합니다. MDN의 Universal Selector 문서에서 설명하듯이, 이 선택자는 모든 타입의 HTML 요소를 선택합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* 페이지의 모든 요소에 적용 */
* {
margin: 0;
padding: 0;
font-family: "맑은 고딕", sans-serif;
}
/* 특정 영역 안의 모든 요소 */
.box * {
color: blue;
}
</style>
</head>
<body>
<div class="box">
<h2>박스 안의 제목</h2>
<p>박스 안의 문단</p>
<span>박스 안의 텍스트</span>
</div>
</body>
</html>
3. 속성 선택자
속성 선택자는 태그가 가진 특별한 표시(속성)를 보고 선택해요. 대괄호 []를 사용해요! MDN의 속성 선택자 문서에서 다양한 속성 선택자 패턴을 확인할 수 있습니다.
기본 속성 선택자
<!DOCTYPE html>
<html>
<head>
<style>
/* title 속성이 있는 모든 요소 */
[title] {
border-bottom: 2px dotted blue;
cursor: help;
}
/* type이 "text"인 input */
input[type="text"] {
border: 2px solid green;
padding: 5px;
}
/* type이 "submit"인 input */
input[type="submit"] {
background-color: blue;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}
/* href가 .pdf로 끝나는 링크 */
a[href$=".pdf"] {
color: red;
}
/* href가 .pdf로 끝나는 링크 뒤에 PDF 아이콘 추가 */
a[href$=".pdf"]:after {
content: " 📄";
}
</style>
</head>
<body>
<p title="마우스를 올려보세요!">나는 설명이 있어요!</p>
<form>
<input type="text" placeholder="텍스트를 입력하세요" />
<input type="submit" value="전송" />
</form>
<a href="document.pdf">PDF 문서 다운로드</a>
</body>
</html>
고급 속성 선택자
<!DOCTYPE html>
<html>
<head>
<style>
/* class에 "btn"이 포함된 요소 */
[class*="btn"] {
padding: 10px;
margin: 5px;
cursor: pointer;
}
/* class가 "btn-"로 시작하는 요소 */
[class^="btn-"] {
border-radius: 5px;
}
/* data- 속성 활용 */
[data-color="red"] {
color: red;
}
[data-color="blue"] {
color: blue;
}
[data-size="big"] {
font-size: 30px;
}
</style>
</head>
<body>
<button class="btn-primary">주요 버튼</button>
<button class="btn-secondary">보조 버튼</button>
<button class="small-btn">작은 버튼</button>
<p data-color="red" data-size="big">빨갛고 큰 글씨입니다</p>
<p data-color="blue">파란 글씨입니다</p>
</body>
</html>
4. 가상 클래스
가상 클래스는 요소의 특별한 상태를 선택합니다. 콜론(:)으로 시작합니다! MDN의 가상 클래스 문서에 따르면, CSS는 80개 이상의 가상 클래스를 제공합니다.
🖱️ 마우스 관련 가상 클래스
<!DOCTYPE html>
<html>
<head>
<style>
/* 마우스를 올렸을 때 */
.hover-box {
background-color: lightblue;
padding: 20px;
transition: all 0.3s;
}
.hover-box:hover {
background-color: darkblue;
color: white;
transform: scale(1.1);
}
/* 링크 상태들 */
a {
text-decoration: none;
padding: 5px;
}
a:link {
color: blue; /* 방문하지 않은 링크 */
}
a:visited {
color: purple; /* 방문한 링크 */
}
a:hover {
background-color: yellow; /* 마우스 올렸을 때 */
}
a:active {
color: red; /* 클릭하는 순간 */
}
/* 버튼 효과 */
.magic-button {
background-color: green;
color: white;
padding: 15px 30px;
border: none;
font-size: 18px;
cursor: pointer;
transition: all 0.3s;
}
.magic-button:hover {
background-color: darkgreen;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.magic-button:active {
transform: translateY(2px);
}
</style>
</head>
<body>
<div class="hover-box">마우스를 올려보세요! 색이 변해요!</div>
<p>
<a href="https://www.google.com">구글 링크</a>
<a href="https://www.naver.com">네이버 링크</a>
</p>
<button class="magic-button">마법 버튼을 눌러보세요!</button>
</body>
</html>
📝 폼 관련 가상 클래스
<!DOCTYPE html>
<html>
<head>
<style>
/* 포커스 받았을 때 */
input:focus {
outline: 3px solid blue;
background-color: lightyellow;
}
/* 체크된 체크박스 */
input[type="checkbox"]:checked {
width: 20px;
height: 20px;
}
/* 체크박스 옆 라벨 스타일 */
input[type="checkbox"]:checked + label {
color: green;
font-weight: bold;
}
/* 비활성화된 요소 */
input:disabled {
background-color: #ccc;
cursor: not-allowed;
}
/* 필수 입력 필드 */
input:required {
border-left: 5px solid red;
}
/* 유효한/무효한 입력 */
input:valid {
border-color: green;
}
input:invalid {
border-color: red;
}
</style>
</head>
<body>
<form>
<p>
<input type="text" placeholder="여기를 클릭해보세요!" required />
</p>
<p>
<input type="checkbox" id="agree" />
<label for="agree">동의합니다</label>
</p>
<p>
<input type="email" placeholder="이메일 주소" required />
</p>
<p>
<input type="text" placeholder="비활성화된 입력창" disabled />
</p>
</form>
</body>
</html>
🔢 순서 관련 가상 클래스
<!DOCTYPE html>
<html>
<head>
<style>
/* 첫 번째 자식 */
li:first-child {
color: red;
font-weight: bold;
}
/* 마지막 자식 */
li:last-child {
color: blue;
font-weight: bold;
}
/* n번째 자식 */
li:nth-child(3) {
background-color: yellow;
}
/* 짝수 번째 */
tr:nth-child(even) {
background-color: #f2f2f2;
}
/* 홀수 번째 */
tr:nth-child(odd) {
background-color: white;
}
/* 3의 배수 번째 */
div.box:nth-child(3n) {
background-color: pink;
}
/* 특정 타입의 첫 번째 */
p:first-of-type {
font-size: 20px;
color: green;
}
</style>
</head>
<body>
<ul>
<li>첫 번째 항목 (빨간색)</li>
<li>두 번째 항목</li>
<li>세 번째 항목 (노란 배경)</li>
<li>네 번째 항목</li>
<li>마지막 항목 (파란색)</li>
</ul>
<table border="1" style="width: 100%;">
<tr>
<td>1번 행</td>
<td>홀수</td>
</tr>
<tr>
<td>2번 행</td>
<td>짝수</td>
</tr>
<tr>
<td>3번 행</td>
<td>홀수</td>
</tr>
<tr>
<td>4번 행</td>
<td>짝수</td>
</tr>
</table>
<div>
<h2>제목</h2>
<p>첫 번째 문단 (크고 초록색)</p>
<p>두 번째 문단</p>
</div>
</body>
</html>
🎯 유용한 가상 클래스
<!DOCTYPE html>
<html>
<head>
<style>
/* :not() - 제외하기 */
.menu li:not(:last-child) {
border-right: 1px solid #ccc;
}
/* :empty - 비어있는 요소 */
p:empty {
display: none;
}
/* :target - 앵커 대상 */
div:target {
background-color: yellow;
padding: 20px;
border: 2px solid orange;
}
/* ::before와 ::after - 가상 요소 */
.quote::before {
content: "『";
color: red;
font-size: 30px;
}
.quote::after {
content: "』";
color: red;
font-size: 30px;
}
/* 첫 글자 꾸미기 */
.story::first-letter {
font-size: 50px;
float: left;
line-height: 1;
margin-right: 5px;
color: blue;
}
/* 첫 줄 꾸미기 */
.story::first-line {
font-weight: bold;
color: green;
}
</style>
</head>
<body>
<ul class="menu" style="list-style: none; display: flex; gap: 10px;">
<li>홈</li>
<li>소개</li>
<li>서비스</li>
<li>연락처</li>
</ul>
<p></p>
<!-- 이 빈 문단은 보이지 않아요 -->
<p><a href="#section1">섹션 1로 이동</a></p>
<div id="section1">타겟이 된 섹션입니다!</div>
<p class="quote">명언이 들어가는 곳</p>
<p class="story">
옛날 옛적에 아주 작은 마을에 살고 있던 소녀가 있었습니다. 그 소녀는 매일
아침 일찍 일어나 정원에 물을 주었어요.
</p>
</body>
</html>
5. 결합자
결합자는 선택자들 사이의 관계를 나타냅니다. 가족 관계처럼 생각하면 쉬워요! MDN의 결합자 문서에서 4가지 주요 결합자를 설명합니다.
후손 선택자 (Descendant Combinator)
공백으로 표현되는 후손 선택자는 특정 요소의 모든 후손을 선택합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* .container 안의 모든 p 태그 */
.container p {
color: blue;
}
/* nav 안의 모든 a 태그 */
nav a {
text-decoration: none;
color: white;
padding: 10px;
background-color: navy;
}
/* 여러 단계도 가능 */
.box div p {
background-color: yellow;
}
</style>
</head>
<body>
<div class="container">
<p>나는 파란색이에요!</p>
<div>
<p>나도 파란색이에요!</p>
</div>
</div>
<nav>
<a href="#">메뉴1</a>
<a href="#">메뉴2</a>
<div>
<a href="#">서브메뉴</a>
</div>
</nav>
<div class="box">
<div>
<p>나는 노란 배경이에요!</p>
</div>
</div>
</body>
</html>
자식 선택자 (Child Combinator)
> 기호로 표현되는 자식 선택자는 직접적인 자식 요소만 선택합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* 직접적인 자식만 선택 */
.parent > p {
border: 2px solid red;
padding: 10px;
}
/* ul의 직접 자식 li만 */
ul > li {
color: blue;
font-weight: bold;
}
/* 중첩된 li는 영향 없음 */
ul ul > li {
color: green;
font-weight: normal;
}
</style>
</head>
<body>
<div class="parent">
<p>나는 직접 자식이라 빨간 테두리가 있어요!</p>
<div>
<p>나는 손자라서 테두리가 없어요.</p>
</div>
</div>
<ul>
<li>
파란색 굵은 글씨
<ul>
<li>초록색 보통 글씨</li>
<li>초록색 보통 글씨</li>
</ul>
</li>
<li>파란색 굵은 글씨</li>
</ul>
</body>
</html>
인접 형제 선택자 (Next-sibling Combinator)
+ 기호로 표현되는 인접 형제 선택자는 바로 다음에 오는 형제 요소를 선택합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* h2 바로 다음의 p */
h2 + p {
color: red;
font-size: 18px;
font-style: italic;
}
/* 체크박스 바로 다음의 label */
input[type="checkbox"] + label {
margin-left: 5px;
cursor: pointer;
}
input[type="checkbox"]:checked + label {
color: green;
font-weight: bold;
}
/* 이미지 다음의 설명 */
img + p {
font-size: 12px;
color: gray;
font-style: italic;
}
</style>
</head>
<body>
<h2>제목입니다</h2>
<p>제목 바로 다음의 문단은 빨갛고 기울어져요!</p>
<p>그 다음 문단은 평범해요.</p>
<input type="checkbox" id="check1" />
<label for="check1">체크해보세요!</label>
<img src="https://via.placeholder.com/200" alt="샘플 이미지" />
<p>이미지 설명입니다.</p>
</body>
</html>
일반 형제 선택자 (Subsequent-sibling Combinator)
~ 기호로 표현되는 일반 형제 선택자는 이후에 오는 모든 형제 요소를 선택합니다.
<!DOCTYPE html>
<html>
<head>
<style>
/* h2 다음에 오는 모든 p */
h2 ~ p {
margin-left: 20px;
border-left: 3px solid blue;
padding-left: 10px;
}
/* 첫 번째 .special 다음의 모든 div */
.special ~ div {
background-color: lightgray;
padding: 10px;
margin: 5px 0;
}
</style>
</head>
<body>
<h2>주제</h2>
<p>첫 번째 문단</p>
<p>두 번째 문단</p>
<div>일반 div</div>
<p>세 번째 문단</p>
<div class="special">특별한 div</div>
<div>회색 배경 1</div>
<div>회색 배경 2</div>
<p>일반 문단</p>
<div>회색 배경 3</div>
</body>
</html>
6. CSS 우선순위
여러 CSS 규칙이 충돌할 때, 어떤 규칙이 적용되는지 알아봅시다! MDN의 명시도(Specificity) 문서에서 자세한 계산 방법을 확인할 수 있습니다.
📊 우선순위(명시도) 계산 방법
CSS 명시도는 ID-CLASS-TYPE 형식 (A-B-C)으로 계산됩니다:
- A: ID 선택자의 개수
- B: 클래스 선택자, 속성 선택자, 가상 클래스의 개수
- C: 타입 선택자와 가상 요소의 개수
비교할 때는 점수를 더하는 것이 아니라, 왼쪽 컬럼부터 차례로 비교합니다!
<!DOCTYPE html>
<html>
<head>
<style>
/* 명시도 계산 예제 */
/* 타입 선택자 */
p {
color: black;
} /* 0-0-1 */
/* 클래스 선택자 */
.text {
color: blue;
} /* 0-1-0 → 0-0-1보다 우선 */
/* ID 선택자 */
#special {
color: red;
} /* 1-0-0 → 0-1-0보다 우선 */
/* 복합 선택자 계산 */
p.text {
color: green;
} /* 0-1-1 (클래스1개 + 타입1개) */
div p.text {
color: purple;
} /* 0-1-2 (클래스1개 + 타입2개) → 0-1-1보다 우선 */
#special .text {
color: orange;
} /* 1-1-0 (ID1개 + 클래스1개) → 0-1-2보다 우선 */
/* 속성 선택자도 CLASS 컬럼 */
p[class] {
color: yellow;
} /* 0-1-1 (속성1개 + 타입1개) */
/* 가상 클래스도 CLASS 컬럼 */
p:hover {
color: pink;
} /* 0-1-1 (가상클래스1개 + 타입1개) */
</style>
</head>
<body>
<p>기본 검정색 (0-0-1)</p>
<p class="text">파란색이 이김 (0-1-0 > 0-0-1)</p>
<p id="special">빨간색이 이김 (1-0-0 > 0-1-0)</p>
<p id="special" class="text">ID가 있어서 빨간색 유지</p>
</body>
</html>
🎯 명시도 비교 원리
/* 컬럼별 비교 방식 */
.box /* 0-1-0 */
p.box /* 0-1-1 */
div p.box /* 0-1-2 */ ← 가장 높음 (C 컬럼이 가장 큼)
#header /* 1-0-0 */ ← 가장 높음 (A 컬럼이 있음)
.nav .menu /* 0-2-0 */
.nav ul li /* 0-1-2 */
/* 컬럼별 비교 ✅ */
/* 1-0-0 vs 0-2-0 → 첫 번째 컬럼에서 1 > 0이므로 #header 승리 */
🎯 우선순위 실전 예제
<!DOCTYPE html>
<html>
<head>
<style>
/* 같은 명시도일 때는 나중 선언이 이김 */
.box {
background-color: red; /* 0-1-0 */
}
.box {
background-color: blue; /* 0-1-0 → 나중 선언이므로 적용 */
}
/* 더 구체적인 선택자가 이김 */
.container .box {
background-color: green; /* 0-2-0 → 0-1-0보다 우선 */
}
.box {
background-color: yellow; /* 0-1-0 → 적용 안됨 */
}
/* !important는 최강 */
.box {
background-color: purple !important;
}
/* 인라인 스타일은 가장 높은 명시도 */
/* <div style="background-color: pink;"> → 별도 우선순위 */
/* 상속은 명시도가 없음 (가장 약함) */
.parent {
color: red; /* 자식에게 상속 */
}
.parent p {
/* 상속받은 color보다 직접 지정이 우선 */
color: blue; /* 0-1-1 > 상속 */
}
</style>
</head>
<body>
<div class="container">
<div class="box">배경색: purple (!important 때문)</div>
</div>
<div class="parent">
<p>빨간색 (상속)</p>
<p>파란색 (직접 지정)</p>
<p style="color: green;">초록색 (인라인 스타일)</p>
</div>
</body>
</html>
7. 실습 예제
🎮 인터랙티브 버튼 만들기
<!DOCTYPE html>
<html>
<head>
<style>
.game-button {
background: linear-gradient(to bottom, #4caf50, #45a049);
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 12px;
box-shadow: 0 4px #999;
transition: all 0.1s;
}
.game-button:hover {
background: linear-gradient(to bottom, #45a049, #4caf50);
}
.game-button:active {
box-shadow: 0 2px #666;
transform: translateY(2px);
}
/* 다양한 색상의 버튼들 */
.red {
background: linear-gradient(to bottom, #f44336, #da190b);
}
.red:hover {
background: linear-gradient(to bottom, #da190b, #f44336);
}
.blue {
background: linear-gradient(to bottom, #008cba, #006687);
}
.blue:hover {
background: linear-gradient(to bottom, #006687, #008cba);
}
</style>
</head>
<body>
<button class="game-button">기본 버튼</button>
<button class="game-button red">빨간 버튼</button>
<button class="game-button blue">파란 버튼</button>
</body>
</html>
📋 체크리스트 만들기
<!DOCTYPE html>
<html>
<head>
<style>
.checklist {
list-style: none;
padding: 0;
}
.checklist li {
padding: 10px;
margin: 5px 0;
background-color: #f9f9f9;
border-radius: 5px;
position: relative;
padding-left: 40px;
}
.checklist input[type="checkbox"] {
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
cursor: pointer;
}
.checklist input[type="checkbox"]:checked + label {
text-decoration: line-through;
color: #999;
}
.checklist input[type="checkbox"]:checked ~ .check-mark {
display: block;
}
.check-mark {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: green;
font-size: 20px;
display: none;
}
/* 완료된 항목 스타일 - :has()는 최신 브라우저에서 지원 */
.checklist li:has(input:checked) {
background-color: #e8f5e9;
opacity: 0.7;
}
</style>
</head>
<body>
<ul class="checklist">
<li>
<input type="checkbox" id="task1" />
<label for="task1">숙제하기</label>
<span class="check-mark">✓</span>
</li>
<li>
<input type="checkbox" id="task2" />
<label for="task2">방 청소하기</label>
<span class="check-mark">✓</span>
</li>
<li>
<input type="checkbox" id="task3" />
<label for="task3">책 읽기</label>
<span class="check-mark">✓</span>
</li>
</ul>
</body>
</html>
🎨 테이블 꾸미기
<!DOCTYPE html>
<html>
<head>
<style>
.pretty-table {
border-collapse: collapse;
width: 100%;
margin: 20px 0;
}
.pretty-table th,
.pretty-table td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
.pretty-table th {
background-color: #4caf50;
color: white;
font-weight: bold;
}
/* 줄무늬 효과 */
.pretty-table tr:nth-child(even) {
background-color: #f2f2f2;
}
/* 마우스 오버 효과 */
.pretty-table tr:hover {
background-color: #ddd;
}
/* 첫 번째 열 강조 */
.pretty-table td:first-child {
font-weight: bold;
background-color: #e8f5e9;
}
/* 마지막 열 정렬 */
.pretty-table td:last-child {
text-align: center;
}
</style>
</head>
<body>
<table class="pretty-table">
<tr>
<th>과목</th>
<th>점수</th>
<th>등급</th>
</tr>
<tr>
<td>국어</td>
<td>95</td>
<td>A</td>
</tr>
<tr>
<td>수학</td>
<td>88</td>
<td>B</td>
</tr>
<tr>
<td>영어</td>
<td>92</td>
<td>A</td>
</tr>
<tr>
<td>과학</td>
<td>86</td>
<td>B</td>
</tr>
</table>
</body>
</html>
🎯 카드 레이아웃
<!DOCTYPE html>
<html>
<head>
<style>
.card-container {
display: flex;
gap: 20px;
flex-wrap: wrap;
justify-content: center;
}
.card {
width: 200px;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
transition: transform 0.3s, box-shadow 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
}
.card img {
width: 100%;
height: 150px;
object-fit: cover;
}
.card-content {
padding: 15px;
}
.card-content h3 {
margin: 0 0 10px 0;
color: #333;
}
.card-content p {
margin: 0;
color: #666;
font-size: 14px;
}
.card-content button {
margin-top: 10px;
width: 100%;
padding: 8px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.card-content button:hover {
background-color: #45a049;
}
/* 특별한 카드 */
.card.featured {
border-color: gold;
border-width: 3px;
}
.card.featured::before {
content: "⭐ 추천";
position: absolute;
top: 10px;
right: 10px;
background-color: gold;
color: white;
padding: 5px 10px;
border-radius: 15px;
font-size: 12px;
}
</style>
</head>
<body>
<div class="card-container">
<div class="card">
<img
src="https://via.placeholder.com/200x150/FF6B6B/ffffff?text=카드1"
alt="카드 이미지"
/>
<div class="card-content">
<h3>일반 카드</h3>
<p>이것은 일반적인 카드입니다.</p>
<button>자세히 보기</button>
</div>
</div>
<div class="card featured" style="position: relative;">
<img
src="https://via.placeholder.com/200x150/4ECDC4/ffffff?text=카드2"
alt="카드 이미지"
/>
<div class="card-content">
<h3>특별한 카드</h3>
<p>이것은 추천 카드입니다!</p>
<button>자세히 보기</button>
</div>
</div>
<div class="card">
<img
src="https://via.placeholder.com/200x150/45B7D1/ffffff?text=카드3"
alt="카드 이미지"
/>
<div class="card-content">
<h3>또 다른 카드</h3>
<p>마우스를 올려보세요!</p>
<button>자세히 보기</button>
</div>
</div>
</div>
</body>
</html>
📚 정리하기
CSS 선택자는 웹페이지를 꾸미는 핵심 도구입니다!
기억해야 할 중요한 내용:
-
기본 선택자
- 태그 선택자:
p,div,h1 - 클래스 선택자:
.classname - ID 선택자:
#idname - 전체 선택자:
*
- 태그 선택자:
-
속성 선택자
[속성]: 속성이 있는 요소[속성="값"]: 정확히 일치[속성^="시작"]: 시작 부분 일치[속성$="끝"]: 끝 부분 일치[속성*="포함"]: 포함하는 경우
-
가상 클래스
:hover- 마우스 올렸을 때:active- 클릭할 때:focus- 포커스 받을 때:first-child- 첫 번째 자식:nth-child()- n번째 자식
-
결합자
- 공백 - 후손 선택자
>- 자식 선택자+- 인접 형제 선택자~- 일반 형제 선택자
-
우선순위 (명시도)
- A-B-C 형식으로 계산: ID개수-클래스개수-타입개수
- 왼쪽 컬럼부터 비교 (점수 덧셈 ❌)
- !important > 인라인 스타일 > ID(A) > 클래스(B) > 타입(C)
- 같은 명시도면 나중 선언이 적용
더 자세한 내용은 MDN의 CSS 선택자 종합 가이드와 W3C CSS Selectors 명세를 참고하세요.