JS(JavaScript) 안에서 스타일을 정의하고, 렌더링할 때 라이브러리가 클래스를 만들어 style 태그로 주입하는 방식. styled-components와 Emotion이 대표다. React 18 이후 서버 컴포넌트(React Server Components)·스트리밍 SSR(Streaming Server-Side Rendering)이 자리 잡으면서 런타임에 CSS를 만드는 방식은 줄고, 빌드할 때 CSS를 뽑는 방식이 늘었다(2026 기준).
유행했던 이유
- 클래스 이름을 해시로 만들어 전역 충돌을 없앴다
- props로 스타일을 바꾸는 등 JS 값과 자연스럽게 연결됐다
- 컴포넌트와 스타일을 한 파일에 묶을 수 있었다
밀려난 이유
- 런타임 비용: 렌더링 → CSS 문자열 생성 →
style삽입 → 스타일 재계산이 매번 끼어든다. 라이브러리 런타임도 번들에 들어간다 → 번들 크기 줄이기 - 서버 컴포넌트와 맞지 않는다: 스타일을 만들려면 클라이언트 런타임(Context 등)이 필요해서 서버 컴포넌트에서 바로 쓸 수 없다
- 스트리밍 SSR: HTML을 조각조각 보내면 "다 렌더링한 뒤 스타일을 모아 넣는" 기존 방식이 꼬인다. 서버와 클라이언트의 클래스가 어긋나면 하이드레이션(Hydration) 불일치도 생긴다
- 재사용 방식도
styled(Button)상속에서variant·sizeprops를 받는 컴포넌트 API로 옮겨 갔다
대안
- Tailwind: 빌드 때 정적 CSS 생성, 서버 컴포넌트에서 그냥 쓴다
- CSS Modules: 파일 단위 스코프, 여전히 많이 쓴다
- Vanilla Extract·Panda CSS·StyleX: TS(TypeScript)로 쓰되 빌드 때 CSS 파일로 뽑는 "제로 런타임" 계열
런타임 값이 많은 경우(진행률 width, 사용자가 고른 색)는 인라인 스타일이나 CSS 변수로 넘기면 된다. 이 선택은 결국 "스타일을 언제 만드느냐"의 문제다. Sass와 PostCSS가 빌드 단계 안에서의 선택이라면, 이것은 빌드냐 런타임이냐의 선택이다.