
CSS in JS ๊ธฐ์ ์ด์ ์ธ๊ธฐ ํฐ์ง๋ React ๋ผ์ด๋ธ๋ฌ๋ฆฌ
React ์คํ์ผ ์ ์ฉ๋ฐฉ์
1) CSS
2) CSS-in-CSS (Sass, Bootstrap, TailwindCSS ๋ฑ)
3) CSS-in-JS (styled-components ๋ฑ)
styled-components ์ค์นํ๊ธฐ
npm install styled-components
// npm install styled-components@5
// App.js
import React from 'react';
import Example from './components/Example';
import normalize from 'styled-normalize';
import { createGlobalStyle } from 'styled-components';
// GlobalStyle ์ ์ฉ
const GlobalStyle = createGlobalStyle`
${normalize}
div {
padding: 30px;
}
span {
color: hotpink;
font-size: 18px;
font-weight: bold;
}
button {
width: 60px;
border: none;
margin-top: 20px;
cursor: pointer;
background-color: pink;
}
`;
const App = () => {
return (
<>
<GlobalStyle />
<div>
<h1>์๋
ํด๋ ์คํํธ๋ผ</h1>
<span>์ธ์์์ ์ ์ผ๊ฐ๋ ํฌํ
์ดํ ์นฉ</span>
<br />
<button>ํด๋ฆญ</button>
<Example />
</div>
</>
);
};
export default App;
// Example.jsx
import React from 'react';
const Example = () => {
return (
<>
<h1>๋ธ๊ธฐ๊ฐ ์ข์ ๋ธ๊ธฐ๊ฐ ์ข์</h1>
<span>๋ธ๊ธฐ ๋ธ๊ธฐ ๋ธ๊ธฐ ๋ธ๊ธฐ ์์์์์์</span>
<br />
<button>click</button>
</>
);
};
export default Example;
Global Style
Styled-Components๊ฐ ์ ๊ณตํ๋createGlobalStyle()ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
Global๋ง ๊ทธ๋๋ก ์ ์ญ ์ฆ, ๋ชจ๋ ์ปดํฌ๋ํธ์์ ๊ณตํต์ผ๋ก ์ ์ฉ๋๋ ์คํ์ผ์ ์๋ฏธํ๋ค.
โ ์น ํ์ด์ง ๋ฐฐ๊ฒฝ์, ๊ธ๊ผด ๋ฑ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ ์คํ์ผ์ ํจ์จ์ ์ด๋ค.
createGlobalStyle()ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด CSS ํ์ผ ์์ด๋ ์ ์ญ ์คํ์ผ ์ฝ๊ฒ ์์ฑํ ์ ์๋ค.
createGlobalStyle()๋ฅผApp.js(ํ์ฌ ์ต์์ ์ปดํฌ๋ํธ)์๋จ์ ์ถ๊ฐํด ์ฃผ๋ฉด, ๋ชจ๋ ํ์ ์ปดํฌ๋ํธ ์คํ์ผ์ ์ ์ฉํ ์ ์๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ์ ์์๊ฐ ๋๋ค.
Styled-Components๋ฌธ๋ฒ์์ ์คํ์ผ์ ๊พธ๋ฉฐ์ค ๋tagged tamplate literal (``)์ ์ฌ์ฉํ๋ค.


Reset & Normalize ์ ์ฐจ์ด๊ฐ ๋๋ ๊ฑธ๊น?
- ๋ธ๋ผ์ฐ์ ์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ์คํ์ผ์ด ๋ธ๋ผ์ฐ์
(Chrome, Safari, Edge ๋ฑ)๋ง๋ค ๋ค๋ฅด๋ค.Reset CSS vs Normalize CSS๋ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ง์ ์ํด ๊ฐ ๋ธ๋ฌ์ฐ์ ์ ๊ธฐ๋ณธ ์คํ์ผ์ ๋ฌดํจํํ๋ค.
Reset CSS / Normalize CSS ์ค์นํ๊ธฐ
npm i styled-reset npm i styled-normalize
Reset CSS์ ์ ์ฉํ๋ฉด ๊ธ๊ฒฉํ๊ฒ ์นํ์ด์ง๊ฐ ๋ฌ๋ผ์ง๋ค.Reset CSS๋ฅผ ์ ์ฉํ ๋ค, ์๋ฌด๋ฐ ์คํ์ผ๋ ์ถ๊ฐํ์ง ์์ผ๋ฉด, ํด๋น ์นํ์ด์ง ์์ ๋ชจ๋ HTML ์์๊ฐ ๋์ผํ๊ฒ ๋ณด์ธ๋ค.Normalize CSS๊ฐ ๊ฐ์ฅ ๋์ค์ ์ผ๋ก ์ฌ์ฉ๋๊ณ ์๋ค.๊ฒฐ๋ก ์ ๋ฌด์์ ์ฌ์ฉํ๋ ์ ๋ต์ ์๋ค๋ ๊ฒ ์๋๊น?
์์ ์ ์ํฉ์ ๊ฐ์ฅ ์ ํฉํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ํํ์!! ๊ทธ๊ฒ์ด ๊ทธ๋๊ฐ ๊ฐ๋ ๊ธธ์ด๋
ธ๋ผ ๐ข
Reset / Normalize ์ฐธ๊ณ ์ฌ์ดํธ
import React from 'react';
import styled from 'styled-components';
const ContentDiv = styled.div`
margin: 40px;
padding: 30px;
border: solid 2px;
background-color: aliceblue;
`;
const ContentH2 = styled.h2`
width: 200px;
margin: 0 auto;
text-align: center;
`;
const App2 = () => {
return (
<ContentDiv>
<ContentH2>Content</ContentH2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos excepturi corrupti quo
blanditiis! Adipisci amet corporis ipsum odio minima aliquid quisquam! Dignissimos natus
laborum qui veritatis quaerat eaque! Nemo, ullam.
</p>
</ContentDiv>
);
};
export default App2;
styled-components
- React ์ธ๋ผ์ธ์ผ๋ก ์คํ์ผ์ ์ ์ฉํ ๋์ ๋ค๋ฅด๊ฒ ๊ธฐ์กด CSS ๋ฌธ๋ฒ์ผ๋ก ํ๋กํผํฐ ์์ฑ ๊ฐ๋ฅํ๋ค.
const ๋ณ์๋ช = styled.ํ๊ทธ๋ช ` background-color : red; `

import React from 'react';
import styled from 'styled-components';
const ContentDiv = styled.div`
margin: 40px;
padding: 30px;
border: solid 2px;
background-color: aliceblue;
`;
const ContentH2 = styled.h2`
color: ${(props) => (props.name === 'hello' ? 'hotpink' : 'black')};
width: 200px;
margin: 0 auto;
text-align: center;
`;
const App2 = () => {
return (
<ContentDiv>
<ContentH2 name="hello">Content</ContentH2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos excepturi corrupti quo
blanditiis! Adipisci amet corporis ipsum odio minima aliquid quisquam! Dignissimos natus
laborum qui veritatis quaerat eaque! Nemo, ullam.
</p>
</ContentDiv>
);
};
export default App2;
props
props๋ฅผ ์ฌ์ฉํด์ ์กฐ๊ฑด์ ๋ฐ๋ผ ์คํ์ผ์ ์ ์ฉํ๋ค.
- ๋ฌธ์์ด ๋ฆฌํฐ๋ด ์์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๋ฃ์ ๋ ์ฒ๋ผ
${ }์์ ์ฝ๋๋ฅผ ์ ๋ ฅํ๋ค.
- ์ผํญ์ฐ์ฐ์๋ฅผ ์ด์ฉํด
props.name์ ์กฐ๊ฑด์ด ์ฐธ์ด๋ฉดhotpink๊ธ์์์, ๊ฑฐ์ง์ด๋ฉดblack๊ธ์์์ ์ถ๋ ฅํ๋ค.

import React from 'react';
import styled from 'styled-components';
const ContentDiv = styled.div`
margin: 40px;
padding: 30px;
border: solid 2px;
background-color: aliceblue;
`;
const ContentH2 = styled.h2`
color: ${(props) => (props.name === 'hello' ? 'hotpink' : 'black')};
width: 200px;
margin: 0 auto;
text-align: center;
`;
const Content = styled(ContentH2)`
border: 1px solid blue;
`;
const App2 = () => {
return (
<ContentDiv>
<ContentH2 name="hello">Content</ContentH2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos excepturi corrupti quo
blanditiis! Adipisci amet corporis ipsum odio minima aliquid quisquam! Dignissimos natus
laborum qui veritatis quaerat eaque! Nemo, ullam.
</p>
<Content>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</Content>
</ContentDiv>
);
};
export default App2;
ํ์ฅํ๊ธฐ
ContentH2์ ์คํ์ผ์Content๋ก ํ์ฅํด์ ์ฌ์ฉํ ์ ์๋ค.


// App3.js
import React from 'react';
import { createGlobalStyle } from 'styled-components';
import { ButtonOne } from './components/ButtonOne';
import { ButtonTwo } from './components/ButtonTwo';
import { ButtonThree } from './components/ButtonThree';
import { ButtonFour } from './components/ButtonFour';
// ๊ธ๋ก๋ฒ ์คํ์ผ ์ ์ฉ
const GlobalStyle = createGlobalStyle`
button {
width: 200px;
height: 80px;
border-radius: 10px;
margin: 30px;
font-size: 20px;
}
`;
const App3 = () => {
return (
<>
<GlobalStyle />
<ButtonOne>Global / Styled</ButtonOne>
<ButtonTwo>Global / Styled</ButtonTwo>
<ButtonThree>Global / ํ์ฅ</ButtonThree>
<ButtonFour name="Four">Global / props</ButtonFour>
</>
);
};
export default App3;
// ButtonOne.jsx
import styled from 'styled-components';
// ์ผ๋ฐ styled-components ์คํ์ผ ์ ์ฉ
export const ButtonOne = styled.button`
background-color: gold;
`;
// ButtonTwo.jsx
import styled from 'styled-components';
// ์ผ๋ฐ styled-components ์คํ์ผ ์ ์ฉ
export const ButtonTwo = styled.button`
background-color: lightgreen;
color: white;
box-shadow: 5px -5px greenyellow;
font-weight: bold;
`;
// ButtonTree.jsx
import styled from 'styled-components';
import { ButtonTwo } from './ButtonTwo';
// ํ์ฅํ๊ธฐ
export const ButtonThree = styled(ButtonTwo)`
border: 4px solid purple;
border-radius: 50px;
color: purple;
`;
// ButtonFour.jsx
import styled from 'styled-components';
// props์ ๋ฐ๋ฅธ ์กฐ๊ฑด๋ถ ์คํ์ผ
export const ButtonFour = styled.button`
background-color: ${(props) => (props.name === 'Four' ? 'powderblue' : 'red')};
border-radius: 50px 70px;
border: 5px dotted yellow;
`;
import React from 'react';
import './App.css';
import Question from './components/Question';
const App = () => {
return (
<>
<nav className="box">
<ul>
<li id="detail" className="text">
์์ธ์ ๋ณด
</li>
<li id="qa" className="text">
Q&A
</li>
<li id="review" className="text">
Review
</li>
</ul>
</nav>
<Question />
</>
);
};
export default App;
import React from 'react';
const Question = () => {
return (
<div className="box">
<h2 className="text">Q&A</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos excepturi corrupti quo
blanditiis! Adipisci amet corporis ipsum odio minima aliquid quisquam! Dignissimos natus
laborum qui veritatis quaerat eaque! Nemo, ullam.
</p>
</div>
);
};
export default Question;

CSS
- ๋ถ๋ชจ ์ปดํฌ๋ํธ์์
importํ CSS๋ ์์๊น์ง ์๋์ผ๋ก ์ ์ฉ๋๋ค.
- ์์ ์ปดํฌ๋ํธ์์ ์๋ก CSS๋ฅผ ์ ์ฉํ๊ฒ ๋๋ฉด ๋ถ๋ชจ์ ์คํ์ผ์ ์์ ์ปดํฌ๋ํธ์
import๋ ์คํ์ผ์ด ๋ฎ์ด ์ฐ์ฌ์ง๊ฒ ๋๋ค.=> ๋ฐ๋ผ์ ๋ฆฌ์กํธ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก
CSS ์ ํ์ ์ฐ์ ์์๊ฐ ์ ์ฉ๋๋ฉฐ, ์ปดํฌ๋ํธ์ ์คํ์ผ์ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ตญ ๋ค๋ฅธ ์ปดํฌ๋ํธ ์คํ์ผ์๋ ์ํฅ์ ๋ฏธ์น๋ค.
์๋์ importํ CSS๋ฅผ ์ดํด๋ณด์!
๋ถ๋ชจ ์ปดํฌ๋ํธ
App.js๊ฐimportํApp.css์คํ์ผ์ด ์๋,
์์ ์ปดํฌ๋ํธQuestion.jsx๊ฐimportํQuestion.css์ ์คํ์ผ์ด ์ ์ฉ๋์๋ค.
import "./App.css";
body {
padding: 30px;
}
div {
margin: 40px;
background: rgb(214, 243, 255);
}
h2 {
width: 200px;
margin: 0 auto;
text-align: center;
color: rgb(206, 74, 131);
}
import './Question.css';
div {
background: rgb(255, 220, 226);
margin: 30px;
padding: 30px;
}
h2 {
width: 200px;
margin: 0 auto;
text-align: center;
color: rgb(132, 196, 153);
}
p {
font-weight: bold;
}

๊ทธ๋ฐ๋ฐ ๋ง์ฝ...
App.js์ ์ผ๋ฐ ํ๊ทธ๊ฐ ์๋๋ผ ํ๊ทธ์ ํด๋์ค ์ด๋ฆ์ ๋ฃ์ด์ฃผ๊ณ ,
App.css์์ ํด๋์ค ์ด๋ฆ์ ์ ํํ ๋ค, ์คํ์ผ์ ์ ์ฉํ๋ฉด ๊ณผ์ฐ ์ด๋ป๊ฒ ๋ ๊น?
import "./App.css";
body {
padding: 30px;
}
.box {
margin: 40px;
background: rgb(214, 243, 255);
padding: 20px;
}
.text {
width: 200px;
margin: 0 auto;
text-align: center;
color: rgb(206, 74, 131);
font-weight: bold;
}
p {
font-weight: bold;
padding: 20px;
}

import './Question.css';
.box {
background: rgb(255, 220, 226);
margin: 30px;
padding: 30px;
}
.text {
width: 200px;
margin: 0 auto;
text-align: center;
color: rgb(132, 196, 153);
}
p {
font-weight: bold;
}

์ผ๋ฐ์ ์ธ CSS
App.js์๋ง ํด๋์ค ์ด๋ฆ์ ์ ํํ CSS ์คํ์ผ์ ์ ์ฉํ๋ํ๋์ ๋ฐฐ๊ฒฝ์ด ์ ์ ์ฉ๋ ๊ฑธ ๋ณผ ์์๋ค.
- ๊ทธ๋ฐ๋ฐ ์ญ์, ์์ ์ปดํฌ๋ํธ
Question.jsx์๋ ํด๋์ค ์ด๋ฆ์ ์ ํํ CSS ์คํ์ผ์ ์ ์ฉํ๋ ๋ฐ๋ก ์์ ์ปดํฌ๋ํธ CSS ์คํ์ผ์ด ๋ฎ์ด ์ฐ์ฌ์ง๋ฉด์๋ถํ์ ๋ฐฐ๊ฒฝ์ด ์ ์ฉ๋์๋ค.=> ๋ฐ๋ผ์ ํด๋์ค๋ฅผ ํตํด ์ฐ์ ์์๋ฅผ ๋์ฌ๋ ๊ฒฐ๊ตญ ์ปดํฌ๋ํธ๋ผ๋ฆฌ
ํด๋์ค ์ด๋ฆ์ด ์ค๋ณต๋๋ฉด ์์ฉ ์์ด์ง๋ค. ํนํ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌํด ์์ ํ๋ ๋ฆฌ์กํธ์ ํน์ฑ์ ํด๋์ค ์ด๋ฆ์ด ๊ฒน์น ์ํ์ฑ์ ๋ ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด CSS ํ์ผ ์ด๋ฆ์ .css๋ฅผ
module.css๋ก ๋ฐ๊ฟ์ฃผ์!
module.css๋ฅผ ์ฌ์ฉํ๋ฉดclass๋ช์ ๊ณ ์ ๊ฐ์ ์ถ๊ฐํด๋ ๊ฒน์น์ง ์๋๋ค!
import React from 'react';
import styles from './Question.module.css';
const Question = () => {
return (
<div className={styles.box}>
<h2 className={styles.text}>Q&A</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos excepturi corrupti quo
blanditiis! Adipisci amet corporis ipsum odio minima aliquid quisquam! Dignissimos natus
laborum qui veritatis quaerat eaque! Nemo, ullam.
</p>
</div>
);
};
export default Question;

import React from 'react';
import styles from './App.module.css';
import Question from './components/Question';
const App = () => {
return (
<>
<nav className={styles.box}>
<ul>
<li id="detail" className={styles.text}>
์์ธ์ ๋ณด
</li>
<li id="qa" className={styles.text}>
Q&A
</li>
<li id="review" className={styles.text}>
Review
</li>
</ul>
</nav>
<Question />
</>
);
};
export default App;

module ์ ์ฉ
Question.cssํ์ผ๋ช โQuestion.module.css๋ก ๋ฐ๊ฟ์ค๋ค.
Question.jsxํด๋์ค๋ช โ{styles.ํด๋์ค๋ช }์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
App.cssํ์ผ๋ช โApp.module.css๋ก ๋ฐ๊ฟ์ค๋ค.
App.jsํด๋์ค๋ช โ{styles.ํด๋์ค๋ช }์ผ๋ก ๋ฐ๊ฟ์ค๋ค.=> ์ด๋ ๊ฒ ํ๋ฉด ์๋์ผ๋ก ํด๋์ค๋ช ์ด ๊ฒน์น์ง ์๋๋ก ์ฒ๋ฆฌํด์ค๋ค.
nav์ div ๋ชจ๋ box๋ผ๋ style์ ๋ฐ๊ณ ์์ง๋ง, ํด๋์ค๋ช ์ด ๋ค๋ฅด๋ค!
Example.jsx ํ์ผ โ Example.module.css ํ์ผ
// Example.modeule.css ํ์ผ
.section h1 {
font-size: 50px;
}
// Example.jsx ํ์ผ
<div className={styles.section}>
<h1>hello world</h1>
<p className={styles.contents}>hello world</p>
<div/>