Skip to main content
css-modules CSS Modules with Lightning CSS and PostCSS for component-scoped styling.
Covers *.module.css patterns, TypeScript integration, Vite configuration, and composition.
Use when building complex animations, styling third-party components, or migrating legacy CSS.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/MadAppGang/claude-code --skill css-modules명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name css-modules description CSS Modules with Lightning CSS and PostCSS for component-scoped styling.
Covers *.module.css patterns, TypeScript integration, Vite configuration, and composition.
Use when building complex animations, styling third-party components, or migrating legacy CSS.
CSS Modules
Overview
CSS Modules provide locally-scoped CSS by automatically generating unique class names at build time. This prevents style conflicts and enables true component encapsulation.
When to Use CSS Modules
Use Case CSS Modules Tailwind Complex animations Best Good Third-party component styling Best Harder Legacy CSS migration Best Refactor needed Rapid prototyping Slower Best Design system utilities Not ideal Best Component encapsulation Best N/A Team with CSS expertise Best Either
Hybrid Approach : Use both together - Tailwind for utilities, CSS Modules for complex components.
Documentation Index
Vite Integration
Lightning CSS
CSS Modules Spec
TypeScript Integration
CSS Modules Fundamentals
File Naming Convention src/
├── components/
│ ├── Button/
│ │ ├── Button.tsx
│ │ ├── Button.module.css # CSS Module
│ │ └── Button.test.tsx
│ └── Card/
│ ├── Card.tsx
│ ├── Card.module.css # CSS Module
│ └── index.ts
Files ending in .module.css are automatically processed as CSS Modules.
Basic Usage
.button {
padding : 0.5rem 1rem ;
border-radius : 0.375rem ;
font-weight : 500 ;
transition : background-color 150ms ease;
}
.primary {
background-color : hsl (221 , 83% , 53% );
color : white;
}
.primary :hover {
background-color : hsl (224 , 76% , 48% );
}
.secondary {
background-color : hsl (0 , 0% , 96% );
color : hsl (0 , 0% , 9% );
}
import styles from './Button.module.css'
interface ButtonProps {
variant ?: 'primary' | 'secondary'
children : React .ReactNode
}
export function Button ({ variant = 'primary' , children }: ButtonProps ) {
return (
<button className ={ `${styles.button } ${styles [variant ]}`}>
{children}
</button >
)
}
Generated Class Names
<button class ="${styles.button} ${styles.primary}" >
<button class ="Button_button_x7d9f Button_primary_a3k2j" >
Local vs Global Scope
.button {
}
:local (.button) {
}
:global (.external-library-class) {
}
.card :global (.markdown-body) {
}
Composition
composes Keyword Share styles between classes:
.flexCenter {
display : flex;
align-items : center;
justify-content : center;
}
.interactive {
cursor : pointer;
transition : all 150ms ease;
}
.button {
composes: flexCenter from './base.module.css' ;
composes: interactive from './base.module.css' ;
padding : 0.5rem 1rem ;
}
Multiple Compositions .primaryButton {
composes: button;
composes: primary from './colors.module.css' ;
composes: rounded from './shapes.module.css' ;
}
Usage in React
<button className={styles.primaryButton }>
{}
</button>
Vite Configuration
Lightning CSS (Recommended) Lightning CSS is 100x faster than PostCSS for transforms:
npm install lightningcss browserslist
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import browserslistToTargets from 'lightningcss/browserslist'
import browserslist from 'browserslist'
export default defineConfig ({
plugins : [react ()],
css : {
transformer : 'lightningcss' ,
lightningcss : {
targets : browserslistToTargets (browserslist ('>= 0.25%' )),
cssModules : {
pattern : '[name]__[local]_[hash:5]' ,
}
}
},
build : {
cssMinify : 'lightningcss'
}
})
Class Name Patterns Pattern Example Output [name]__[local]_[hash:5]Button__primary_a3k2j[local]_[hash:8]primary_a3k2j9x1[hash:8]a3k2j9x1 (production)
Lightning CSS Features (Included) Lightning CSS automatically handles:
Vendor prefixing (replaces autoprefixer)
Modern syntax transpilation
Nesting
Custom media queries
Color functions (oklch, lab, lch)
PostCSS Configuration (When Needed) For plugins Lightning CSS doesn't support:
export default {
plugins : {
'postcss-import' : {},
'postcss-custom-media' : {},
}
}
Note : Use Lightning CSS for transforms, PostCSS only for unsupported plugins.
TypeScript Integration
Type Declarations Without types, TypeScript doesn't know the shape of CSS modules:
import styles from './Button.module.css'
styles.button
Option 1: Wildcard Declaration (Simple)
declare module '*.module.css' {
const classes : { [key : string ]: string }
export default classes
}
Pros : No extra tooling
Cons : No autocomplete, no type safety
Option 2: Generated Declarations (Recommended) npm install -D vite-plugin-css-modules-dts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import cssModulesDts from 'vite-plugin-css-modules-dts'
export default defineConfig ({
plugins : [
react (),
cssModulesDts ({
outputDir : '.' ,
})
]
})
declare const styles : {
readonly button : string
readonly primary : string
readonly secondary : string
}
export default styles
Pros : Full autocomplete, type safety, catches typos
Cons : Generated files in source (add to .gitignore)
Option 3: CLI Generation npm install -D typed-css-modules
npx tcm src --pattern '**/*.module.css'
npx tcm src --pattern '**/*.module.css' --watch
{
"scripts" : {
"css:types" : "tcm src --pattern '**/*.module.css'" ,
"css:types:watch" : "tcm src --pattern '**/*.module.css' --watch"
}
}
Patterns
Component-Scoped Styling
.card {
border-radius : 0.5rem ;
background : white;
box-shadow : 0 1px 3px rgba (0 , 0 , 0 , 0.1 );
overflow : hidden;
}
.header {
padding : 1rem ;
border-bottom : 1px solid hsl (0 , 0% , 90% );
}
.content {
padding : 1.5rem ;
}
.footer {
padding : 1rem ;
background : hsl (0 , 0% , 98% );
}
import styles from './Card.module.css'
export function Card ({ children }: { children: React.ReactNode } ) {
return <div className ={styles.card} > {children}</div >
}
Card .Header = ({ children }: { children: React.ReactNode } ) => (
<header className ={styles.header} > {children}</header >
)
Card .Content = ({ children }: { children: React.ReactNode } ) => (
<div className ={styles.content} > {children}</div >
)
Card .Footer = ({ children }: { children: React.ReactNode } ) => (
<footer className ={styles.footer} > {children}</footer >
)
CSS Variables with Modules
:root {
--color-primary : hsl (221 , 83% , 53% );
--color-primary-dark : hsl (224 , 76% , 48% );
--spacing-sm : 0.5rem ;
--spacing-md : 1rem ;
}
.button {
background-color : var (--color-primary);
padding : var (--spacing-sm) var (--spacing-md);
}
.button :hover {
background-color : var (--color-primary-dark);
}
Theming with CSS Variables
.light {
--bg : white;
--text : hsl (0 , 0% , 9% );
--border : hsl (0 , 0% , 90% );
}
.dark {
--bg : hsl (0 , 0% , 9% );
--text : hsl (0 , 0% , 98% );
--border : hsl (0 , 0% , 20% );
}
.component {
background-color : var (--bg);
color : var (--text);
border : 1px solid var (--border);
}
Complex Animations CSS Modules excel at complex animations:
.overlay {
position : fixed;
inset : 0 ;
background : rgba (0 , 0 , 0 , 0.5 );
opacity : 0 ;
transition : opacity 200ms ease;
}
.overlayVisible {
composes: overlay;
opacity : 1 ;
}
.modal {
position : fixed;
top : 50% ;
left : 50% ;
transform : translate (-50% , -50% ) scale (0.95 );
opacity : 0 ;
transition : all 200ms cubic-bezier (0.16 , 1 , 0.3 , 1 );
}
.modalVisible {
composes: modal;
transform : translate (-50% , -50% ) scale (1 );
opacity : 1 ;
}
@keyframes slideIn {
from {
transform : translate (-50% , -50% ) translateY (20px ) scale (0.95 );
opacity : 0 ;
}
to {
transform : translate (-50% , -50% ) translateY (0 ) scale (1 );
opacity : 1 ;
}
}
.modalAnimated {
animation : slideIn 300ms cubic-bezier (0.16 , 1 , 0.3 , 1 );
}
Hybrid Approach: CSS Modules + Tailwind Use both together for maximum flexibility:
import styles from './ComplexCard.module.css'
function ComplexCard ({ title, children }: Props ) {
return (
<div className ={ `${styles.card } p-4 md:p-6 `}>
<h2 className ={ `${styles.title } text-lg font-semibold mb-2 `}>
{title}
</h2 >
<div className ={styles.animatedContent} >
{children}
</div >
</div >
)
}
When to Use Which Scenario Approach Layout utilities (flex, grid, spacing) Tailwind Responsive utilities Tailwind State variants (hover, focus) Tailwind Complex animations CSS Modules Keyframe animations CSS Modules Third-party component overrides CSS Modules Component state classes CSS Modules Design system utilities Tailwind One-off complex styles CSS Modules
Performance Benefits
Lightning CSS Advantages Feature Speed Improvement CSS parsing 100x faster than PostCSS Vendor prefixing Built-in, instant Minification Faster than cssnano Bundling Parallel processing
Dead Code Elimination Vite automatically eliminates unused CSS:
CSS Modules are naturally tree-shaken (only imported classes included)
Lightning CSS removes unused selectors
Bundle Size Optimization
export default defineConfig ({
build : {
cssMinify : 'lightningcss' ,
cssCodeSplit : true ,
}
})
Related Skills
tailwindcss - Utility-first CSS (complementary approach)
shadcn-ui - Component library using CSS variables
react-typescript - Component patterns with className
testing-frontend - Testing styled components
관련 직업
SOC