본문으로 건너뛰기 CSS 기초 | 선택자, 속성, 색상, 폰트

CSS 기초 | 선택자, 속성, 색상, 폰트

CSS 기초 | 선택자, 속성, 색상, 폰트

이 글의 핵심

같은 요소에 여러 선언이 겹칠 때, 브라우저는 캐스케이드 규칙으로 ‘한 값’을 고릅니다. 특이도·상속·레이어를 알아야 예측이 됩니다.

시리즈 안내

#03 | 📋 전체 목차 | 이전: #02 HTML 기본


들어가며

CSS는 HTML이 만든 요소에 색·크기·배치 규칙을 입힙니다. 박스 모델Flexbox는 같은 “상자” 관점에서 읽으면 연결됩니다.

심화: 캐스케이드, 특이도(Specificity), 상속

아래에서 다루는 선택자 예제들이 같은 속성에 서로 다른 값을 주면, 브라우저는 캐스케이드(Cascade) 알고리즘으로 하나를 고릅니다. “ID가 클래스보다 강하다”는 말만으로는 부족하며, 출처(origin)·중요도(importance)·레이어(@layer)·특이도·선언 순서를 함께 봐야 합니다.

캐스케이드가 비교하는 단계(요약)

일반적으로 한 선언이 다른 선언을 이기려면, 아래 순서로 먼저 다른 쪽을 이겨야 합니다(같은 단계 안에서는 다음 단계로).

  1. 출처와 중요도
    사용자 !important → 작성자 !important → 작성자 일반 → 사용자 일반 → UA(브라우저 기본) 스타일시트.
    (실제 엔진은 명세의 cascade sort에 따라 더 세밀합니다.)

  2. 레이어(@layer)
    레이어가 없는 일반 선언은 레이어 안 선언보다 우선할 수 있습니다(명세의 레이어 순서 규칙). 디자인 시스템에서 베이스/컴포넌트/유틸을 레이어로 나누면 !important 없이도 순서를 제어하기 쉽습니다.

  3. 선택자 특이도(Specificity)
    동일 출처·중요도·레이어라면 특이도가 큰 선언이 이깁니다.

  4. 선언 순서
    그래도 동률이면 문서에서 뒤에 온 선언이 이깁니다(같은 스타일시트 내 import 순서와 링크 순서도 여기에 포함).

특이도 계산: 단순 “ID > 클래스”를 넘어서

CSS2 시절의 직관(ID=100, class=10, 요소=1)은 여전히 직관용으로 쓰이지만, 최신 선택자는 4개의 카운터로 이해하는 편이 정확합니다(Selectors Level 4 기준 개념).

  • 인라인 스타일(style="...")은 선택자 특이도보다 에 올라갑니다(별도로 처리).
  • :where()는 인자 선택자의 특이도를 0으로 만듭니다. 반면 :is(), :not(), :has()는 인자 안의 가장 특이도 높은 선택자를 반영합니다.
  • 가상 요소(::before, ::after)는 타입 선택자와 동급으로 1을 더합니다.
  • :nth-child() 등 구조 의사 클래스는 특이도에 포함됩니다.

복합 선택자 .a.b#c는 각 구성 요소의 특이도가 합산됩니다. 따라서 “클래스 하나만 더 추가했다”가 ID가 아닌 이상 ID 규칙을 이기지 못하는 이유가 수치로 설명됩니다.

실무에서 자주 쓰는 팁은 다음과 같습니다.

  • 특이도 전쟁을 피하려면 클래스·데이터 속성 하나로 범위를 잡으며, 불가피할 때만 @layer로 정리합니다.
  • !important 디버깅을 어렵게 만들고 레이어·순서 문제를 가립니다. 정말 필요한 경우(예: 유틸리티 오버라이드)만 제한적으로 씁니다.

상속(Inheritance)과 초기값

모든 CSS 속성은 상속 여부가 정해져 있습니다.

  • 상속되는 속성: color, font-*, line-height 등 — 자식은 부모의 계산값(computed value)을 상속받습니다(단, rem처럼 루트 기준인 값은 부모와 무관).
  • 상속되지 않는 속성: margin, padding, border, width 등 — 초기값(initial value)에서 시작합니다. 브라우저 기본 스타일(UA)이 일부 요소에 margin 등을 넣는 이유가 여기에 있습니다.

전역 리셋(* { margin: 0 })은 상속이 아니라 모든 요소에 직접 적용되는 것입니다.

inherit, initial, unset, revert

  • inherit: 부모의 계산값을 강제로 물려받습니다(상속 여부와 무관).
  • initial: 해당 속성의 표준 초기값으로 맞춥니다.
  • unset: 속성이 상속되면 inherit, 아니면 initial과 같이 동작합니다.
  • revert: 캐스케이드를 한 단계 되실행하여 UA/작성자 스타일 중 이전 층으로 돌아갑니다(레이어·출처 맥락이 있으므로 “완전 초기화”와는 다릅니다).

이 단계까지 이해하면, “같은 선택자인데 왜 이 속성만 이상한가?” 같은 문제가 상속·초기값·더 구체적인 규칙 중 어디에 속하는지로 분해됩니다. 레이아웃과 겹침은 박스 모델position·쌓임 맥락과 연결됩니다.

1. CSS 선택자

기본 선택자

CSS 선택자는 스타일을 적용할 HTML 요소를 선택합니다:

/* 1. 태그 선택자 (Type Selector) */
p {
    /* 모든 <p> 태그에 적용 */
    color: blue;
}
h1 {
    /* 모든 <h1> 태그에 적용 */
    font-size: 32px;
}
/* 2. 클래스 선택자 (Class Selector) */
.highlight {
    /* class="highlight"를 가진 모든 요소에 적용 */
    /* 여러 요소에 재사용 가능 */
    background-color: yellow;
}
.button {
    /* class="button"을 가진 요소 */
    padding: 10px 20px;
    border-radius: 5px;
}
/* HTML 예시:
   <p class="highlight">강조된 텍스트</p>
   <div class="highlight">강조된 영역</div>
*/
/* 3. ID 선택자 (ID Selector) */
#header {
    /* id="header"를 가진 요소에 적용 */
    /* 페이지에서 유일해야 함 (한 번만 사용) */
    font-size: 24px;
}
#main-content {
    /* id="main-content"인 요소 */
    max-width: 1200px;
}
/* HTML 예시:
   <div id="header">헤더</div>
*/
/* 4. 전체 선택자 (Universal Selector) */
* {
    /* 모든 요소에 적용 */
    /* CSS 리셋에 자주 사용 */
    margin: 0;      /* 모든 요소의 외부 여백 제거 */
    padding: 0;     /* 모든 요소의 내부 여백 제거 */
    box-sizing: border-box;  /* 박스 크기 계산 방식 통일 */
}

선택자 우선순위 (직관용 숫자): 아래 숫자는 교육용 비유이며, 실제 엔진은 위 「심화: 캐스케이드, 특이도, 상속」에서 설명한 대로 출처·레이어·:where() 등을 함께 봅니다.

/* (비유) ID > 클래스 > 태그 — 복합 선택자는 각 부분이 합산됨 */
p { color: black; }           /* 타입 1개 */
.text { color: blue; }        /* 클래스 1개 */
#title { color: red; }        /* ID 1개 */
/* <p id="title" class="text">텍스트</p> → 보통 #title 이김 */
/* !important는 같은 조건에서 특이도보다 앞선 “중요도” 축에서 판정됨 */
p { color: green !important; }

선택자 조합:

/* 여러 클래스 동시 적용 */
.button.primary {
    /* class="button primary"를 가진 요소 */
    background: blue;
}
/* 여러 선택자에 같은 스타일 */
h1, h2, h3 {
    /* h1, h2, h3 모두에 적용 */
    font-family: Arial;
}

복합 선택자

/* 자손 선택자 (모든 하위) */
div p {
    color: red;
}
/* 자식 선택자 (직접 하위만) */
div > p {
    color: blue;
}
/* 인접 형제 선택자 */
h1 + p {
    font-weight: bold;
}
/* 일반 형제 선택자 */
h1 ~ p {
    color: gray;
}

속성 선택자

/* 속성 존재 */
[type] {
    border: 1px solid;
}
/* 속성 값 일치 */
[type="text"] {
    background: white;
}
/* 속성 값 포함 */
[class*="btn"] {
    padding: 10px;
}
/* 속성 값 시작 */
[href^="https"] {
    color: green;
}
/* 속성 값 끝 */
[href$=".pdf"] {
    color: red;
}

가상 클래스

가상 클래스는 요소의 특정 상태를 선택합니다:

/* 1. 링크 상태 (LVHA 순서 권장) */
a:link {
    /* 방문하지 않은 링크 */
    color: blue;
}
a:visited {
    /* 방문한 링크 */
    color: purple;
}
a:hover {
    /* 마우스를 올렸을 때 */
    color: red;
    text-decoration: underline;
}
a:active {
    /* 클릭하는 순간 */
    color: orange;
}
/* 2. 구조 가상 클래스 */
li:first-child {
    /* 첫 번째 자식 요소 */
    font-weight: bold;
}
li:last-child {
    /* 마지막 자식 요소 */
    font-style: italic;
}
li:nth-child(2) {
    /* 두 번째 자식 요소 */
    color: red;
}
li:nth-child(odd) {
    /* 홀수 번째 자식 (1, 3, 5, ...) */
    background: #f0f0f0;
}
li:nth-child(even) {
    /* 짝수 번째 자식 (2, 4, 6, ...) */
    background: white;
}
/* nth-child 고급 사용 */
li:nth-child(3n) {
    /* 3의 배수 (3, 6, 9, ...) */
    color: blue;
}
li:nth-child(3n+1) {
    /* 3으로 나눈 나머지가 1 (1, 4, 7, ...) */
    color: green;
}
/* 3. 상태 가상 클래스 */
input:focus {
    /* 포커스를 받았을 때 (클릭 또는 Tab 키) */
    border-color: blue;
    outline: 2px solid blue;
}
input:disabled {
    /* 비활성화된 입력 필드 */
    opacity: 0.5;
    cursor: not-allowed;
}
input:checked + label {
    /* 체크된 input의 바로 다음 label */
    /* + : 인접 형제 선택자 */
    color: green;
    font-weight: bold;
}
/* HTML 예시:
   <input type="checkbox" id="agree">
   <label for="agree">동의합니다</label>
*/
/* 4. 기타 유용한 가상 클래스 */
button:hover {
    /* 마우스 오버 시 */
    background: #0056b3;
    cursor: pointer;
}
input:valid {
    /* 유효한 입력 */
    border-color: green;
}
input:invalid {
    /* 유효하지 않은 입력 */
    border-color: red;
}
div:empty {
    /* 내용이 비어있는 요소 */
    display: none;
}
:not(.active) {
    /* active 클래스가 없는 요소 */
    opacity: 0.5;
}

가상 클래스 실전 예시:

/* 테이블 줄무늬 */
tr:nth-child(odd) {
    background: #f9f9f9;
}
/* 첫 단락만 크게 */
article p:first-child {
    font-size: 1.2em;
}
/* 마지막 아이템 구분선 제거 */
li:last-child {
    border-bottom: none;
}

가상 요소

/* 첫 글자 */
p::first-letter {
    font-size: 2em;
    font-weight: bold;
}
/* 첫 줄 */
p::first-line {
    color: blue;
}
/* 앞에 내용 추가 */
.note::before {
    content: "📌 ";
}
/* 뒤에 내용 추가 */
.external-link::after {
    content: " 🔗";
}

2. 색상

색상 표현 방법

/* 색상 이름 */
color: red;
color: blue;
color: green;
/* HEX 코드 */
color: #FF0000;  /* 빨강 */
color: #00FF00;  /* 초록 */
color: #0000FF;  /* 파랑 */
color: #FFF;     /* 축약형 */
/* RGB */
color: rgb(255, 0, 0);
color: rgb(0, 255, 0);
color: rgb(0, 0, 255);
/* RGBA (투명도) */
color: rgba(255, 0, 0, 0.5);  /* 50% 투명 */
background: rgba(0, 0, 0, 0.8);
/* HSL */
color: hsl(0, 100%, 50%);    /* 빨강 */
color: hsl(120, 100%, 50%);  /* 초록 */
color: hsl(240, 100%, 50%);  /* 파랑 */
/* HSLA (투명도) */
color: hsla(0, 100%, 50%, 0.5);

색상 활용

.box {
    /* 글자 색 */
    color: #333;
    
    /* 배경색 */
    background-color: #f5f5f5;
    
    /* 테두리 색 */
    border-color: #ddd;
    
    /* 그라데이션 */
    background: linear-gradient(to right, #667eea, #764ba2);
    background: radial-gradient(circle, #667eea, #764ba2);
}

3. 폰트

폰트 기본

.text {
    /* 폰트 종류 */
    font-family: Arial, sans-serif;
    font-family: 'Malgun Gothic', '맑은 고딕', sans-serif;
    
    /* 폰트 크기 */
    font-size: 16px;
    font-size: 1.5em;
    font-size: 1.5rem;
    
    /* 폰트 굵기 */
    font-weight: normal;   /* 400 */
    font-weight: bold;     /* 700 */
    font-weight: 600;
    
    /* 폰트 스타일 */
    font-style: normal;
    font-style: italic;
    
    /* 줄 높이 */
    line-height: 1.6;
    line-height: 24px;
}

웹 폰트

/* Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap');
body {
    font-family: 'Noto Sans KR', sans-serif;
}
/* 로컬 폰트 */
@font-face {
    font-family: 'MyFont';
    src: url('fonts/myfont.woff2') format('woff2'),
         url('fonts/myfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}
.custom {
    font-family: 'MyFont', sans-serif;
}

4. 텍스트 스타일

텍스트 정렬

.text {
    /* 수평 정렬 */
    text-align: left;
    text-align: center;
    text-align: right;
    text-align: justify;
    
    /* 수직 정렬 (인라인 요소) */
    vertical-align: top;
    vertical-align: middle;
    vertical-align: bottom;
}

텍스트 장식

.text {
    /* 밑줄 */
    text-decoration: underline;
    text-decoration: none;
    text-decoration: line-through;
    
    /* 대소문자 변환 */
    text-transform: uppercase;  /* 대문자 */
    text-transform: lowercase;  /* 소문자 */
    text-transform: capitalize; /* 첫 글자만 대문자 */
    
    /* 들여쓰기 */
    text-indent: 20px;
    
    /* 자간 */
    letter-spacing: 2px;
    
    /* 단어 간격 */
    word-spacing: 5px;
    
    /* 그림자 */
    text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}

텍스트 오버플로우

.text {
    /* 한 줄 말줄임 */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    
    /* 여러 줄 말줄임 (Webkit) */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

5. 단위

절대 단위

// 실행 예제
.element {
    width: 100px;   /* 픽셀 */
    width: 2.54cm;  /* 센티미터 */
    width: 25.4mm;  /* 밀리미터 */
    width: 72pt;    /* 포인트 */
}

상대 단위

.element {
    /* em: 부모 요소 기준 */
    font-size: 1.5em;
    
    /* rem: 루트 요소 기준 */
    font-size: 1.5rem;
    
    /* %: 부모 요소 기준 */
    width: 50%;
    
    /* vw/vh: 뷰포트 기준 */
    width: 50vw;   /* 뷰포트 너비의 50% */
    height: 100vh; /* 뷰포트 높이의 100% */
    
    /* vmin/vmax */
    width: 50vmin;  /* 뷰포트 작은 쪽 기준 */
    width: 50vmax;  /* 뷰포트 큰 쪽 기준 */
}

6. CSS 변수

변수 정의와 사용

:root {
    /* 변수 정의 */
    --primary-color: #3498db;
    --secondary-color: #2ecc71;
    --font-size-base: 16px;
    --spacing-unit: 8px;
}
.button {
    /* 변수 사용 */
    background-color: var(--primary-color);
    font-size: var(--font-size-base);
    padding: calc(var(--spacing-unit) * 2);
}
.button:hover {
    background-color: var(--secondary-color);
}
/* 기본값 지정 */
.element {
    color: var(--text-color, #333);
}

7. 실전 예제

예제: 버튼 스타일

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>버튼 스타일</title>
    <style>
        :root {
            --primary: #3498db;
            --success: #2ecc71;
            --danger: #e74c3c;
            --warning: #f39c12;
        }
        .btn {
            display: inline-block;
            padding: 12px 24px;
            font-size: 16px;
            font-weight: 600;
            text-decoration: none;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s;
        }
        .btn-primary {
            background-color: var(--primary);
            color: white;
        }
        .btn-primary:hover {
            background-color: #2980b9;
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }
        .btn-success {
            background-color: var(--success);
            color: white;
        }
        .btn-danger {
            background-color: var(--danger);
            color: white;
        }
        .btn-outline {
            background-color: transparent;
            color: var(--primary);
            border: 2px solid var(--primary);
        }
        .btn-outline:hover {
            background-color: var(--primary);
            color: white;
        }
    </style>
</head>
<body>
    <button class="btn btn-primary">Primary</button>
    <button class="btn btn-success">Success</button>
    <button class="btn btn-danger">Danger</button>
    <button class="btn btn-outline">Outline</button>
</body>
</html>

정리

핵심 요약

  1. 선택자: 태그, 클래스, ID, 가상 클래스
  2. 색상: HEX, RGB, RGBA, HSL
  3. 폰트: font-family, font-size, font-weight
  4. 텍스트: text-align, text-decoration
  5. 단위: px, em, rem, %, vw, vh
  6. 변수: —변수명, var(—변수명)

다음 단계


관련 글


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. 선택자·캐스케이드·특이도 계산·상속까지. 출처·중요도·레이어·상속/초기값을 포함해 스타일이 최종적으로 어떻게 확정되는지 고급 관점에서 정리합니다. 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

CSS, 스타일, 선택자, 디자인, 캐스케이드 등으로 검색하시면 이 글이 도움이 됩니다.