728x90

CSS-in-JS가 무엇인지 모를때부터, 부트캠프를 통해 styled-components를 사용했었다. 배민에서는 어떻게 사용하는지도 궁금해서 개인적으로 흥미있는 장이었다!

 

 

CSS-in-JS

CSS-in-JS와 인라인 스타일의 차이점

 

CSS-in-JS는 CSS-in-CSS보다 더 강력한 추상화 수준을 제공한다. CS-in-JS를 활용하면 자바스크립트로 스타일을 선언적이고 유지보수 할 수 있게 표현할 수 있다.

흔히 인라인 스타일과 헤깔릴 수 있는데 두 방식의 차이점은 아래와 같다.

import React from 'react';
import styled from 'styled-components';

const textStyles = {
  color: 'white',
};
const CssInJs = () => {
  return (
    <div>
      <div style={textStyles}>예시2</div>
      <StyledComponentsEx>CSS-in-JS</StyledComponentsEx>
    </div>
  );
};

export default CssInJs;

const StyledComponentsEx = styled.div`
  color: white;
  background-color: black;
`;
<div style={{ color: 'white' }}>인라인2</div>

<style>
	.hash136s21 {
    	color:white;
    }
</style>
<div class='hash123s21'>CSS-in-JS</div>

 

인라인 스타일은 DOM노드에 속성으로 스타일을 추가한 반면에 CSS-in-JS는 DOM 상단에 style태그를 추가했다.

 

 

CSS-in-JS의 몇 가지 장점은 아래와 같다.

  1. 컴포넌트로 생각할 수 있다 : CSS-in-JS는 스타일을 컴포넌트 단위로 추상화하여 생각할 수 있게 해준다.
  2. 부모와 분리할 수 있다 : CSS에는 명시적으로 정의하지 않은 경우 부모 요소에서 자동으로 상속되는 속성이 있다.
  3. 스코프를 가진다 : CSS는 하나의 전역 네임스페이스를 가지기기 때문에 선택자 충돌을 피하기 어렵다. 이를 방지할 수 있음
  4. 자동으로 벤더 프리픽스가 붙는다 : 브라우저 호환성을 향상해줌
  5. 자바스크립트와 CSS사이에 상수와 함수를 쉽게 공유할 수 있다.

 

CSS-in-JS의 등장 배경

스타일링 라이브러리는 크게 두 가지로 나눌 수 있다.

CSS Preprocessor
sass/scss
less
stylus
CSS in JS
styled-components
emotion

 

웹 애플리케이션의 UI를 구성하는 데에도 CSS를사용하고 웹 개발에 컴포넌트/모듈 방식이 적용됨에 따라 CSS Modules를 시작으로 자바스크립트에서 CSS를 생성하는 방식이 도입되고 있다.

 

 크시르토퍼 쉬도가  CSS의 7가지 문제점을 제기했다 그리고 그에 대한 해결책으로 CSS-in-JS를 개념을 제시했다

  1. 글로벌 네임스페이스 : 모든 스타일이 전역 공간을 공유하므로 중복되지 않는 CSS 클래스 이름을 고민해야함
  2. 의존성 : CSS의 의존성과 자바스크립트의 의존성이 달라서 사용하지 않는 스타일이 포함되거나 꼭 필요한 스타일이 누락되는 문제가 생긴다.
  3. 불필요 코드 제거 : 기능 추가 수정 삭제 과정에서 불필요한 CSS를 삭제하기 힘들다.
  4. 최소화 : 클래스 이름을 최소화하기 힘들다.
  5. 상수 고융 : 자바스크립트와 상태 값을 공유할 수 없다. (현재는 CSS Variable이 도입됨)
  6. 비결정적 해결 : CSS 로드 순서에 따라 스타일 우선순위가 달라진다.
  7. 고립 : CSS의 외부 수정 관리하기 어렵다(캡슐화)

물론 CSS-in-JS를 적용하기 위해서는 별도의 라이브러리를 설치해야하고, 런타임에 스타일을 생성하기 위한 동작이 필요하기 때문에 CSS-in-CSS에 비해 성능적인 측면이 떨어질 수 있다.

 

하지만 동적인 대규모 웹 앱에서 컴포넌트 기반으로 개발할 떄 생산성을 높일 수 있다.

 

CSS-in-JS 사용하기

대부분의 CSS-in-JS은 사용방식이 유사한데, 템플릿 리터럴을 활ㅇ요해서 동적인 스타일을 정의하면 된다. 먼저 props의 타입을 정의하고, 이 props를 활용해서 동적인  스타일링을 구현한다.

또한 variant props의 유형에 따라 다른 스타일을 적용하고 싶다면 css함수를 사용하여 스타일을 정의하고 variant 값에 따라 맵 객체를 생성하여 사용할 수도 있다. (emotion 기준)

type ButtonRadius = 'xs' | 's' | 'm' | 'l';
export const buttonRadiusStyleMap:Record<ButtonRadius, SerializedStyles>={
  xs:css`
    border-radius:${radius.extra_small}
  `,
  // ...
}

 

 

그리고 유틸리티 함수를 활용하여 중복 타입 선언을 피할 수 있다.

interface BadCase {
  height?: string;
  isFull?: boolean;
}

const Component = styled.div<BadCase>`
  height: 100;
  margin: 0;
  ${({ isFull }) =>
    isFull &&
    css`
      margin: 0 -15px;
    `}
`;

const GoodCase = styled.div<Pick<Props, 'height' | 'isFull'>>``;

 

 

+ Recent posts