Styling tool/일반

[styling tool]CSS작성 방식 비교하기:CSS방법론(BEM), SCSS, CSS-in-JS, Tailwind

tea-tea 2024. 3. 26. 08:07

웹 페이지를 스타일링하는 방식으로서 등장한 CSS는 기존의 인라인 스타일 방식에 비해 많은 이점을 가졌지만 동시에 단점도 가지고 있었다. 이런 한계는 웹 기술이 발전하면서 다양한 방법으로 해결하고자 하였는데, 오늘 날에 나처럼 처음 이 영역에 들어선 사람들에게는 각 방식에 어떤 장단점이 있는 걸 비교하기가 어렵고, 최종적으로 무엇을 사용해야할지 고르기가 힘들다. 

그래서 이번 기회에 이 부분을 정리하려 한다.


1. 기존 CSS의 문제


  • 전역 스페이스 오염: 전역 스타일은 예기치 않은 충돌을 일으킬 수 있음.
  • JS 변수를 통한 동적 스타일링 불가: CSS는 정적이기 때문에 JavaScript 변수에 따라 스타일을 동적으로 변경하는 것이 제한적.
  • 컴포넌트 단위의 CSS 작성 불가: CSS는 전역 범위를 가지므로 컴포넌트 단위의 스타일링을 구현하기 어려움.

 

3. BEM 방법론의 등장: SCSS

BEM(블록(Element)-요소(Element)-모디파이어(Modifier)) 방법론은  HTML의 class와 CSS의 클래스 선택자를 작성하는 규약이다. . BEM은 코드의 가독성과 유지 보수성을 향상시키는 데 도움이 되는 구조를 제공한다. 

BEM 방법론의 주요 개념은 다음과 같다:

  1. 블록(Block): 독립적으로 의미 있는 부분을 나타내는 최상위 요소이다. 예를 들어, '버튼', '카드', '메뉴' 등이 블록에 해당할 수 있다.
  2. 요소(Element): 블록의 일부분으로 블록에 종속되어 있는 요소를 나타낸다. 요소는 블록 안에 위치하며 독립적으로 사용할 수 없다. 예를 들어, '버튼' 블록 내에서 '텍스트' 요소가 있을 수 있다.
  3. 모디파이어(Modifier): 블록이나 요소의 외관, 동작 또는 상태를 변경하는 데 사용된다. 예를 들어, '버튼' 블록의 크기를 조절하거나 색상을 변경하는 등의 수정을 모디파이어를 통해 할 수 있다.

하지만, 단점도 만만치 않았는데, 클래스명이 워낙 길어지다 보니 html의 가독성이 심각하게 떨어졌고 한눈에 코드를 파악하기 어려웠다. 

 

2024.02.27 - [CSS] - [CSS] BEM - CSS 방법론

2. 전처리기와 css module의 등장: SCSS


전처리기란, 웹팩 같은 번들러를 통해 일반 css로 컴파일되는 파일을 의미한다. 대표적으로 SCSS가 있다.

이들은 기존 css가 제공하지못하는 중첩 작성, 상속 및 확장, 믹스인 기반의 기능을 제공하여 코드의 재사용성과 가독성을 높였고 media-query 같은 적응형 css를 작성할 때도 편리함을 주었다.

또한, css module을 만들 수 있었다.

 

전처리기의 한계: JS 변수를 통한 동적 스타일링의 불편성은 여전히 존재.

3. CSS-in-JS의 등장

CSS-in-JS는 JavaScript 코드 내에서 CSS를 작성하고 관리하는 방식으로, 일반적으로 JSX 코드 내에서 스타일을 정의하거나 동적으로 스타일을 적용하는 것을 허용한다.


기본 작동 원리

CSS-in-JS는 주로 두 가지 방식으로 작동한다.

  1. 인라인 스타일 태그 사용: 일부 라이브러리(예: react-jss, emotion)는 스타일을 인라인 <style> 태그로 삽입하여 사용한다. 이를 통해 컴포넌트 단위의 스타일링이 가능해지며, 컴포넌트가 렌더링될 때 해당 스타일이 동적으로 적용된다.
  2. 예를 들어, react-jss를 사용하면 JavaScript 객체 형식으로 스타일을 작성하고, 해당 객체를 컴포넌트에 주입하여 사용할 수 있다. 컴포넌트의 state에 따라 스타일을 동적으로 변경할 수 있어서, 상태 변화에 따라 스타일을 업데이트할 수 있다
  3. 동적 클래스 생성: 다른 라이브러리(예: styled-components)는 tagged template literal을 사용하여 컴포넌트를 생성하고, props를 기반으로 스타일을 동적으로 변경할 수 있다. 이를 통해 컴포넌트의 props에 따라 다른 스타일을 적용할 수 있다.
  4. 컴포넌트 기반의 모듈 처리가 가능해진다.

 

문제: 성능 및 SSR과의 관계

CSS-in-JS는 일반적으로 번들 크기를 증가시키고 초기 렌더링 성능을 저하시킬 수 있다. 또한 몇몇 SSR 프레임워크에서는 CSS-in-JS와의 호환성 문제가 발생할 수 있다. 이를 해결하기 위해 다양한 최적화 기술이 필요하다.

성능 문제를 해결하기 위해 사용할 수 있는 몇 가지 대안

  • Critical CSS: 초기 렌더링에 필요한 CSS를 먼저 로드하여 페이지 성능을 향상시킨다. styled-components의 ServerStyleSheet API와 같은 기능을 사용하여 구현할 수 있다.
  • 최적화된 CSS 생성: CSS-in-JS 라이브러리가 생성하는 CSS를 최적화하여 번들 크기를 줄인다.
  • Near Runtime CSS: 컴포넌트 단위의 스타일을 최적화하여 동적 스타일링을 최소화한다.

 

4. 컴파일 타임의 CSS 라이브러리 + Util CSS (Tailwind) 조합 등장

이 방식은 css-in-js의 성능 상 단점과 ssr 호환성 문제를 해결하기 위해 등장하였다. 이는 기존의 scss 같은 컴파일 타임 라이브러리를 사용해서 클라이언트 단의 css 수정을 최소화하고, util css로 스타일 코드를 줄이며 state 기반으로 class를 수정하는 방식으로 동적 사용도 어느정도 구현 가능하다.

  • 장점: 전역 스페이스 오염 방지, 스타일 재사용, 런타임 오버헤드 방지 가능.
  • 단점: 직접적인 스타일 조작이 어려움.