코샵
끄적끄적 코딩 공방
코샵

인기 글

  • 분류 전체보기 (476) N
    • MongoDB (4)
    • 일기장 (4)
    • Unity (138)
      • Tip (41)
      • Project (1)
      • Design Pattern (8)
      • Firebase (6)
      • Asset (2)
    • 파이썬 (127)
      • Basic (40)
      • OpenCV (8)
      • Pandas (15)
      • PyQT (3)
      • SBC(Single Board Computer) (1)
      • 크롤링 (14)
      • Fast API (29)
      • Package (6)
    • Linux (4)
    • C# (97)
      • Algorithm (11)
      • Window (7)
    • TypeScript (45) N
      • CSS (7) N
    • Git (11)
    • SQL (5)
    • Flutter (10)
      • Tip (1)
    • System (1)
    • BaekJoon (6)
    • Portfolio (2)
    • MacOS (1)
    • 유틸리티 (1)
    • 서비스 (6)
    • 자동화 (3)
    • Hobby (10)
      • 물생활 (10)
      • 식집사 (0)
전체 방문자
오늘
어제

최근 댓글

최근 글

반응형
hELLO · Designed By 정상우.
코샵

끄적끄적 코딩 공방

TypeScript/CSS

CSS 선택자 총정리: 원하는 요소를 정확히 타겟팅하는 방법

2025. 5. 14. 10:16
반응형

CSS를 사용하다 보면 가장 먼저 마주치는 도전 과제는 스타일을 적용할 특정 요소를 정확하게 선택하는 것입니다. 복잡한 웹 페이지에서 원하는 요소만 골라내는 것은 마치 모래사장에서 특정 모양의 조개껍데기를 찾는 것처럼 느껴질 수 있습니다. 하지만 CSS 선택자(Selectors)를 제대로 이해하고 활용한다면, 아무리 복잡한 HTML 구조에서도 필요한 요소를 정확히 타겟팅할 수 있습니다. 이 글에서는 CSS 선택자의 기본부터 고급 기법까지 완벽하게 정리해 보겠습니다.

기본 선택자

CSS 선택자의 기본 중의 기본부터 시작해봅시다. 이 선택자들은 CSS를 막 시작한 분들도 쉽게 이해할 수 있는 것들입니다.

전체 선택자(Universal Selector)

별표(*)를 사용하여 모든 요소를 선택합니다.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

모든 요소에 기본 스타일을 적용할 때 유용하지만, 성능에 영향을 줄 수 있으므로 신중하게 사용해야 합니다.

타입 선택자(Type Selector)

HTML 태그 이름을 사용하여 특정 유형의 모든 요소를 선택합니다.

p {
  line-height: 1.6;
}

h1 {
  font-size: 2rem;
}

클래스 선택자(Class Selector)

점(.)을 사용하여 특정 클래스를 가진 요소를 선택합니다. 가장 널리 사용되는 선택자입니다.

.button {
  display: inline-block;
  padding: 10px 20px;
}

.primary {
  background-color: #3498db;
}

여러 클래스를 가진 요소를 선택할 수도 있습니다:

.button.primary {
  border: none;
}

위 코드는 class="button primary"와 같이 두 클래스를 모두 가진 요소만 선택합니다.

ID 선택자(ID Selector)

해시 기호(#)를 사용하여 특정 ID를 가진 요소를 선택합니다. ID는 페이지에서 고유해야 합니다.

#header {
  position: sticky;
  top: 0;
}

#main-content {
  margin-top: 20px;
}

속성 선택자(Attribute Selector)

대괄호([])를 사용하여 특정 속성을 가진 요소를 선택합니다.

[type] {
  /* type 속성을 가진 모든 요소 */
}

[type="text"] {
  /* type="text" 속성을 가진 요소 */
  padding: 5px 10px;
}

[data-theme="dark"] {
  /* 사용자 정의 데이터 속성 선택 */
  background-color: #333;
  color: white;
}

속성 값의 일부를 기준으로 선택할 수도 있습니다:

/* class 속성에 "btn"이 포함된 요소 */
[class*="btn"] {
  cursor: pointer;
}

/* href 속성이 ".pdf"로 끝나는 링크 */
[href$=".pdf"] {
  background-image: url('pdf-icon.png');
  padding-left: 20px;
}

/* href 속성이 "https"로 시작하는 링크 */
[href^="https"] {
  color: green;
}

결합자(Combinators)

결합자는 선택자 간의 관계를 정의하여 더 구체적인 요소를 선택할 수 있게 해줍니다.

자손 결합자(Descendant Combinator)

공백( )을 사용하여 특정 요소의 모든 자손(자식, 손자 등)을 선택합니다.

article p {
  /* article 내부의 모든 p 요소 */
  text-indent: 1em;
}

.container .item {
  /* .container 클래스 요소 내부의 모든 .item 클래스 요소 */
  margin: 10px;
}

자식 결합자(Child Combinator)

더 큰 기호(>)를 사용하여 특정 요소의 직접적인 자식만 선택합니다.

ul > li {
  /* ul의 직접적인 자식인 li만 선택 (중첩된 li는 선택되지 않음) */
  list-style-type: square;
}

.dropdown > .dropdown-menu {
  display: none;
}

인접 형제 결합자(Adjacent Sibling Combinator)

더하기 기호(+)를 사용하여 특정 요소 바로 다음에 오는 형제 요소를 선택합니다.

h2 + p {
  /* h2 바로 다음에 오는 p 요소 */
  font-weight: bold;
}

.field + .field {
  /* 연속된 .field 클래스 중 두 번째부터 선택 (간격 추가에 유용) */
  margin-top: 10px;
}

일반 형제 결합자(General Sibling Combinator)

물결 기호(~)를 사용하여 특정 요소 다음에 오는 모든 형제 요소를 선택합니다.

h2 ~ p {
  /* h2 다음에 오는 모든 p 요소 */
  color: #666;
}

.active ~ li {
  /* .active 클래스를 가진 요소 다음의 모든 li 요소 */
  color: #999;
}

의사 클래스(Pseudo-classes)

의사 클래스는 요소의 특정 상태나 위치를 기반으로 요소를 선택할 수 있게 해줍니다.

사용자 액션 의사 클래스

/* 마우스 호버 시 */
a:hover {
  text-decoration: underline;
}

/* 마우스 클릭 중(누르고 있는 상태) */
button:active {
  transform: translateY(1px);
}

/* 포커스 상태일 때 (탭 이동 등) */
input:focus {
  border-color: #3498db;
  outline: none;
}

/* 방문한 링크 */
a:visited {
  color: purple;
}

폼 요소 상태 의사 클래스

/* 체크된 상태의 체크박스/라디오 버튼 */
input:checked + label {
  color: #3498db;
}

/* 비활성화된 입력 필드 */
input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

/* 유효한/유효하지 않은 입력 값 */
input:valid {
  border-color: green;
}

input:invalid {
  border-color: red;
}

/* 선택적 입력 필드 */
input:optional {
  background-color: #f9f9f9;
}

/* 필수 입력 필드 */
input:required {
  border-left: 3px solid red;
}

구조적 의사 클래스

/* 첫 번째 자식 요소 */
li:first-child {
  font-weight: bold;
}

/* 마지막 자식 요소 */
li:last-child {
  border-bottom: none;
}

/* n번째 자식 요소 */
li:nth-child(3) {
  background-color: #f5f5f5;
}

/* 홀수번째 자식 요소 */
li:nth-child(odd) {
  background-color: #f9f9f9;
}

/* 짝수번째 자식 요소 */
li:nth-child(even) {
  background-color: #eee;
}

/* 특정 패턴의 자식 요소: 3n은 3, 6, 9, ... */
li:nth-child(3n) {
  color: red;
}

/* 특정 유형의 n번째 요소 */
p:nth-of-type(2) {
  font-style: italic;
}

/* 부모의 유일한 자식 */
li:only-child {
  list-style-type: none;
}

/* 해당 타입의 유일한 요소 */
p:only-of-type {
  font-weight: bold;
}

/* 빈 요소 */
div:empty {
  display: none;
}

기타 유용한 의사 클래스

/* 부정 선택자: 특정 선택자와 일치하지 않는 요소 */
:not(.special) {
  opacity: 0.8;
}

/* 현재 타겟된 요소 (URL의 #fragment와 일치) */
:target {
  animation: highlight 2s;
}

/* 루트 요소 (보통 html) */
:root {
  --primary-color: #3498db;
}

/* 현재 클릭/탭 가능한 요소 */
:focus-visible {
  outline: 2px dashed #3498db;
}

의사 요소(Pseudo-elements)

의사 요소는 실제 HTML에 존재하지 않는 "가상" 요소를 선택할 수 있게 해줍니다. 이중 콜론(::)으로 표시하지만, 하위 호환성을 위해 단일 콜론(:)도 허용됩니다.

기본 의사 요소

/* 요소의 첫 글자 */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
}

/* 요소의 첫 줄 */
p::first-line {
  font-variant: small-caps;
}

/* 요소의 선택된 텍스트 */
::selection {
  background-color: #ffeb3b;
  color: black;
}

/* 요소 내용 앞/뒤에 콘텐츠 추가 */
.quote::before {
  content: '"';
  font-size: 2em;
  color: #ccc;
}

.quote::after {
  content: '"';
  font-size: 2em;
  color: #ccc;
}

고급 의사 요소 활용

/* 아이콘 추가 */
.external-link::after {
  content: ' ↗';
  font-size: 0.8em;
}

/* 툴팁 생성 */
[data-tooltip]::after {
  content: attr(data-tooltip);
  display: none;
  position: absolute;
  background: black;
  color: white;
  padding: 5px;
  border-radius: 3px;
}

[data-tooltip]:hover::after {
  display: block;
}

/* 장식선 만들기 */
h2::before {
  content: '';
  display: block;
  width: 50px;
  height: 3px;
  background-color: #3498db;
  margin-bottom: 10px;
}

/* 플레이스홀더 스타일링 */
input::placeholder {
  color: #999;
  font-style: italic;
}

선택자 결합 및 고급 패턴

이제 앞서 배운 선택자들을 결합하여 더 강력하고 정확한 선택을 해봅시다.

여러 선택자 그룹화

쉼표(,)를 사용하여 여러 선택자에 동일한 스타일을 적용할 수 있습니다.

h1, h2, h3, h4, h5, h6 {
  font-family: 'Montserrat', sans-serif;
}

.btn-primary, .btn-secondary, .btn-tertiary {
  border-radius: 4px;
  padding: 10px 20px;
}

복합 선택자

여러 선택자 유형을 결합하여 매우 구체적인 요소를 타겟팅할 수 있습니다.

/* nav 내부의 .active 클래스를 가진 a 태그 */
nav a.active {
  font-weight: bold;
}

/* article 내부의 첫 번째 p 요소의 첫 글자 */
article p:first-child::first-letter {
  font-size: 2em;
}

/* form 내부의 disabled 상태가 아닌 모든 input */
form input:not([disabled]) {
  background-color: white;
}

/* 레이블이 있는 체크박스를 선택했을 때 레이블 스타일 변경 */
input[type="checkbox"]:checked + label {
  color: #3498db;
}

/* 특정 섹션 내의 홀수번째 목록 아이템만 선택 */
.features-list li:nth-child(odd) {
  background-color: #f9f9f9;
}

실용적인 선택자 패턴

실제 개발에서 유용하게 사용할 수 있는 선택자 패턴을 살펴봅시다.

/* 형제 요소 간 간격 추가 (마진 충돌 방지) */
.card + .card {
  margin-top: 20px;
}

/* 제목 다음에 오는 첫 단락만 특별 스타일링 */
h2 + p {
  font-size: 1.1em;
  font-weight: 500;
}

/* 특정 깊이의 요소만 선택 */
.menu > li > ul > li {
  /* 메뉴의 2단계 깊이 항목만 */
  font-size: 0.9em;
}

/* 부모 기준 선택자 */
.parent:hover > .child {
  /* 부모에 호버했을 때 자식 요소 스타일 변경 */
  visibility: visible;
}

선택자 우선순위 이해하기

CSS에서 여러 규칙이 동일한 요소에 적용될 때, 어떤 규칙이 우선하는지는 "명시도(Specificity)"에 따라 결정됩니다.

명시도 계산 방법

명시도는 다음과 같은 순서로 계산됩니다 (높은 것이 우선):

  1. 인라인 스타일 (style 속성)
  2. ID 선택자 (#id)
  3. 클래스 선택자 (.class), 속성 선택자 ([attr]), 의사 클래스 (:hover)
  4. 요소 선택자 (div), 의사 요소 (::before)

예를 들어:

#nav .list li:hover {
  /* 명시도: 1-2-1 (ID 1개, 클래스+의사클래스 2개, 요소 1개) */
}

body .wrapper .button {
  /* 명시도: 0-2-1 (ID 0개, 클래스 2개, 요소 1개) */
}

첫 번째 선택자가 ID를 포함하기 때문에 두 번째 선택자보다 우선합니다.

!important

모든 명시도 규칙을 무시하고 최우선 적용하는 방법입니다. 남용하면 유지보수가 어려워지므로 꼭 필요한 경우에만 사용해야 합니다.

.button {
  background-color: blue !important; /* 다른 모든 배경색 규칙 무시 */
}

최신 CSS 선택자

CSS의 최신 사양에서 도입된 몇 가지 강력한 선택자를 살펴봅시다.

:is() 및 :where() 의사 클래스

이 선택자들은 선택자 목록을 그룹화하여 코드를 간결하게 만들어 줍니다.

/* 기존 방식 */
header a:hover, 
main a:hover, 
footer a:hover {
  text-decoration: underline;
}

/* :is() 사용 */
:is(header, main, footer) a:hover {
  text-decoration: underline;
}

차이점은 :is()는 내부 선택자의 가장 높은 명시도를 가져오는 반면, :where()는 명시도가 0입니다.

:has() 관계 선택자

부모 선택자를 가능하게 하는 혁신적인 선택자입니다. "특정 요소를 포함하는 요소"를 선택할 수 있습니다.

/* 이미지를 포함하는 단락 */
p:has(img) {
  display: flex;
  align-items: center;
}

/* 체크된 라디오 버튼을 포함하는 라벨 */
label:has(input[type="radio"]:checked) {
  font-weight: bold;
}

/* 자식 요소가 없는 div (빈 컨테이너) */
div:not(:has(*)) {
  display: none;
}

:focus-visible 및 :focus-within

/* 키보드 포커스일 때만 스타일 적용 (마우스 클릭은 제외) */
button:focus-visible {
  outline: 2px dashed blue;
}

/* 내부 요소 중 하나가 포커스를 받으면 컨테이너 스타일 변경 */
form:focus-within {
  background-color: #f5f5f5;
}

실무 CSS 선택자 활용 팁

유지보수성 향상을 위한 팁

  1. 과도하게 구체적인 선택자 피하기
/* 지양할 것 */
body header nav ul li a.nav-link {}

/* 지향할 것 */
.nav-link {}
  1. BEM 방법론과 같은 명명 규칙 사용
.block {}
.block__element {}
.block--modifier {}
  1. 선택자 깊이 제한하기 최대 3단계 이하로 선택자 깊이를 유지하면 유지보수성이 향상됩니다.

성능 최적화 팁

  1. 선택자는 오른쪽에서 왼쪽으로 해석됨을 이해하기
/* 비효율적: 모든 div를 확인한 후 .container 클래스 확인 */
div.container {}

/* 효율적: .container 클래스를 먼저 찾고 div인지 확인 */
.container {}
  1. 전체 선택자(*) 사용 제한하기 특히 복잡한 선택자의 일부로 사용할 때 성능에 영향을 줄 수 있습니다.
  2. ID 선택자 활용하기 ID 선택자는 페이지에서 고유하므로 브라우저가 빠르게 요소를 찾을 수 있습니다.

마무리

CSS 선택자는 단순한 기술 이상의 예술입니다. 기본 선택자부터 시작하여 복잡한 선택자 조합까지 마스터하면, HTML 구조를 변경하지 않고도 원하는 요소에 정확하게 스타일을 적용할 수 있습니다. 이는 유지보수성이 높고 효율적인 CSS 코드를 작성하는 데 필수적입니다.

가장 중요한 것은 실전 경험입니다. 다양한 선택자를 실험해보고, 개발자 도구를 활용하여 선택자가 어떤 요소를 타겟팅하는지 확인해보세요. 점차 더 복잡한 레이아웃과 인터랙션을 구현할 수 있게 될 것입니다.

최신 CSS 선택자는 계속해서 발전하고 있으므로, 새로운 스펙과 브라우저 지원 상황을 주기적으로 확인하는 것도 잊지 마세요. 이제 여러분은 CSS 선택자의 강력함을 활용하여 웹 개발의 새로운 가능성을 탐색할 준비가 되었습니다!

저작자표시 비영리 변경금지 (새창열림)

'TypeScript > CSS' 카테고리의 다른 글

CSS 단위 완벽 이해하기: px vs. em vs. rem vs. vh/vw  (0) 2025.05.15
CSS 애니메이션 마스터하기: 자바스크립트 없이 인터랙티브한 웹 만들기  (0) 2025.05.13
반응형 웹 디자인: 모바일부터 데스크톱까지 완벽하게 대응하는 CSS 기법  (1) 2025.05.12
CSS 변수(Custom Properties)로 코드 유지보수 시간 절반으로 줄이기  (2) 2025.05.11
CSS Grid 완벽 가이드: 복잡한 레이아웃도 쉽게 만드는 방법  (0) 2025.05.10
    'TypeScript/CSS' 카테고리의 다른 글
    • CSS 단위 완벽 이해하기: px vs. em vs. rem vs. vh/vw
    • CSS 애니메이션 마스터하기: 자바스크립트 없이 인터랙티브한 웹 만들기
    • 반응형 웹 디자인: 모바일부터 데스크톱까지 완벽하게 대응하는 CSS 기법
    • CSS 변수(Custom Properties)로 코드 유지보수 시간 절반으로 줄이기
    코샵
    코샵
    나의 코딩 일기장

    티스토리툴바