바닐라 CSS는 단순하고 협업에 좋지만, React에서 가장 큰 단점은 스타일이 전역 스코프를 가진다는 점이다. 즉, 한 컴포넌트의 CSS 파일에서 작성한 규칙이 다른 컴포넌트까지 영향을 줄 수 있다.
CSS Modules는 이 문제를 해결할 수 있는 방식이다. CSS는 그대로 쓰되, 클래스 이름을 자동으로 "파일 단위로 고유하게 변환"하여 각 컴포넌트에만 적용되도록 스코프를 만들어준다.
이 글에서는 CSS Modules의 동작 원리, 사용법, 장단점을 정리한다.
CSS Modules는 CSS 파일에서 선언한 클래스 이름을 컴포넌트 단위로 고유하게 변환해주는 방식이다.
즉,
이 방식으로 스타일 충돌 없이 CSS를 안전하게 사용할 수 있다.
module.css 형태로 변경header.css → header.module.css
이 .module.css 이름이 빌드 툴에게 "이 파일은 CSS Modules 방식으로 처리해라"라고 알려주는 신호다.
import classes from './header.module.css';
여기서 classes 객체 안에는 CSS Modules에 의해 변환된 "고유 클래스 이름들"이 들어 있다.
<p className={classes.paragraph}>Hello World</p>
예를 들어 CSS에 아래와 같이 작성했다면
.paragraph {
text-align: center;
}
브라우저에서 렌더링된 HTML에는 아래와 같이 변경된 클래스가 붙는다.
<p class="paragraph_header__Xa2De">Hello World</p>
이렇게 고유한 클래스 이름이 생성되기 때문에 다른 컴포넌트에서 .paragraph를 선언해도 절대로 충돌하지 않는다.
CSS Modules를 사용해도 className은 문자열이므로 조건부 스타일링도 기존과 동일하게 사용 가능하다.
<p className={`${classes.paragraph} ${isActive ? classes.active : ''}`}>
Hello!
</p>
여기서 classes.active 또한 고유한 문자열이기 때문에 충돌이 생기지 않는다.
1) 컴포넌트 단위 스코프
2) CSS는 그대로 사용 가능
3) 협업 용이
4) 조건부 스타일링도 자연스럽게 가능
1) CSS 파일이 많아짐
2) 여전히 CSS를 알아야 함
3) 전역 스타일이 필요할 때 다소 번거로움