ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CSS와 JS 사이에 변수 공유하기
    DEV/CSS 2021. 5. 3. 15:21

    프론트엔드 개발을 하다 보면 각종 스타일 변수(대표적으로 컬러와 여백값)를 JS 코드에서 끌어다 써야 할 때가 있다. 생각나는 방법으로는 세가지 정도가 있다.

    1. styled-component 등 CSS-in-JS 라이브러리를 사용하는 경우: JS 코드로 정의하기
    2. CSS 커스텀 프로퍼티로 정의해 두고 DOM API를 사용해 접근하기
    3. 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;
    }

    참고

Designed by Tistory.