가장 전통적이고 간단한 스타일링 방식입니다. .css 확장자를 가진 파일을 생성하고, 컴포넌트에서 직접 import하여 사용합니다.
import된 CSS 파일은 프로젝트 전체에 영향을 미칩니다. 따라서 서로 다른 컴포넌트에서 동일한 클래스 이름을 사용하면 스타일이 겹치거나 덮어쓰여 예기치 않은 결과를 초래할 수 있습니다.Button.css
.button {
background-color: blue;
color: white;
padding: 10px 20px;
border-radius: 5px;
}
Button.jsx
import React from 'react';
import './Button.css'; // CSS 파일 import
function Button({ children }) {
return <button className="button">{children}</button>;
}
export default Button;
만약 다른 컴포넌트(예: Card.jsx)에서 다른 스타일을 의도하고 .button이라는 동일한 클래스 이름을 사용하면, 두 스타일이 충돌하여 개발자가 의도하지 않은 스타일이 적용될 수 있습니다. 프로젝트가 커질수록 이러한 충돌 가능성도 높아집니다.
CSS Modules는 CSS 클래스 이름이 컴포넌트 내에서만 유효하도록(Locally Scoped) 만들어주는 기술입니다. 파일 이름을 [컴포넌트명].module.css로 작성하면, 빌드 과정에서 각 클래스 이름이 고유한 문자열로 자동 변환되어 스타일 충돌을 원천적으로 방지합니다.
Button.module.css
.button {
background-color: red;
color: white;
padding: 10px 20px;
border-radius: 5px;
}
Button.jsx
import React from 'react';
// CSS 모듈을 `styles` 객체로 불러옴
import styles from './Button.module.css';
function Button({ children }) {
// className에 `styles.클래스명` 형태로 적용
return <button className={styles.button}>{children}</button>;
}
export default Button;
위 코드는 빌드 시 다음과 같이 고유한 클래스 이름을 가진 HTML로 변환됩니다.
<button class="Button_button__a1B2c">버튼</button>
Button_button__a1B2c처럼 파일명과 클래스명, 해시값이 조합된 고유한 이름이 생성되므로 다른 컴포넌트의 스타일과 절대 충돌하지 않습니다.
App 컴포넌트와 Header 컴포넌트에서 각각 .title이라는 클래스를 정의했다고 가정해봅시다.
App.module.css
.title { color: red; }
Header.module.css
.title { color: green; }
App.jsx
import styles from './App.module.css';
import Header from './Header';
function App() {
return (
<>
<h1 className={styles.title}>App Title (빨간색)</h1>
<Header />
</>
);
}
Header.jsx
import styles from './Header.module.css';
function Header() {
return <h1 className={styles.title}>Header Title (초록색)</h1>;
}
App 컴포넌트의 <h1> 태그는 빨간색으로 렌더링됩니다.Header 컴포넌트의 <h1> 태그는 초록색으로 렌더링됩니다.일반 CSS였다면 CSS 로드 순서에 따라 하나의 스타일이 다른 스타일을 덮어썼겠지만, CSS Modules 덕분에 각 컴포넌트가 의도한 스타일을 안전하게 유지할 수 있습니다.
| 구분 | 일반 CSS | CSS Modules |
|---|---|---|
| 적용 범위 | 전역 (Global) | 로컬 (Local / Scoped) |
| 충돌 가능성 | 높음 (스타일 덮어쓰기 발생) | 없음 (클래스명 자동 고유화) |
| 클래스명 | className="title" | className={styles.title} |
| 적합한 경우 | - 전역 스타일 (Reset.css 등) - 간단한 단일 페이지 - 소규모 프로젝트 | - 컴포넌트 단위 스타일링 - 중/대규모 프로젝트 - 재사용 가능한 컴포넌트 개발 |