๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋ก ํŠธ์—”๋“œ/React

CSS Module

by alswlfl 2022. 12. 8.

CSS Module: ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์Šคํƒ€์ผ๋ง ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ  → CSS ํด๋ž˜์Šค๊ฐ€ ์ค‘์ฒฉ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€

โญ๏ธ CRA(create-react-app)๋กœ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ์—์„œ CSS Module๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, CSSํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ .module.css๋กœ ํ•˜๋ฉด ๋จ

์‚ฌ์šฉ๋ฒ•

[Box.module.css]

.Box {
  background: black;
  color: white;
  padding: 2rem;
}

[Box.js]

import React from "react";
import styles from "./Box.module.css";

function Box() {
  return <div className={styles.Box}>{styles.Box}</div>;
}

export default Box;

→ className์„ ์„ค์ • ํ•  ๋•Œ์—๋Š”, styles.Box ์ฒ˜๋Ÿผ import๋กœ ๋ถˆ๋Ÿฌ์˜จ styles๊ฐ์ฒด ์•ˆ์— ์žˆ๋Š” ๊ฐ’์„ ์ฐธ์กฐ

→ ํด๋ž˜์Šค ์ด๋ฆ„์— ๋Œ€ํ•˜์—ฌ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์—, CSS ํด๋ž˜์Šค ์ด๋ฆ„์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•œ ์ด๋ฆ„๊ณผ ์ค‘๋ณต๋˜๋Š” ์ผ์ด ์—†์Œ

 

์‚ฌ์šฉํ•˜๊ธฐ ์ ํ•ฉํ•œ ์ƒํ™ฉ

  • ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ(ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด, ํ”Œ๋žซํผ ๊ทธ๋ฆฌ๊ณ  ๊ธฐ์ˆ  ๋“ฑ์— ์žˆ์–ด์„œ ๊ณผ๊ฑฐ๋กœ๋ถ€ํ„ฐ ๋ฌผ๋ ค ๋‚ด๋ ค์˜จ ๊ฒƒ์„ ์˜๋ฏธ)์— ๋ฆฌ์•กํŠธ๋ฅผ ๋„์ž…ํ•  ๋•Œ
  • CSS ํด๋ž˜์Šค๋ฅผ ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•˜์—ฌ CSS ํด๋ž˜์Šค ๋„ค์ด๋ฐ ๊ทœ์น™ ๋งŒ๋“ค๊ธฐ ๊ท€์ฐฎ์„ ๋•Œ

CSS ํด๋ž˜์Šค ๋„ค์ด๋ฐ ๊ทœ์น™

1. ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์€ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ž‘ ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ ํ•จ.

2. ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ๋‹จ CSS ํด๋ž˜์Šค๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„๊ณผ ์ผ์น˜์‹œํ‚ด (ex: .Button)

3. ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ณด์—ฌ์ง€๋Š” CSS ํด๋ž˜์Šค๋Š” CSS Selector๋ฅผ ์ž˜ ํ™œ์šฉํ•œ๋‹ค. (ex: .MyForm .my-input)

 


CSS Module์€ ๋ณ„๋„๋กœ ์„ค์น˜ํ•ด์•ผ ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์Œ โ–ธ webpack(์—ฌ๋Ÿฌ๊ฐœ ํŒŒ์ผ์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ํ•ฉ์ณ์ฃผ๋Š” ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(Module bundler)์—์„œ ์‚ฌ์šฉํ•˜๋Š” css-loader์—์„œ ์ง€์›

 

์•„์ด์ฝ˜๋“ค์„ ์ปดํฌ๋„ŒํŠธ ํ˜•ํƒœ๋กœ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: react-icons

$ yarn add react-icons
  • ํด๋ž˜์Šค ์ด๋ฆ„์— - ๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค๋ฉด styles['my-class']๋กœ ์ž‘์„ฑ
  • ๋งŒ์•ฝ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด, ${styles.one} ${styles.two}๋กœ ์ž‘์„ฑ
  • ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์€ ${styles.one} ${condition ? styles.two : ''}๋กœ ์ž‘์„ฑ

 CSS Module์ธ classnames๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ bind๊ธฐ๋Šฅ ์‚ฌ์šฉ

CSS ํด๋ž˜์Šค ์ด๋ฆ„ ์ง€์ •ํ•ด์ค„ ๋•Œ, cx('ํด๋ž˜์Šค ์ด๋ฆ„')๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

ex)

cx('one', 'two')
cx('my-component', {
	condition: true
})
cx('my-component', ['another','classnames'])

โœ”๏ธŽ ์ฐธ๊ณ  ๋‚ด์šฉ

  • CSS Module์€ Sass์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ → ํ™•์žฅ์ž๋ฅผ .module.scss๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋จ (๊ทธ ์ „์— node-sass ์„ค์น˜ํ•„์š”)
  • CSS Module์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํŒŒ์ผ์—์„œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ณ ์œ ํ™” ํ•˜์ง€ ์•Š๊ณ  ์ „์—ญ์  ํด๋ž˜์Šค์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ:global
:global .my-global-name{
}

[Sass์˜ ๊ฒฝ์šฐ]

:global {
	.my-global-name{
   	}
}
  • CSS Module์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ณณ์—์„œ ํŠน์ • ํด๋ž˜์Šค์—์„œ๋งŒ ๊ณ ์œ  ์ด๋ฆ„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ:local
:local .make-this-local{
}

[Sass์˜ ๊ฒฝ์šฐ]

:local {
	.make-this-local{
    }
}