Post

React 스타일링 선택 기준

CSS, CSS Module, Styled-components, Tailwind를 협업·유지보수 관점에서 비교

React 스타일링 선택 기준

React 스타일링 전략 비교: “무엇이 최고인가”가 아니라 “언제 무엇이 맞는가”

React에서 스타일링은 취향 문제가 아니다. 컴포넌트 설계 방식, 팀 협업 구조, 유지보수 비용과 직결된 아키텍처 선택이다. 따라서 중요한 질문은 이것이다.

이 프로젝트의 변경 속도, 협업 방식, UI 복잡도에 가장 잘 맞는 스타일링 방식은 무엇인가?

아래에서는 CSS, CSS Module, Styled-components, Tailwind를 선택 기준 중심으로 비교한다.


스타일링을 논하기 전에: React가 스타일링에 요구하는 전제

React는 UI를 컴포넌트 단위로 분리한다. 따라서 스타일링 역시 다음 질문을 피할 수 없다.

  • 스타일의 스코프(scope) 는 어디까지인가?
  • 스타일과 컴포넌트의 결합도는 어느 정도가 적절한가?
  • UI 변경 시 코드 수정 범위는 어디까지 허용하는가?

이 질문에 대한 답이 곧 스타일링 방식 선택 기준이다.


1️⃣ 전통 CSS (Global CSS)

개념

일반적인 .css 파일을 전역으로 로드하고 클래스명을 사용한다.

1
2
3
.button {
  padding: 8px 12px;
}
1
<button className="button">확인</button>

철학

  • 스타일과 구조 분리
  • CSS는 전역 자원
  • HTML 시절의 사고방식 연장선

왜 중요한가

  • 진입 장벽이 가장 낮다
  • 디자이너/퍼블리셔 협업이 쉽다
  • 빌드/런타임 비용이 없다

언제 문제가 되는가

  • 클래스 충돌(namespace 문제)
  • “이 클래스가 어디서 쓰이는지” 추적이 어렵다
  • 컴포넌트 단위 변경이 전체 UI에 파급됨

결론

  • 소규모 프로젝트, 정적 페이지, 프로토타입에는 적합
  • 컴포넌트 수가 늘어나는 순간 유지보수 비용 급증

2️⃣ CSS Module

개념

CSS를 파일 단위로 스코핑하여 컴포넌트 전용 스타일로 사용한다.

1
2
3
4
/* Button.module.css */
.button {
  padding: 8px 12px;
}
1
2
3
import styles from './Button.module.css';

<button className={styles.button}>확인</button>

철학

  • CSS는 유지하되, 스코프만 컴포넌트로 제한
  • 스타일 충돌을 빌드 타임에 해결

왜 중요한가

  • 전통 CSS의 단점을 가장 현실적으로 보완
  • 스타일 충돌 원천 차단
  • React의 컴포넌트 모델과 잘 맞는다

언제 문제가 되는가

  • 동적 스타일링이 많아질수록 클래스 조합이 복잡해짐
  • 로직(JS)과 스타일(CSS)이 완전히 분리되어 맥락 파악이 느릴 수 있음
  • 디자인 시스템 수준의 추상화는 다소 불편

결론

  • 대부분의 React 프로젝트에서 기본 선택지
  • “CSS를 잘 아는 팀”에게 가장 안정적인 옵션

3️⃣ Styled-components (CSS-in-JS)

개념

스타일을 JS 안에서 정의하고, 컴포넌트로 취급한다.

1
2
3
4
const Button = styled.button`
  padding: 8px 12px;
  background: ${props => props.primary ? 'blue' : 'gray'};
`;

철학

  • 스타일 = 컴포넌트의 일부
  • 상태/props 기반 스타일링을 1급 시민으로 취급

왜 중요한가

  • props 기반 동적 스타일링이 매우 자연스럽다
  • 스타일과 로직이 같은 파일에 있어 맥락 파악이 빠르다
  • 디자인 시스템, 테마 시스템 구축에 유리

언제 문제가 되는가

  • 런타임 스타일 생성 비용
  • 번들 사이즈 증가
  • 스타일이 과도하게 로직화될 위험
  • 팀 내 CSS 경험이 낮으면 오히려 가독성 저하

결론

  • 디자인 시스템, 테마, 고도의 동적 UI에 적합
  • 단순 CRUD 화면에서는 과한 선택일 수 있다

4️⃣ Tailwind CSS (Utility-first)

개념

미리 정의된 유틸리티 클래스를 조합해 스타일을 완성한다.

1
2
3
<button className="px-3 py-2 bg-blue-500 text-white rounded">
  확인
</button>

철학

  • 클래스 조합 = 디자인
  • 추상화보다 명시성
  • CSS 작성 자체를 최소화

왜 중요한가

  • 스타일 작성 속도가 매우 빠르다
  • 디자인 일관성이 강제된다
  • 클래스 네이밍 고민이 사라진다

언제 문제가 되는가

  • JSX 가독성 저하 (클래스 폭발)
  • UI 의미가 클래스에 묻혀 추상화가 약해질 수 있음
  • 디자인 변경 시 “조합 전체 수정”이 필요

결론

  • 빠른 개발, 소규모 팀, 스타트업에 매우 강력
  • 장기 유지보수에서는 컴포넌트 추상화 전략이 필수

철학적 차이 요약

방식핵심 철학
CSS스타일은 전역 자원
CSS Module스타일은 컴포넌트 전용 자원
Styled-components스타일은 컴포넌트 그 자체
Tailwind스타일은 클래스 조합 결과

협업과 유지보수 관점 비교

기준CSSCSS ModuleStyled-componentsTailwind
스코프 안전성
동적 스타일⚠️⚠️
디자이너 협업⚠️⚠️
대규모 유지보수⚠️⚠️
초기 생산성⚠️⚠️

“언제 무엇이 맞는가”에 대한 실전 기준

CSS / CSS Module이 맞는 경우

  • 명확한 디자인 가이드
  • 디자이너/퍼블리셔 협업
  • 중장기 유지보수 중요
  • 컴포넌트 수가 많음

CSS Module 우선


Styled-components가 맞는 경우

  • 테마/다크모드 필수
  • 상태 기반 스타일링이 핵심
  • 디자인 시스템 구축 목표

Styled-components


Tailwind가 맞는 경우

  • 빠른 MVP
  • 소규모 팀
  • UI 실험이 잦음

Tailwind + 컴포넌트 추상화 병행


정리: 스타일링 선택은 기술 문제가 아니라 구조 문제다

  • 스타일링 방식은 컴포넌트 경계 설정 문제
  • “편하다”보다 변경 비용을 기준으로 선택해야 한다
  • 하나가 최고인 경우는 없다
  • 프로젝트 성격이 바뀌면 스타일링 전략도 바뀌어야 한다

This post is licensed under CC BY 4.0 by the author.