레슨 10 / 13·4개 토픽
CSS 변수와 특이도
CSS 커스텀 속성 (변수)
CSS 커스텀 속성(Custom Properties)은 --로 시작하는 사용자 정의 변수입니다. var() 함수로 값을 참조하며, 테마 색상, 간격, 폰트 크기 등을 일관되게 관리할 수 있습니다. JavaScript로도 읽고 쓸 수 있어 동적 테마 전환에 매우 유용합니다.
css
/* ── 커스텀 속성 선언과 사용 ── */
:root {
/* 색상 팔레트 */
--color-primary: #10b981;
--color-primary-dark: #059669;
--color-bg: #ffffff;
--color-text: #111827;
/* 간격 */
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 32px;
/* 폰트 */
--font-size-base: 16px;
--font-size-lg: 20px;
--border-radius: 8px;
}
/* 변수 사용 */
.button {
background: var(--color-primary);
color: var(--color-bg);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
font-size: var(--font-size-base);
}
.button:hover {
background: var(--color-primary-dark);
}다크 테마 구현
커스텀 속성의 가장 큰 장점은 테마 전환입니다. :root에 기본 테마 값을 정의하고, 다크 모드 클래스나 미디어 쿼리에서 값을 덮어쓰면 전체 사이트의 색상이 한꺼번에 바뀝니다.
css
/* 라이트 테마 (기본) */
:root {
--color-bg: #ffffff;
--color-surface: #f9fafb;
--color-text: #111827;
--color-text-muted: #6b7280;
--color-border: #e5e7eb;
}
/* 다크 테마 — 클래스로 전환 */
.dark {
--color-bg: #111827;
--color-surface: #1f2937;
--color-text: #f9fafb;
--color-text-muted: #9ca3af;
--color-border: #374151;
}
/* 또는 시스템 설정을 따르기 */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #111827;
--color-surface: #1f2937;
--color-text: #f9fafb;
--color-text-muted: #9ca3af;
--color-border: #374151;
}
}
/* 모든 컴포넌트에서 변수만 사용 */
body {
background: var(--color-bg);
color: var(--color-text);
}
.card {
background: var(--color-surface);
border: 1px solid var(--color-border);
}javascript
// JavaScript로 CSS 변수 읽기/쓰기
const root = document.documentElement;
// 읽기
const primary = getComputedStyle(root)
.getPropertyValue('--color-primary');
// 쓰기 — 실시간으로 테마 색상 변경
root.style.setProperty('--color-primary', '#3b82f6');
// 다크 모드 토글
document.body.classList.toggle('dark');CSS 특이도 (Specificity)
여러 CSS 규칙이 같은 요소에 적용될 때, 브라우저는 특이도(Specificity) 점수로 우선순위를 결정합니다. 특이도는 4자리 숫자 (인라인, ID, 클래스, 요소) 형태로 계산됩니다. 점수가 같으면 나중에 선언된 규칙이 적용됩니다.
- •인라인 스타일 (
style="...") →1,0,0,0— 가장 높음 - •ID 선택자 (
#header) →0,1,0,0 - •클래스/속성/가상클래스 (
.btn,[type],:hover) →0,0,1,0 - •요소/가상요소 (
div,p,::before) →0,0,0,1 - •전체 선택자 (
*) →0,0,0,0— 특이도 없음
css
/* ── 특이도 점수 비교 예시 ── */
/* 0,0,0,1 — 요소 선택자 */
p { color: black; }
/* 0,0,1,0 — 클래스 선택자 (위의 p보다 우선) */
.highlight { color: blue; }
/* 0,0,1,1 — 요소 + 클래스 */
p.highlight { color: green; }
/* 0,1,0,0 — ID 선택자 (클래스보다 우선) */
#main-text { color: red; }
/* 0,1,1,1 — ID + 클래스 + 요소 */
#main-text p.highlight { color: purple; }
/* ── 같은 특이도일 때: 나중에 선언된 것이 이김 ── */
.box { color: blue; }
.box { color: red; } /* ← 이것이 적용됨 */캐스케이드와 상속
CSS의 "C"는 Cascading(계단식)을 뜻합니다. 브라우저는 다음 순서로 스타일 우선순위를 결정합니다: ① !important ② 인라인 스타일 ③ 특이도 점수 ④ 소스 순서. 상속(Inheritance)은 부모 요소의 일부 속성이 자식에게 전달되는 것으로, color와 font-* 계열은 상속되지만 margin, padding, border는 상속되지 않습니다.
css
/* !important는 특이도를 무시하고 최우선 적용 */
.button {
color: blue !important; /* 어떤 규칙보다 우선 */
}
#nav .button {
color: red; /* 특이도가 더 높지만, !important에 밀림 */
}
/* ⚠️ !important 남용 금지 — 디버깅이 매우 어려워집니다 */
/* 상속 제어 키워드 */
.child {
color: inherit; /* 부모 값 상속 */
margin: initial; /* 브라우저 기본값으로 리셋 */
padding: unset; /* 상속 가능하면 inherit, 아니면 initial */
}💡
!important는 최후의 수단으로만 사용하세요. 특이도 문제를 근본적으로 해결하려면 선택자를 단순하게 유지하는 것이 좋습니다. BEM(.block__element--modifier) 같은 네이밍 컨벤션을 사용하면 클래스 기반으로 일관된 특이도를 유지할 수 있습니다.