CSS와 JS 사이에 변수 공유하기
프론트엔드 개발을 하다 보면 각종 스타일 변수(대표적으로 컬러와 여백값)를 JS 코드에서 끌어다 써야 할 때가 있다. 생각나는 방법으로는 세가지 정도가 있다.
styled-component
등 CSS-in-JS 라이브러리를 사용하는 경우: JS 코드로 정의하기- CSS 커스텀 프로퍼티로 정의해 두고 DOM API를 사용해 접근하기
css-modules
사용하는 경우::export
사용하여 스타일 파일에서 변수 내보내기
각각의 방법을 하나씩 살펴보자!
JS 코드에 객체 등으로 정리
스타일과 스크립트 코드가 섞이는 것에 그닥 불만이 없다면 적극 활용을 권장하고 싶다. 나는 그 둘 사이의 명확한 구분이 꼭 필요하다고 생각하는 타입이 아니고, 객체로 상수값 정리하는 것을 좋아해서 예전에 네이버 스마트 플레이스 모바일 버전 개발할 때 이 방법을 택했다. 정말 간단하게 예를 들자면 아래와 같다.
// styleVars.js
const COLORS = {
white: '#fff',
black: '#000',
...
}
export default {
COLORS,
...
}
// Button.jsx
import { COLORS } from 'src/styleVars'
const Button = () => {
return (
<button type="button"
style={{ backgroundColor: COLORS.white }}>
Simple Button</button>)
}
CSS 커스텀 프로퍼티로 정의한 후 DOM API로 접근하기
부끄럽지만 CSS 커스텀 프로퍼티는 아직 실무에서 써 본 적이 없다. 이거 잘 정의하면 나중에 Theme 설정할 때 컬러 팔레트를 통째로 손쉽게 바꿀 수 있을 것 같다. 커스텀 프로퍼티는 스코프를 정할 수 있다. 보통 전역으로 두고 사용하기 때문에 :root
선택자를 사용한다.
:root {
--my-theme-color: rebeccapurple;
}
getComputedStyle(document.documentElement).getPropertyValue('--my-theme-color')
// 혹은
document.documentElement.style.getPropertyValue("--my-theme-color'");
커스텀 프로퍼티는 CSS Houdini와 연관지어 생각할 수 있다. 브라우저 실험 기간이 끝나고 본격적으로 벤더들이 지원하기 시작하면 다양한 활용법이 나오리라 기대한다. 나중에 Houdini도 한번 공부해 봐야겠다.
그러나 이 방법은 JS 코드가 이쁘게 나오지 않아서 안 땡긴다. (넘 길어! 😔 타이핑 하다가 시간 다 보낼 것 같다.)
css-modules
사용하는 경우: :export
사용하여 스타일 파일에서 변수 내보내기
이 방법은 모르고 있었는데, 이번에 Woven Planet에서 작업하게 된 UI 라이브러리에 이미 적용이 되어 새로 알게 되었다. 커스텀 프로퍼티 가져다 쓰는 것보다 코드도 깔끔하고 1번 방법 느낌도 나기 때문에 CSS와 JS의 철저한 분리를 지향하면서 코드도 깔끔했으면 하는 사람들에게 추천한다.
:export {
someVar: $some-var;
thisIsAlsoSomeVar: $this-is-also-some-var;
...
}
import { someVar, thisIsAlsoSomeVar } from 'styles/exports'
⚠️ 주의할 점은, :export
를 한 파일에 몰아서 해야 한다는 것이다. 그렇지 않고 스타일 파일 여기저기서 :export
한다면, 그 파일을 다른 스타일 파일에서 사용할 때마다 매번 :export
되기 때문에 스타일 코드량이 불어나게 된다.
예를 들어, colors.scss
, font.scss
두 파일이 있는데, 각각의 파일마다 변수를 내보내고 있다고 하자.
// colors.scss
$white: '#fff';
:export {
white: $white;
}
// font.scss
$font-size: 48px;
:export {
fontSize: 48px;
}
그러면 만약 Button.scss
에서 이 두 파일을 불러와서 사용한다면,
@use 'colors';
@use 'font';
.button {
...
}
브라우저 개발자 도구에서 보는 경우, 코드가 아래처럼 나온다.
// 이거는 여기서 필요 없는데!
:export {
white: '#fff';
fontSize: '48px';
}
.button {
...
}
export.scss
같은 변수 내보내기 전용 파일을 하나 만들고 그것만 JS에서 가져다 사용하는 것이 좋다.
// exports.scss
@use 'colors';
@use 'font';
:export {
white: $colors.white;
fontSize: $font.font-size;
}