2025. 4. 20. 14:22ㆍReact
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
리액트에서 CSS Modules을 사용할 때 이런 코드 자주 쓰이죠?
import styles from './Component.module.css';
return <div className={styles.container}>Hello</div>;
리액트에서 CSS Modules을 사용할 때, styles. 입력 시 클래스명이 자동으로 추천되거나, styles.container를 클릭해도 CSS 정의로 바로 이동되지 않으면 불편할 수 있습니다. 이 문제, VS Code 확장 하나로 깔끔하게 해결할 수 있습니다.
CSS Modules 설치 방법
VS Code 에디터에서 CSS Modules 확장 프로그램을 검색하여 설치합니다.
또는 터미널에서 명령어로 바로 설치 가능합니다.
code --install-extension clinyong.vscode-css-modules
CSS Modules의 주요 기능
자동완성(Auto-complete)
styles. 입력 시 .module.css에 정의된 클래스명이 자동으로 제안됩니다.
이제 클래스명 외울 필요도, 복붙할 필요도 없습니다.
정의로 이동(Go to Definition)
styles.container에서 Ctrl(또는 Cmd)+클릭 시, 해당 클래스 정의 위치로 바로 이동합니다.
작은 기능 같지만 개발 흐름이 끊기지 않아 큰 차이를 만들어요.
CSS Modules의 사용 예시
이제 styles. 입력하면 container가 자동완성되고,
클릭만으로 CSS 정의로 이동할 수 있습니다. 두 기능 모두 아주 깔끔하게 동작해요.
.container {
padding: 16px;
background-color: #f2f2f2;
.description {
margin-top: 10px;
font-size: 15px;
font-weight: 400;
line-height: 21px;
text-align: center;
&.skeleton {
margin-top: 14.5px;
margin-bottom: 34.5px;
}
}
}
import styles from './Component.module.css';
function Component() {
return
<div className={cx(styles.container)}>
Hello!
<div className={cx(styles.description, styles.skeleton)}>
<span></span>
</div>
</div>;
}
❗ 파일명이 반드시 *.module.css 또는 *.module.scss 형식이어야 하고, import styles from 형태로 스타일을 불러와야 합니다. 또한, 확장을 설치한 후에는 VS Code를 재시작해보세요. 위 조건들이 충족되지 않으면 기능이 제대로 동작하지 않을 수 있습니다.
예시 1. 배열을 활용한 CSS Modules 클래스 동적 적용
이 예시에서는 stars라는 배열을 .map()을 이용해 순회하며 별점을 렌더링 하고 있습니다. 포인트는 배열의 값(type)을 그대로 CSS Modules의 클래스 키로 사용하는 것입니다.
.reviewStarsArea {
display: flex;
position: absolute;
right: 10px;
bottom: 12px;
gap: 1px;
.star {
width: 10px;
height: 10px;
background: url("/images/search/icon_star_empty.svg") no-repeat 0 0;
background-size: cover;
&.filled {
background: url("/images/search/icon_star_filled.svg") no-repeat 0 0;
}
&.half {
background: url("/images/search/icon_star_half.svg") no-repeat 0 0;
}
}
}
return (
<div className={cx(styles.reviewStarsArea)}>
{stars.map((type, index) => (
<span key={index} className={cx(styles.star, styles[type])} />
))}
</div>
);
이처럼 배열을 활용해 styles[배열값] 형태로 클래스명을 동적으로 지정하면, CSS Modules의 타입 안전성과 자동완성 기능을 그대로 유지하면서도 유연하게 스타일을 적용할 수 있습니다.
예시 2. subType을 활용한 클래스 동적 적용과 조건부 렌더링
이 컴포넌트는 리뷰의 타입(subType)에 따라 다른 컴포넌트를 렌더링하고, 동시에 CSS Modules 클래스를 동적으로 적용하는 구조입니다.
.review {
&.photo {
aspect-ratio: 168 / 213;
}
&.text {
aspect-ratio: 168 / 252;
}
}
const ReviewTypeItem = ({
type,
imageUrl = [],
imageAlt = [],
thumUrl,
description,
isTesters = false,
hasKeyword = false,
reviewStars = 0,
subType,
}: ReviewTypeItemProps) => {
return (
<div className={cx(styles.review, styles[subType])}>
{subType === "photo" ? (
<PhotoReview type={type} imageUrl={imageUrl} imageAlt={imageAlt} thumUrl={thumUrl} description={description} />
) : (
<TextReview type={type} thumUrl={thumUrl} description={description} isTesters={isTesters} hasKeyword={hasKeyword} reviewStars={reviewStars} />
)}
</div>
);
};
CSS Modules에서는 객체 형태로 클래스명이 매핑되기 때문에, styles["photo"]나 styles[subType]처럼 문자열 키를 통해 접근할 수 있습니다.
예시 3. 드래그 상태에 따라 CSS Modules 클래스 동적으로 적용하기
useState를 사용해 드래그 상태를 관리하면, 드래그가 시작되거나 끝날 때마다 isDragging 값이 자동으로 변경됩니다. 이 상태 값을 기반으로 cx(styles.base, { [styles.active]: 조건 }) 형태로 조건부 클래스를 자연스럽게 조합할 수 있어, 특정 조건일 때만 스타일을 다르게 적용할 수 있습니다.
.dragItemWrapper {
padding: 12px;
border: 1px solid #ddd;
background-color: #fff;
transition: box-shadow 0.2s ease, background-color 0.2s ease;
cursor: grab;
&.active {
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
background-color: #f0f8ff;
}
}
import React, { useState } from 'react';
import styles from './DraggableItem.module.css';
import cx from 'classnames';
const DraggableItem = () => {
const [isDragging, setIsDragging] = useState<boolean>(false);
const handleDragStart = () => {
setIsDragging(true);
};
const handleDragEnd = () => {
setIsDragging(false);
};
return (
<div
draggable
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
className={cx(styles.dragItemWrapper, { [styles.active]: isDragging })}
>
드래그 가능한 아이템
</div>
);
};
export default DraggableItem;
React + CSS Modules 조합을 쓰는 개발자라면, 이 확장은 정말 생산성을 높여주는 필수템입니다.
클래스명 자동완성은 물론, 정의로 이동까지 한 번에 해결하세요!
[AI] 스마트스토어 & 쿠팡 셀러 주목! AI로 상세페이지 5분 만에 완성하기 (제디터 AI)
쇼핑몰 운영자라면 상세페이지 제작이 필수적이지만, 시간과 비용이 많이 듭니다. 이를 해결하기 위해 가비아(Gabia)에서 개발한 제디터 AI가 등장했습니다. 이 AI 도구는 상품 정보를 입력하면 자
dev-chim.tistory.com
스크립트 선언 위치
자바스크립트 선언 위치에 대해서 알아보겠습니다. head 태그 안에 스크립트 선언할 경우 DOM이 읽혀지기 전에 스크립트가 먼저 읽히므로 common.js에서 따로 후처리 해줘야 합니다. load 이벤트는 리
dev-chim.tistory.com
반응형 페이지 작업할 때, 분기점 순서 설정하는 법
반응형(responsive) 페이지 작업할 때, css에서 미디어 쿼리(media query) 분기점(breakpoint) 작성 순서입니다 분기점은 해당 프로젝트에 맞게 설정하시면 됩니다 Mobile First 작은 너비 순으로 시작 @media scre
dev-chim.tistory.com
[Utility] 쉽고 간편하게 디자인하기 : 캔바(Canva) 사용법
많은 사람들은 전문적인 디자이너가 아니라면 디자인 작업을 시작하는 것이 어렵다고 생각합니다. 이는 복잡한 디자인 프로그램의 사용에 대한 부담 때문일 수 있습니다. 그러나 제가 소개드리
dev-chim.tistory.com
[Terminal] nvm 설치 방법 및 오류 해결 하기
Node.js 버전을 관리하기 위해 많이 사용하는 nvm(Node Version Manager)을 설치하려 했으나, 터미널에서 nvm 명령어를 찾을 수 없다는 메시지가 출력되는 경우가 있습니다. 이번 포스팅에서는 nvm 설치 방
dev-chim.tistory.com
'React' 카테고리의 다른 글
[React] React 개발 속도를 높이는 나만의 VS Code 스니펫 설정 (0) | 2025.04.21 |
---|