지난 다크모드 글을 다시 보면, 배경색과 글자색을 body와 .dark-mode에 각각 따로 적었습니다. 만약 색상을 하나 바꾸고 싶다면, 코드 여기저기를 찾아다니며 일일이 고쳐야 합니다. 이런 반복을 줄여주는 것이 바로 CSS 변수입니다.
[CSS 변수란?]
자주 쓰는 값(색상, 여백 크기 등)에 이름을 붙여두고, 필요할 때마다 그 이름을 불러와 쓰는 기능입니다. 값을 한 곳에서만 바꾸면 그 변수를 사용한 모든 곳에 자동으로 반영됩니다.
:root {
--main-color: #1a73e8;
}
h1 {
color: var(--main-color);
}
a {
color: var(--main-color);
}
:root는 문서 전체를 가리키는 최상위 선택자입니다. 여기에 변수를 선언해두면 페이지 어디서든 var(--변수이름)으로 불러다 쓸 수 있습니다. 변수 이름 앞에는 반드시 대시 두 개(--)를 붙여야 합니다.
[실전: 다크모드를 CSS 변수로 다시 만들기]
지난번 다크모드 코드를 CSS 변수로 바꾸면 이렇게 정리됩니다.
:root {
--bg-color: #ffffff;
--text-color: #1a1a1a;
--link-color: #1a73e8;
}
.dark-mode {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
--link-color: #8ab4f8;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
a {
color: var(--link-color);
}
이전 방식과 비교해보면 차이가 명확합니다.
- 이전 방식:
body와.dark-mode각각에 배경색·글자색을 따로 적었습니다. - 변수 방식:
body,a등 실제 스타일 규칙은 한 번만 작성하고,.dark-mode에서는 변수 값만 재정의합니다.
요소가 늘어날수록(제목, 버튼, 테두리 등) 이 차이는 훨씬 크게 벌어집니다. 색상을 쓰는 곳이 10군데면, 기존 방식은 다크모드용 스타일을 10번 따로 적어야 하지만 변수 방식은 :root와 .dark-mode 딱 두 곳만 관리하면 됩니다.
[덤: 부드러운 전환 효과]
위 코드에 있는 transition: background-color 0.3s, color 0.3s;는 색상이 갑자기 뚝 바뀌지 않고, 0.3초에 걸쳐 부드럽게 바뀌도록 해줍니다. 다크모드 버튼을 눌렀을 때 화면이 스르륵 전환되는 효과를 원한다면 이 한 줄이면 충분합니다.
[변수를 쓰면 좋은 다른 경우]
색상뿐 아니라 반복해서 쓰는 여백, 글자 크기, 테두리 두께 등에도 활용할 수 있습니다.
:root {
--content-padding: 20px;
--border-radius: 8px;
}
.box {
padding: var(--content-padding);
border-radius: var(--border-radius);
}
블로그 레이아웃을 통일감 있게 유지하고 싶을 때, 이런 값들을 변수로 미리 정해두면 나중에 디자인을 바꿀 때 훨씬 편해집니다.
[초보자가 자주 하는 실수 2가지]
- 변수 이름 앞의 대시(--)를 하나만 쓰는 경우:
-main-color처럼 대시 하나만 쓰면 변수로 인식되지 않습니다. 반드시 두 개(--main-color)여야 합니다. - var() 없이 변수를 바로 쓰는 경우:
color: --main-color;처럼var()로 감싸지 않으면 작동하지 않습니다. 반드시color: var(--main-color);형태로 써야 합니다.
핵심 요약
- CSS 변수는
:root { --이름: 값; }으로 선언하고,var(--이름)으로 불러옵니다. - 다크모드처럼 상태에 따라 값이 바뀌는 경우, 클래스 안에서 변수 값만 재정의하면 코드가 훨씬 간결해집니다.
transition을 함께 쓰면 색상 전환이 부드러워집니다.- 색상뿐 아니라 여백, 테두리 두께 등 반복되는 값 전반에 활용할 수 있습니다.
지난 두 편에서 만든 다크모드 코드가 있으시다면, 이번 기회에 CSS 변수 방식으로 한번 바꿔보시는 것도 좋은 연습이 될 것 같습니다.
