스타일링 선택 기록: CSS, SCSS, styled-components, Tailwind CSS 비교

진밥·2026년 3월 11일
post-thumbnail

썸네일 이미지는 AI를 활용했지만, 글은 모두 직접 작성했습니다.


🪄 TL;DR

  • CSS → SCSS → CSS Modules → MUI → styled-components → Tailwind CSS 순으로 직접 프로젝트에 적용해보며 체감한 장단점을 정리해보았다.
  • 여러가지를 사용해본 후 결국 채택한 건 Tailwind CSS였다. 태그 이름을 명확하게 볼 수 있고, 개발자 도구로 바로 수정해 볼 수 있고, 파일 관리와 네이밍 고민에 대한 비용을 아끼기 위해 선택하였다.
  • 토큰(컬러/폰트/규칙)은 CSS로 따로 모아 관리하고, 나머지는 유틸리티로 빠르게 조립하였다.

대충이 안 되는 스타일링 방식 고르기

나는 CSS를 정말 좋아한다. 어떤 디바이스에서 봐도 틀어짐이 없고, 디테일한 인터랙션까지 완벽하게 들어간 UI를 완성할 때 가장 뿌듯하다. 특히나 처음 보는 유형의 에러 원인을 찾아내고 여러번 테스트 끝에 해결했을 땐, 오랫동안 더럽게 방치된 집을 깨끗하게 청소한 것처럼 뿌듯하다. (집 대청소 하는 것도 좋아하는데, 더러운 걸 치우고 정리해서 완벽한 상태를 만드는 것을 좋아하는 듯하다.) SI회사에서 수많은 프로젝트의 퍼블리셔로 일하며 별의 별 UI 오류들과 이상하게 틀어지는 레이아웃을 다 고쳐온 만큼 CSS를 꽤 잘 안다고 생각했다.

하지만 1px의 오차도 허용하지 못하던 이 성격이, React 공부라는 목적을 달성하는 데 방해가 된다. UI는 간단하게만 구현하고 React를 공부하려고 했는데 만족스럽지 않은 UI를 보면 그냥 지나치지 못하고 자꾸만 디테일을 다듬고 있다. 스타일링은 힘 빼고 대충하자고 생각했지만, 나도 이렇게 모든 방식을 다 적용해보고 고를 줄 몰랐다. 😅

CSS부터 Tailwind CSS까지 다 갈아엎어본 기록

회사에서는 보통 프로젝트 스펙에 맞춰 정해진 방식을 사용한다. SCSS를 사용해야 하면 SCSS를 사용하고, Tailwind CSS를 사용해야 하면 Tailwind CSS를 사용하고, 라이브러리가 정해져 있으면 거기에 맞추면 된다. 그런데 이번 프로젝트는 정말 오랜만에 내가 직접 스타일링 방식을 골라야 했다.

이번 Stock-Lens 프로젝트의 목표는 화려한 인터랙션 구현보다 React와 TypeScript 기본기를 익히고 모달과 무한 스크롤 같은 핵심 기능을 직접 구현해보는 것이었다. 이전 글에서는 폴더 구조를 여러 번 갈아엎으며 내가 통제하고 예상할 수 있는 features 중심 구조를 만들었는데, 이번에도 스타일링 방식을 직접 갈아엎으며 프로젝트에 맞는 최적의 방식을 찾아보게 되었다.

이번 글에서 각 스타일링 방식의 사용법이나 특장점에 대해서는 설명하지 않으려고 한다. 직접 프로젝트에 여러 스타일링 방식을 도입해보며 실제로 어떤 장단점을 느꼈는지, 그리고 어떤 기준으로 선택했는지 개인의 경험을 위주로 기록해보려고 한다.

React 스타일링, 어떤 걸 고려해야 할까

처음에는 일반적으로 어떤 걸 많이 쓰는지부터 찾아보았다. 블로그 글을 몇 개 읽어보니 다들 설명하는 게 비슷했고, 결국 내가 스타일링을 할 때 어떤 부분을 중점적으로 생각하는지 기준을 정해야겠다고 생각했다.

‘React 공부에 집중할 수 있도록 최대한 간단하게 구현할 수 있는 방식’을 찾는 게 나의 목표인만큼, 얼마나 빨리 환경을 만들고 간편하게 적용할 수 있는지가 가장 중요한 고려 사항이었다.

우선 내가 고려한 선택지들의 특징을 요약해보자면 아래와 같았다.

  • CSS는 가장 익숙한 기본 방식이다.
  • SCSS믹스인 및 변수 활용이 가능하고, CSS를 더 짧게 사용할 수 있게 해준다.
  • CSS Modules는 클래스가 기본적으로 로컬 스코프를 가져서 전역 충돌을 줄여주는 방식이다.
  • styled-components는 스타일을 입힌 컴포넌트를 사용하는 방식이다.
  • Tailwind CSS는 직접 태그에 스타일 클래스를 적용해 유틸리티 조합으로 가는 방식이다.
  • MUI는 스타일링 방식보다 UI 라이브러리에 가깝지만, “내가 직접 만들 것인가, 시스템을 빌릴 것인가”도 선택의 일부라서 같이 비교했다.

그럼 본격적으로, 하나씩 적용해본 후기를 작성해보도록 하겠다.

기본 중의 기본, CSS

처음에는 가장 기본 중의 기본인 CSS를 이용하여 스타일을 작성했다. reset, font 같은 기본 설정 관련 파일들을 먼저 만들었는데, 초반 설정 작업에도 시간이 꽤 많이 소요되었다.

딱히 더 추가할 설명이 없을 정도로 큰 문제가 없는 기본적인 방식이었다. 하지만 이미 SCSS의 짧은 코드가 더 친숙한 나는 점점 길어지는 선택자 이름이 아쉬웠고, CSS를 조금 쓰다가 바로 SCSS로 변환했다.

선택자를 짧게 쓸 수 있어서 좋은 SCSS

퍼블리싱을 한지 얼마 안 됐을 때, CSS를 쓰다가 SCSS를 처음 써보았을 때의 감동을 잊을 수 없다. 한없이 길어지는 클래스명을 어떻게 하면 더 짧고 보기 편하게 쓸 수 있을까에 대해 고민하고 있었는데, SCSS가 그 고민의 답이 되었다. 중첩 반복을 줄이기 좋고, 변수나 믹스인도 사용할 수 있고, 구조를 눈으로 따라가기도 편해서 CSS보다 더 선호하는 방식이다.

하지만 CSS와 마찬가지로 변수, 믹스인, 기본 설정들은 다 직접 작성해야 한다. 어서 React 코드로 로직을 작성해야 하는데 기본 파일 설정, 클래스 이름 고민, 파일 분기 고민, 공통 변수와 variations까지 신경쓰다보니 스타일링에 너무 진심이 되어버렸다.

한참이나 고민하며 기본 설정을 하다가 힘을 빼고 사용할 만한 다른 방법을 사용해야겠다고 생각했다.

고민을 덜어주는 CSS Modules 방식

CSS Modules 방식도 최근에서야 써봤는데, 1) 전역 충돌 문제가 줄어든다 2) 긴 고민 없이 클래스 이름을 지을 수 있다는 게 장점이다. 각 컴포넌트당 한 파일만 신경쓰면 되니까 관리가 편했다.

그런데 단점은 .module.scss 파일이 계속 늘어난다. 컴포넌트마다 스타일 파일이 하나씩 붙으니까 관리 포인트가 많아진다. 빠르게 작업하다 보니 비슷한 패턴이 생길 때마다 다른 CSS Modules 파일에서 코드를 복사해오는 일이 늘었고, DRY를 지키기 어려웠다. (사용 단위로 묶어서 재사용할 수도 있었겠지만, 최대한 스타일에 적은 시간을 사용하고 싶었다.)

사실 내 눈에 거슬려서 그렇지 큰 단점은 아니었고, 오히려 규모가 있거나 충돌 관리가 중요한 프로젝트에서는 꽤 합리적인 선택이라고 생각한다. 다만 내 프로젝트에서는 스타일링 안정성보다 시간을 아끼는 게 중요했다. 파일도 그만 만들고 싶었다.

시간 아끼게 MUI 라이브러리를 쓰자!

스타일에 신경을 쓰면서도 'React 공부에 집중해야해!' 라는 생각을 계속 했다. 그래서 그냥 아예 이미 잘 만들어진 시스템을 써보자 싶어서 MUI를 도입했다.

진작 사용할 걸 싶을 정도로 간단하고 좋았지만, 내가 지금까지 만든 화면과 디자인 톤이 너무 달랐다. 그래서 부분부분 커스터마이징하고, 맞는 컴포넌트를 찾아서 적용하고 하다보니 결국 시간이 또 오래 걸렸다... ㅋㅋ

이미 만들어둔 컴포넌트를 바꾸는 것도 일이고, 그 위에 MUI 컴포넌트를 적용하고 커스텀하는 것도 일이었다. 내가 원하는 모양이 꽤 분명한 상태라면, 애매하게 시스템을 빌리는 게 꼭 빠른 길은 아니라는 생각이 들었다. 초반부터 사용해서 MUI 스타일을 그대로 적용했다면 시간을 더 아꼈을 수 있었겠지만, 중간부터 수정하며 도입하기에는 드는 비용이 컸다.

안 써봐서 궁금했던 styled-components를 써보자

React 스타일링 방식을 검색하면 꼭 나오는 styled-components를 사용해보았다. 사실 한 번도 안 써봐서 궁금했던 것도 있었다. 기존 다른 스타일링 방식과는 작성법도 적용법도 달라서 신기했다.

처음에는 CSS-in-JS로 tsx 파일 안에서 작성하다가, 컴포넌트 로직과 관계 없는 스타일 코드가 너무 길어져서 전체 코드의 가독성을 해쳤다. 그래서 각 컴포넌트 파일별로 styled 파일을 따로 분리했다.

styled-components에서 중요한 건 컴포넌트 네이밍이었다. Wrapper, Container, Box, Button 같은 이름의 컴포넌트들이 생기고, 이름만 보고 이게 컴포넌트인지 스타일용 컴포넌트인지 헷갈릴 때도 많았다. 실제로 어떤 태그인지 확인하기 위해서 styled 파일 안으로 한 번 더 들어가야 하는 것도 불편했다.

도메인 컴포넌트와 styled-components의 이름이 겹치는 순간에는 둘 중 하나를 변경해주어야 했고, 쓰면서 불편하다는 생각이 많이 들었다.

시간을 아껴주는 고마운 Tailwind CSS

여러 스타일링 방식을 적용하며 나온 결론: 커스텀하고, 파일 만들고, 이름 짓는 시간을 아끼자!
그렇게 최종적으로 선택한 게 바로 Tailwind CSS였다. 👏🏻

Tailwind CSS는 실무를 하면서 여러 번 사용했었는데, 클래스 이름이 길어지는 게 싫어서 개인적으로는 선호하지 않았다. 하지만 스타일링 구축을 위해 파일을 만들고, 네이밍과 구조를 고민하는 데 많은 시간을 쏟다보니, 이제는 가장 간편하게 시작할 수 있는 방식인 Tailwind CSS가 너무 반가웠다.

Tailwind CSS의 가장 큰 장점은 태그를 태그 그대로 볼 수 있다는 것, 개발자 도구를 켜서 className을 바꾸면 직관적으로 어떻게 스타일이 적용되는지 바로 확인할 수 있다는 것이었다. 스타일을 위해 새로운 클래스 이름을 붙여줄 필요도 없다. 마침 styled-components를 쓰다 넘어와서 이 장점이 더 크게 느껴졌다.

결국 긴 className을 감수하더라도 네이밍 고민과 파일 분리, 연결 추적 비용을 크게 줄여주는 Tailwind CSS의 장점이 크다고 느껴 해당 방식을 채택하게 되었다.

토큰은 CSS, 나머지는 Tailwind CSS

지금 내가 적용한 방식은 이렇다.

  • 토큰 / 컬러 / 폰트 / 기본 규칙은 CSS 쪽에 둔다.
  • 컴포넌트 레벨 스타일링은 Tailwind CSS로 처리한다.

위 이미지처럼 현재 프로젝트 구조를 보면 shared/styles 하위에 tokens.css, fonts.css, base.css를 두고 관리하고 있다.

가장 기초적인 css만 정의해두고 styles 파일을 가볍게 가져간 지금의 구조가 마음에 든다. 적절한 유틸리티 클래스 활용 + 공통으로 적용되는 기본 규칙이 있으니 필요에 맞게 사용하고 확장하기 편하다.

Tailwind CSS 관련 꿀팁들

tokens.css vs tailwind.config.js

현재 내 프로젝트에는 tailwind.config.js를 따로 만들지 않았다. Tailwind CSS v4에서는 CSS-first 구성이 기본이 되었는데, 여기서 @theme는 그냥 CSS 변수를 선언하는 게 아니라, Tailwind 유틸리티와 연결되는 토큰을 정의하는 문법이다.

그래서 현재 프로젝트에서는 토큰은 tokens.css의 일반 CSS 변수로 관리하고, 컴포넌트 스타일링은 Tailwind CSS 유틸리티로 처리하는 방식을 유지했다. 필요할 때만 @theme로 옮기는 쪽이 지금 구조에는 더 잘 맞는다고 판단했다.

prettier-plugin-tailwindcss

prettier-plugin-tailwindcss는 className의 순서를 정렬해주는 prettier 플러그인이다.

Tailwind CSS를 사용할 때 매번 className 순서를 일일이 맞추기가 정말 어렵다. 중구난방으로 정렬된 값들을 보며 전부 뜯어 고치고 싶었는데, 하나하나 리팩토링 하긴 어려워서 찾아보니 역시 공식 플러그인이 있었다.

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

Tailwind CSS 공식 문서에서도 해당 Prettier 플러그인을 공식으로 안내하고 있고, 추천하는 className 순서대로 자동 정렬을 해주어서 정말 정말 편하다.

Tailwind CSS IntelliSense

모든 Tailwind CSS 클래스를 머릿속에 저장하고 쓰는 건 무리기에, IntelliSense 플러그인의 도움을 받았다. IntelliSense 플러그인은 ClassName 자동완성, Hover 미리보기, linting 같은 기능이 있어서 Tailwind CSS로 작업할 때 필수라고 볼 수 있다.

내가 적용한 설정은 아래와 같다.

{
  "editor.quickSuggestions": {
    "strings": "on"
  },
  "files.associations": {
    "*.css": "tailwindcss"
  }
}

작업할 때 특히 체감이 컸던 건 editor.quickSuggestions.strings였다. 원래는 스페이스로 공백을 만들어야 ClassName 속성의 목록이 떴는데, 공백을 만들지 않아도 자동완성이 잘 뜨게 해줘서 정말 편했다.

그리고 files.associations는 .css 파일을 Tailwind CSS 모드로 열어줘서, @theme, @source 같은 Tailwind CSS 전용 문법을 다룰 때도 도움이 되었다.

이런 설정들은 초반에 조금 귀찮더라도 한 번 해두면 이후 작업이 편해진다.

갈아엎은 시간이 아깝지 않은 알찬 경험

결국은 Tailwind CSS 방식을 적용했지만, 적용하기까지 꽤 긴 방황이 있었다. 그래도 대표적인 스타일링 방식들의 사용법을 익히고 장단점도 직접 느껴본 알찬 경험이었다고 생각한다. 다음에 다른 프로젝트에서 스타일링 방식을 고민할 때는 목적과 특성에 맞는 방식을 더 빠르게 선택할 수 있을 것 같다.

나의 이번 프로젝트는 작은 규모 + React 공부 목적 + 스타일에 사용하는 시간 비용 최대한 아끼기가 목적이었고, 그래서 Tailwind CSS가 만족스러운 선택이 되었다.

이름 짓기, 파일 만들기, 태그 감추기 등 모두 여러분의 소중한 시간적 비용을 사용하게 하는 것임을 기억해야 한다. 팀 컨벤션이 있으면 그걸 따르는 게 당연히 우선이지만, 프로젝트 규모와 디자인 시스템 운영의 중요성, 스타일 재사용 전략 등의 핵심 변수들을 고려하여 알맞은 스타일링 방식을 적용해야 한다. 역시나 스타일링 방식에도 정답이 없고, 개인의 선호와 상황에 맞게 사용하면 된다.

다음 글 예고

다음 글에서는 내 노트북에서는 멀쩡하던 폰트가 다른 기기에서 이상하게 보이게 한 FOUT 현상과 해결 과정을 기록해보려고 한다.

프로젝트 진행 과정이 궁금하다면 아래 저장소에서도 함께 볼 수 있다.

stock-lens GitHub 저장소

profile
꼬들밥 말고 진밥

0개의 댓글