Logo

CSS 변수 (CSS 사용자 속성)

CSS 변수는 예전에는 Sass나, LESS, Stylus와 같은 CSS 전처리기(CSS preprocessor)를 통해서 접할 수 있었던 기능이었습니다. 하지만 최근에는 CSS 스펙 자체에 CSS 변수 개념이 추가되어 이제 CSS 전처리기 없이도 부담없이 CSS 변수를 사용할 수 있게 되었습니다. 이번 포스팅에서는 CSS 사용자 속성(CSS custom properties)라고도 알려진 CSS 변수(CSS variables)에 대해서 알아보겠습니다.

CSS 변수 정의

CSS 변수가 CSS 사용자 속성이라고 불리는 이유는 CSS 일반 속성과 동일한 문법으로 정의가 가능하기 때문입니다. 기존의 CSS 일반 속성과 눈에 뛰는 차이점이라면 CSS 사용자 속성은 이름이 --로 시작해야 한다는 것입니다.

예를 들어, 아래 --color 속성은 우리가 새롭게 정의한 속성이며, CSS에 기존에 내장되어 있는 color 속성과는 다른 속성입니다.

.ex {
  --color: red;
  color: blue;
}

글자색을 지정해주는 color 속성과 달리 --color 속성은 그 존재만으로는 아무런 스타일 효과를 내지 못합니다.

CSS 변수 접근

CSS 변수가 스타일하는데 사용되려면 읽어서 일반 CSS 속성에 설정을 해줘야 합니다. CSS 변수값을 읽으려면 var() 함수를 사용합니다.

예를 들어, 다음과 같이 --gray 속성에 저장된 CSS 변수값을 읽어서 background 속성에 할당할 수 있습니다.

.ex {
  --gray: #ccc;
  background: var(--gray);
}

CSS 변수 기본값

var() 함수는 두번째 인자로 기본값을 받는데요. CSS 변수에 접근할 때 해당 CSS 변수가 이미 정의되어 있는지 확실치 않는 경우에 활용할 수 있습니다.

.ex {
  color: var(--color, black);
}

위 스타일 정의는 --color 변수가 정의가 되어 있는 경우에는 그 변수값이 color 속성으로 사용되고, 그렇지 않는 경우에는 black이 대신 color 속성값으로 지정됩니다.

CSS 변수 상속

CSS 변수는 상위 엘리먼트에서 하위 엘리먼트로 상속이 됩니다. 다시 말해, 상위 엘리먼트에서 정의된 CSS 변수는 하위 엘리먼트에서 자유롭게 접근할 수 있습니다.

<form>
  <button class="light">밝음</button>
  <button class="dark">어둠</button>
</form>
form {
  --light: #ccc;
  --dark: #111;
}

button.light {
  color: var(--dark);
  background: var(--light);
}

button.dark {
  color: var(--light);
  background: var(--dark);
}

CSS 전역 변수

CSS 변수는 웹사이트에 일관적으로 스타일하기 위해서 많이 사용됩니다. 대표적인 사례로, 웹사이트에서 사용 가능한 모든 색상을 CSS 전역 변수로 정의해놓고, 웹사이트에서 사용되는 색상을 제약하는 경우를 들 수 있습니다.

CSS 변수를 최상위 엘리먼트에 정의해놓으면 마치 전역 변수처럼 DOM 트리 내에서 어디에서든지 CSS 변수에 접근할 수 있습니다. 보통 :root, html, body 선택자를 이용해서 CSS 전역 변수를 정의합니다.

:root {
  --color-success: #23d160;
  --color-error: #f14668;
}

이렇게 정의한 CSS 변수는 해당 웹사이트의 어떤 엘리먼트에서든지 var() 함수로 접근하여 스타일할 때 사용할 수 있습니다.

<button class="success">성공</button> <button class="error">오류</button>
button.success {
  background: var(--color-success);
}

button.error {
  background: var(--color-error);
}

주의 사항

CSS 변수를 사용할 때 범하기 쉬운 실수는 하위 엘리먼트에서 설정한 CSS 변수값을 상위 엘리먼트를 스타일할 때 읽어오려는 것입니다.

다음 예제를 보면, <li> 엘리먼트에서 --color CSS 변수값을 color 속성값으로 지정하려고 하고 있는데요. --color CSS 변수는 <li> 엘리먼트의 자식인 <a> 엘리먼트에서 클래스에 따라 다른 값으로 설정됩니다.

<ul>
  <li>
    <a href="#" class="success">성공</a>
  </li>
  <li>
    <a href="#" class="error">오류</a>
  </li>
</ul>
li {
  color: var(--color, blue);
}

a.success {
  --color: green;
}

a.error {
  --color: red;
}

아쉽게도 두 개의 <li> 엘리먼트에는 의도했던 글자색이 적용이 되지 않는 것을 확인할 수 있습니다.

원인은 CSS 변수는 상위 엘리먼트에서 하위 엘리먼트로 방향으로만 상속이 되고 그 반대 방향으로 상속이 되지 않기 때문입니다. 부모인 <li> 엘리먼트를 스타일할 때 자식인 <a> 엘리먼트에서 정의한 CSS 변수값을 읽어올 수는 없습니다.

이러한 문제는 해당 CSS 변수에 정의를 부모 엘리먼트로 올리면 어렵지 않게 해결할 수 있습니다.

<ul>
  <li class="success">
    <a href="#">성공</a>
  </li>
  <li class="error">
    <a href="#">오류</a>
  </li>
</ul>
li {
  color: var(--color, blue);
}

li.success {
  --color: green;
}

li.error {
  --color: red;
}

마치면서

이상으로 CSS 변수를 사용하는 기본적인 방법에 대해서 알아보았습니다. 무궁무진한 가능성이 있는 CSS 변수를 잘 활용하셔서 좀 더 효과적으로 스타일을 하실 수 있으셨으면 좋겠습니다.