---
title: "Tailwind를 떠나며 다시 CSS 구조를 배운 이야기"
published: 2026-05-16T09:14:26.000Z
canonical: https://jeff.news/article/2772
---
# Tailwind를 떠나며 다시 CSS 구조를 배운 이야기

Julia Evans가 몇 년간 써온 Tailwind를 걷어내고, 의미 있는 HTML과 순수 CSS로 사이트를 다시 정리한 경험을 공유했다. 핵심은 Tailwind를 단순히 버린 게 아니라, Tailwind가 줬던 제약과 시스템을 CSS 코드베이스 안에서 직접 재구성했다는 점이다.

## Tailwind를 그냥 버린 게 아니라, 배운 걸 자기 CSS로 옮긴 이야기

- 글쓴이는 8년 전 Tailwind를 처음 만났을 때 꽤 반가웠다고 함
  - 당시에는 CSS를 어떻게 구조화해야 할지 감이 없었고, 선택지는 거의 ‘완전한 혼돈’ 아니면 Tailwind였음
  - Tailwind 덕분에 작은 사이트를 많이 만들 수 있었고, 그 과정에서 리셋, 색상 팔레트, 폰트 스케일 같은 시스템의 가치를 배움

- 이번에는 몇몇 사이트에서 Tailwind를 걷어내고, 의미 있는 HTML과 순수 CSS 쪽으로 옮겨봄
  - 본인은 풀타임 프론트엔드 개발자가 아니라 CSS를 띄엄띄엄 배워왔다고 밝힘
  - 그래서 이번 작업은 ‘Tailwind가 싫어서 탈출’이라기보다, Tailwind가 대신 잡아주던 규칙을 직접 설계해보는 실험에 가까움

> [!IMPORTANT]
> 핵심은 Tailwind의 장점을 부정하는 게 아님. Tailwind가 제공하던 제약과 체계를 가져와서, 필요한 부분만 자기 CSS 코드베이스에 다시 심는 쪽에 가까움.

## CSS를 나누는 기준

- 가장 큰 변화는 CSS를 컴포넌트 단위로 나누는 방식임
  - 각 컴포넌트는 고유한 클래스를 갖고, 다른 컴포넌트의 CSS를 덮어쓰지 않는다는 규칙을 둠
  - 각 컴포넌트마다 별도 CSS 파일을 두면, 100줄짜리 컴포넌트를 고칠 때 그 100줄만 생각하면 됨
  - Vue나 React 컴포넌트와 정신적으로는 비슷하지만, 실제로 자바스크립트가 꼭 필요한 건 아님

- 예를 들어 `.zine` 같은 클래스를 하나의 컴포넌트로 보고, 그 안에서 `.horizontal`, `.vertical`, `:hover` 같은 변형을 중첩 선택자로 관리함
  - `@scope`나 웹 컴포넌트처럼 강제 격리를 쓰지는 않음
  - 그래도 “한 컴포넌트의 CSS가 다른 컴포넌트를 건드리지 않는다”는 컨벤션만으로도 유지보수 난이도가 꽤 내려갔다고 함

- 전역 색상은 `colors.css`에 CSS 변수로 모아둠
  - `--pink`, `--red`, `--orange` 같은 변수들을 정의해두고 필요한 곳에서 가져다 씀
  - 색상은 워낙 어려운 영역이라 이번 리팩터링에서는 크게 손대지 않았고, 모든 색상이 이 파일에 있어야 한다는 규칙만 둠

- 폰트 크기는 Tailwind의 스케일을 거의 그대로 가져옴
  - Tailwind에서는 `text-lg`, `text-xl`, `text-2xl`처럼 “좀 크게”라는 감각으로 고를 수 있었음
  - 순수 CSS에서는 `--size-lg`, `--line-height-lg` 같은 변수를 만들고 `font-size: var(--size-lg)`처럼 씀
  - Tailwind보다 조금 장황하지만, `px`, `em`, `rem`을 매번 고민하지 않아도 되는 장점은 유지됨

## 리셋, 유틸리티, 베이스 스타일

- CSS 리셋은 Tailwind의 preflight 스타일 앞부분 약 200줄을 복사해서 가져옴
  - 대표적으로 모든 요소에 `box-sizing: border-box`를 적용하는 부분이 있음
  - 이 설정 덕분에 요소의 너비가 패딩까지 포함해서 계산되는데, 글쓴이는 이미 이 동작에 꽤 익숙해져 있었다고 함
  - `html { line-height: 1.5; }` 같은 기본값도 무의식적으로 기대하고 있었을 가능성이 큼

- 유틸리티 클래스는 아주 작게 유지함
  - 여러 컴포넌트에서 반복되는 버튼 같은 요소나, 스크린리더 전용 텍스트를 위한 `.sr-only` 정도가 여기에 들어감
  - Tailwind식 유틸리티를 전부 재현하려는 게 아니라, 정말 자주 쓰고 조심해서 관리할 것만 남기는 방식임

- 베이스 스타일은 최대한 적게 시작함
  - 예를 들어 모든 `section` 안쪽을 950px 중앙 컬럼으로 맞추는 스타일, 링크 색상을 `--orange`로 지정하는 정도만 둠
  - 처음부터 전역 규칙을 많이 만들면 다시 혼돈이 될 수 있으니, 컴포넌트에서 공통 패턴이 보일 때 아래에서 위로 올리는 방식을 택함

## 여백과 반응형은 더 CSS답게 접근

- 여백은 아직 완전히 정답을 찾은 상태는 아니지만, Tailwind 때보다 원칙적으로 다루려는 중임
  - 예전에는 화면이 마음에 들 때까지 패딩과 마진 클래스를 여기저기 붙이는 식이었다고 함
  - 지금은 바깥 레이아웃 컴포넌트가 자식 간격을 책임지게 하려 함
  - 예를 들어 `section > * + * { margin-top: 1rem; }`처럼 형제 요소 사이에만 여백을 주는 패턴을 실험함

- 반응형 디자인은 미디어 쿼리보다 CSS Grid를 더 쓰는 방향으로 감
  - Tailwind에서는 `md:text-xl`처럼 특정 브레이크포인트 이상에서 스타일을 바꾸는 패턴을 많이 썼음
  - 지금은 `auto-fit`과 `minmax`를 써서 넓은 화면에서는 2열, 좁은 화면에서는 1열이 자동으로 되게 만드는 식을 배우는 중임
  - `grid-template-areas`도 많이 썼는데, 글쓴이는 이 기능을 Tailwind만으로 쓰기 어렵다고 봄

> [!TIP]
> 반응형을 전부 브레이크포인트로 해결하지 않아도 됨. CSS Grid를 잘 쓰면 레이아웃 자체가 화면 크기에 맞춰 자연스럽게 접히는 구조를 만들 수 있음.

## 빌드 시스템을 피하고 싶었지만, esbuild는 괜찮았던 이유

- 개발 중에는 빌드 시스템 없이도 충분히 작업 가능하다고 봄
  - CSS에는 이제 `@import`가 있고, 중첩 선택자도 표준으로 들어왔음
  - 그래서 `reset.css`, `typography.css`, `colors.css` 같은 파일을 직접 import하며 개발할 수 있음

- 배포용으로 묶을 때만 esbuild를 쓰는 정도는 받아들일 만하다고 함
  - 예시 명령은 CSS를 번들링하고, SVG는 data URL로, WOFF2 폰트는 파일로 처리하는 식임
  - esbuild는 웹 표준 위에 얹혀 있고, Go로 된 정적 바이너리라서 부담이 적다고 봄

## 왜 Tailwind에서 멀어졌나

- 현실적인 이유 중 하나는 Tailwind 최신 버전이 빌드 시스템에 더 강하게 의존하게 됐다는 점임
  - 글쓴이는 빌드 시스템을 거의 쓰지 않는 방식으로 Tailwind를 써왔고, 그래서 몇 년 동안 Tailwind v2에 머물러 있었음
  - 여러 프로젝트에 `tailwind.min.css`가 2.8MB, gzip 후 270KB짜리로 들어가 있었는데, 본인도 좀 우스운 상태라고 느낌

- 본인이 CSS를 더 잘하게 된 것도 큰 이유임
  - 처음에는 Tailwind의 제한이 도움이 됐지만, 이제는 이상한 CSS 실험이나 Grid 고급 기능처럼 Tailwind로 표현하기 애매한 것들을 직접 쓰고 싶어짐
  - 어떤 사이트는 순수 CSS와 Tailwind가 섞여 있었고, 이 조합은 유지보수하기 별로였다고 함
  - 의미 있는 HTML을 직접 써보면 어떤 느낌일지도 궁금했다고 함

- 단순한 도구 선택을 넘어, CSS 전문성을 어떻게 바라볼지에 대한 얘기도 나옴
  - 글쓴이는 예전에는 “CSS는 쉬워 보이는데 왜 안 되지?”라는 식의 태도를 갖고 있었을 수 있다고 돌아봄
  - 하지만 지난 10년 동안 CSS를 진지한 기술로 존중하게 됐고, “CSS가 어렵다”는 건 CSS가 어려운 문제를 풀고 있기 때문이라고 봄
  - 특히 대규모 언어 모델(LLM) 시대에는 사람의 전문성을 더 소중히 봐야 한다는 문제의식도 언급함

- 이 글의 결론은 꽤 현실적임
  - Tailwind는 많은 걸 가르쳐줬고 실제로 유용했음
  - 하지만 어느 시점부터는 프레임워크가 제공하는 제약을 그대로 쓰는 대신, 필요한 제약을 직접 고르고 설계하는 쪽이 더 맞을 수 있음
  - CSS를 피해야 할 대상으로 보는 대신, 제대로 배워볼 만한 기술로 보는 태도 변화가 글 전체의 핵심임

---

## 기술 맥락

- 이 글에서 중요한 선택은 Tailwind를 완전히 부정하는 게 아니라, Tailwind가 주던 구조화 장치를 순수 CSS로 옮긴 거예요. 리셋, 폰트 스케일, 색상 변수 같은 건 개발자가 매번 새로 고민하면 금방 흐트러지거든요.

- 컴포넌트별 CSS 파일을 둔 이유는 변경 범위를 줄이기 위해서예요. 한 컴포넌트의 스타일을 고칠 때 사이트 전체 CSS를 머릿속에 올릴 필요가 없으면, 작은 개인 사이트나 문서형 사이트에서도 유지보수가 훨씬 편해져요.

- 반응형에서 CSS Grid를 더 쓰려는 것도 같은 맥락이에요. 브레이크포인트를 많이 만들면 화면 크기마다 예외가 늘어나는데, `auto-fit`이나 `minmax`를 쓰면 레이아웃 규칙 자체가 더 유연해져요.

- esbuild를 배포 단계에만 쓰는 건 꽤 실용적인 절충이에요. 개발 경험은 웹 표준 CSS에 가깝게 유지하면서, 실제 배포 파일은 하나로 묶어 네트워크 비용을 줄일 수 있거든요.

## 핵심 포인트

- Tailwind의 리셋, 색상 팔레트, 폰트 스케일 같은 시스템은 그대로 배울 만한 자산으로 남음
- 컴포넌트별 CSS 파일, 전역 색상 변수, 제한된 유틸리티 클래스로 유지보수 범위를 줄임
- 반응형 처리는 미디어 쿼리보다 CSS Grid, auto-fit, grid-template-areas 같은 웹 표준 기능을 더 활용하는 쪽으로 이동
- Tailwind 최신 버전의 빌드 시스템 의존성과 2.8MB짜리 CSS 파일이 마이그레이션의 현실적 동기가 됨

## 인사이트

이 글은 Tailwind 비판이라기보다, 프레임워크가 가르쳐준 규칙을 자기 CSS 설계로 흡수하는 과정에 가깝다. 프론트엔드 개발자라면 ‘유틸리티 우선’과 ‘의미 있는 구조’ 사이에서 어디까지 자동화하고 어디부터 직접 설계할지 다시 생각하게 됨.
