2 min to read
CSS 변수에 대한 짧은 글
사실 알고보면 당연한건데, 직접 사용하기 전에는 느끼기 힘들었던 것에 대한 짧은 글
들어가며 - CSS 변수의 유용함
웹 프론트엔드 개발에서는 뷰를 특정한 형태로 보여주는 스타일링을 위해 CSS를 사용합니다. CSS에는 퍼블리싱에서 유용하게 쓸 수 있는 여러 기능들이 있지만, 이 글에서는 반복적으로 쓰이는 값들에 이름을 붙일 수 있는 ‘CSS 변수’에 대하여 이야기해보려 합니다.
사실 CSS 변수라는 개념 자체는 오래전부터 알고 있었지만, 저에게는 전역 테마 토큰 정도로만 인식되어 있었습니다. 그러던 중, 마크다운을 렌더링하는 페이지에서 ToC(목차)를 구현하다가 “이건 전역이 아니라 컴포넌트 스코프에서도 충분히 쓰일 수 있겠는데?”라는 순간을 맞이하게 되었고, 그 경험을 짧게 정리해보고자 합니다.
나의 고정관념 - CSS 변수는 전역만 가능하다
대부분 css 변수를 사용할 때에는, 여러 페이지에서 통틀어 사용되는 브랜드 컬러나, 색상 팔레트 등을 사용하고, tailwind css도 전역적으로 적용되기 때문에, 그러하다라고 생각이 들었습니다만, 마크다운을 렌더 하는 페이지의 ToC(목차)를 구현하기 위해서 퍼블리싱을 하다가, 아래의 jsx 마크업이 실제로 유효하다는 것을 알고 깜짝 놀라게 되었습니다.
import tocStyles from 'some-style.module.css'
<span
className={cn(
tocStyles.tocItem,
tocStyles[`tocItemLevel${item.level}`],
'pl-[calc((var(--toc-level)-1)*10px)]',
)}
style={{ '--toc-level': item.level } as React.CSSProperties}>
--toc-level이라는 변수를 해당 컴포넌트에서만 사용할 수 있게 하고, padding-left 속성을 올바르게 계산해 내는것이 놀라웠습니다.
React에서는 CSS 변수 또한 결국 style 속성을 통해 DOM에 직접 주입할 수 있습니다. 즉, 해당 노드에만 유효한 스코프의 변수를 정의할 수 있다는 의미입니다. 이 값은 해당 요소 및 그 하위 트리에서만 참조되며, 전역에 영향을 주지 않습니다.
또한 CSS 변수는 기본적으로 상속(inheritance)됩니다. 예를 들어 상위 요소에 --x: 10px;를 정의하면, 하위 요소에서는 별도의 정의 없이 var(--x)를 그대로 사용할 수 있습니다. 이 특성 덕분에 전역 토큰, 레이아웃 단위 토큰, 컴포넌트 단위 토큰을 계층적으로 구성하는 것도 가능합니다.
CSS 변수가 ‘변’수인 이유 - 변경 가능하다
CSS 변수도, 결국 CSS 속성입니다. 따라서 다른 CSS 요소처럼 다음과 같은 것이 문제 없이 동작합니다.
// 전역 :root에 선언된 변수 변경
document.documentElement.style.setProperty("--color-primary", "#3b82f6");
// 특정 요소에만 적용
const el = document.querySelector(".card");
el?.style.setProperty("--card-bg", "black");
하지만 scss 변수 같은 경우에는 preprocessor나 postCSS와 같은 css 후처리기 등으로 처리되기 때문에, 직접적인 변수 변경이 불가합니다.
마치며
CSS 변수는 단순히 값을 치환하는 도구가 아니라, DOM 트리 위에서 동작하는 ‘런타임 디자인 토큰’에 가깝다는 사실을 다시 한 번 체감하게 되었습니다. 전역 테마를 위한 도구로만 생각하기에는, 컴포넌트 단위에서 동적으로 계산되는 레이아웃이나 표현을 다루기에도 충분히 강력합니다.
당연한 지식처럼 보일 수 있지만, 직접 사용해보기 전까지는 체감하기 어려웠던 부분이었습니다. 앞으로도 개발을 하다가 깨닫는 작은 지식이 생기면 또 정리해보려 합니다. 끝까지 읽어주셔서 감사합니다.