[Javascript] CSS-In-JS

seohyun Kang·2023년 1월 25일
0

Javascript

목록 보기
1/3
post-thumbnail

CSS-In-Js란?

CSS-In-Js는 단어의 의미 그대로 스타일을 작성하기 위해 Javascript를 사용하는 아이디어를 말합니다. 또한, CSS-In-Js는 특정 라이브러리가 아닌 Javascript로 스타일을 작성하는 아이디어를 통칭하며, 해당하는 라이브러리로 React-Jss, Styled-components 등이 있습니다.

CSS-In-Js의 가장 큰 특징은 전처리 Sass 등과 같은 전처리기 방식과 다르게 Runtime에서 스타일 시트를 생성하며, Javascript로 스타일 시트의 동적인 생성이 가능합니다.

CSS-In-Js에서 동적 스타일

아래는 'Red', 'Green', 'Blue' 버튼을 클릭하여 100 x 100 색상 배경 요소를 동적으로 생성하는 CSS-In-Js 예제 코드입니다.

const App = () => {
  const [color, setColor] = useState<string>("default");
  return (
    <div className="App">
      <button onClick={() => setColor("red")}>Red</button>
      <button onClick={() => setColor("green")}>Green</button>
      <button onClick={() => setColor("blue")}>Blue</button>
      <StyledView color={color} />
    </div>
  );
}

예제 코드의 기본 화면은 다음과 같으며,

head Tag의 style은 다음과 같습니다.

이제, 배경이 붉은 색인 가로 세로 100px의 요소를 생성하겠습니다.

해당 요소가 생성됨과 동시에 style에 해당 요소에 대한 스타일이 동적으로 생성되어 추가되었습니다.

이어서 Red, Green, Blue 요소를 생성하면 아래와 같이 각각의 요소에 대한 스타일이 추가됩니다.

당연하게도, 이미 생성된 요소에 대해서는 재생성하지 않습니다. 이를 통해, Styled-Components는 전달받은 props로 스타일을 재정의하고 동적 생성한다는 것을 알 수 있습니다.

CSS-In-Js를 사용하는 이유

Oleg Isonen의 게시물에서 공감하는 부분만 발췌했습니다. 해당 링크는 맨 하단의 Reference를 참조해 주세요.

- Lack of scoping

CSS-In-JS automates the scoping by generating unique selectors.

최근 웹 서비스는 이전과 다르게 다양한 페이지로 구성되며 그 복잡성이 증가하고 있습니다. 문제는 CSS가 단일 전역 네임스페이스를 가지고 있다는 것입니다. CSS-in-Js는 이러한 문제를 개별 Selector를 생성하여 CSS 적용 범위를 지정하는 방법으로 해결합니다.

- One-to-many relationship

CSS-in-JS encourages the coupling of CSS and HTML.

CSS를 수정하려면 그 안에 선언된 수많은 id, class, selector를 확인하고 어느 페이지 어디에 영향을 미치는지 확인하는 과정이 필요합니다. 위의 Lack of scoping 이슈와 동일하게 복잡성이 증가한 현대 웹 서비스에서 CSS를 수정하는 것은 큰 부담이 되며 예기치 못한 Side-effect를 발생시킬 가능성이 높습니다.

- Dead Code

CSS-In-JS helps with removing dead code.

기존 CSS Rule에서는 class, selector 등을 추적하여 HTML과 CSS 사이의 관계를 확인하는 과정이 필요했다면, CSS-In-Js는 변수를 전달받고 모듈을 통하여 컴포넌트(HTML)와 CSS의 관계를 명확하게 합니다.

- State-based styling

마지막으로, CSS-in-Js의 가장 큰 장점은 State-based-styling이라고 생각합니다.

{
	const [isFull, setIsFull] = useState<boolean>(false);
    {isFull ? (
    	<div className="full" /> 
    ) : (
    	<div className="" /> 
    )}
	
}
... OR ...
{

	const divEl = document.getElementById("bar");
    divEl.setAttribute("class", "full");
    <div id="bar" />
}

CSS-in-Js를 사용하기 전 위와 같은 방법으로 style을 지정해야 했지만, CSS-in-Js를 사용하면 state를 직접 변수로 스타일에 전달하여 개발자가 원하는 UI를 그릴 수 있습니다.

여러 클래스 이름을 포함하는 클래스 속성을 빌드하는 보다 전통적인 방법과 비교할 때 이것은 몇 가지 장점이 있습니다.

  1. 최종 CSS 규칙을 담당하는 논리는 상태에 액세스할 수 있으며 나머지 스타일과 함께 찾을 수 있습니다.

  2. HTML을 생성하는 논리는 클래스 연결 논리에 의해 덜 어수선해집니다.

CSS-In-Js 단점

Styled-Components를 사용하여 Progress Bar 컴포넌트를 생성했습니다. CSS-in-Js 는 Runtime에서 Progress Bar는 전달받는 Js property에 대하여 스타일을 동적으로 생성합니다.

위와 같이 각각의 width : n%에 대한 개별 스타일이 등록되고 UI로 그려집니다.

예제 코드에서는 코드가 가벼워서 전처리 CSS와 CSS-in-Js의 유의미한 차이를 발견하지 못하였습니다. 대신, CSS 전처리기와 CSS-in-Js 사이의 찬반 논쟁과 Performance 차이에 대한 포스트를 링크했습니다.

CSS vs CSS-in-Js
단점 및 Performance

마지막으로...

노드 UI 개발을 하면서 Progress bar를 만들었는데, 하루 정도 동작하면 CSS가 깨져버리는 이슈가 있었고 CSS-in-Js의 동작에 대해서 자세하게 찾아보는 계기가 되었습니다.

지금와서 생각하니 Progress bar의 6시간 동안의 진행 상황을 초당 반영하도록 코드를 작성하니 {seconds / 6 * 60 * 60} 총 21,600 번의 Dynamic 스타일이 생성되었음을 의미했습니다.

이번 계기로 Sass와 같은 전처리기와 CSS-in-Js의 차이, atomic CSS(tailwind)와 같은 CSS 라이브러리들의 장단점을 알게 되었고 적재적소에 사용할 수 있도록 하려고 합니다.

* 다음 CSS 관련 포스트는 tailwind 적용이 되지 않을까 생각해봅니다.


Reference :
Title Image 링크
CSS-In-Js를 사용하는 이유
CSS In Js 문제점
CSSOM이란?
Trade off of CSS-in-Js

0개의 댓글