Emotion
Table of Contents
๐คทTL;DR
- CSS-in-JS๋ ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์ด CSS์ ๋ฌธ์ ๋ฅผ ๋ณด์ํ๋ค.
- emotion๊ณผ styled-components๋ ์ฌ์ฉ์์ ์ฐจ์ด๊ฐ ๊ฑฐ์ ์์ผ๋ ๊ณจ๋ผ์ ์ฌ์ฉํ์.
- ์ ์ ํ IDE Extension์ ์ ํ์ฉํ์.
- CSS-in-JS๊ฐ ๋ชจ๋ ๊ฒฝ์ฐ์ ๋ํ ์ ๋ต์ด ์๋์ ์ธ์งํ์.
๐จCSS-in-JS
CSS-in-JS๋ HTML Element์ ์คํ์ผ์ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ํตํด์ ์ง์ ํ๋ ๋ฐฉ์์ ๋๋ค. .css ํ์ผ์ด ํ๋ ์ผ์ .js ํ์ผ์๊ฒ ์ํค๋ ๊ฒ์ด์ฃ . CSS๋ CSS์ด๊ณ , JS๋ JS์ ๋๋ค. ์ ๊ตณ์ด ๋์ ํฉ์ณ์ผ๋ง ํ๋ ๊ฒ์ผ๊น์? ์ด ์ ์ ์๋ ๋ฐ์์ ์ดํดํ๋ ค๋ฉด ์ฐ์ ๊ธฐ์กด css์ ๋จ์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ ๊ฐ ํ์ต ์คํ๋ฆฐํธ๋ ์งํํ ํ๋ก์ ํธ ํ์ผ์ ์ผ๋ถ์
๋๋ค. ์ฌ์ฉ์์ ํ์ฌ ์์น๋ฅผ ํ์ํ๊ธฐ ์ํ ์ปดํฌ๋ํธ์ ์คํ์ผ์ location-bar
๋ผ๋ ํด๋์ค๋ช
์ผ๋ก ์ง์ ํ๊ณ ์์ฃ . ๋จ์ํ ์ด ๋ถ๋ถ๋ง ๋ด์๋ ํฌ๊ฒ ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ด์ง๋ง, ์๋์ ๊ฐ์ ๋ฌธ์ ๋ค์ด ์์ต๋๋ค.
location-bar
๋ผ๋ ํด๋์ค๋ช ์ ์ถ์์ ์ ๋๋ค. ์ฆ, ์ฌ์ฉ์์ ์์น๋ฅผ ํ์ํ๊ธฐ ์ํlocation-bar
๋ ์ฅ๊ธฐ์ ์ผ๋ก ๋ค์ํ ํ์ด์ง์์, ๋ค์ํ ์ปดํฌ๋ํธ์์ ํ์ฉ๋ ์ ์์ต๋๋ค. CSS๋ ๊ทธ ์ ์ฉ ๋ฒ์๋ฅผ ์ง์ ํ๋ ๊ฒ์ด ์๋นํ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ํด๋์ค๋ช ์ ๋ ๊ธธ๊ณ ๋ณต์กํ๊ฒ ์ ํ ์ ๋ฐ์ ์์ต๋๋ค.- css ํ์ผ์ ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ๊ฐ ์ด๋ ต์ต๋๋ค. ๋น์ฅ ์ ํ์ผ์ ์ด๋ค ์ํ์ ์ ๋ณด๋ฅผ ํ์ํ๊ธฐ ์ํ ์ปดํฌ๋ํธ์ ์คํ์ผ๋ง์ด ๋ชจ์ฌ ์์ต๋๋ค. ์ํ ์ ๋ณด์ ์ฌ์ฉ์ ์์น๋ ํฌ๊ฒ ์ฐ๊ด์ด ์์ด๋ณด์์๋ ๊ฐ์ ํ์ด์ง์ ์๋ค๋ ์ด์ ๋ก ๊ฐ์ ํ์ผ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ์์ ํ๋ ค๋ฉด 400์ค ๊ฐ๋ ๋๋ ํ์ผ์์ ์ ๋ถ๋ถ์ ์ฐพ์์ผ๋ง ํฉ๋๋ค.
์์ ํ ๋น์์๋ ๋น์ฐํ ๋ถํธํจ์ด๋ผ ์๊ฐํ๊ณ ๊ฐ๋ดํด ์์ง๋ง, ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ก์ ๋๋ฅผ ์์ํด ๋ณด๋ ๋จธ๋ฆฌ๊ฐ ์ํฐํด์ง๋๋ค. ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฑ์ฅํ ๊ฒ์ด CSS-in-JS์ ๋๋ค.
๐emotion/styled
React์์ ์ฌ์ฉํ๋ CSS-in-JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ styled-components
์ emotion
๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ค ์ฌ์ฉํ๋ ์
์ฅ์์ ์ฐจ์ด๊ฐ ๊ฑฐ์ ์์ต๋๋ค. ์ด๋ค ๋ ํผ๋ฐ์ค๋ฅผ ๋ณด๋ฉด emotion
๋ง์ด css props๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ์ฐจ์ด์ ์ ์ด์ผ๊ธฐํ์ง๋ง, ์ง๊ธ ์์ ์์๋ ์์ชฝ ๋ค ์ง์ํ๊ณ ์์ต๋๋ค. ์ฑ๋ฅ ์ญ์ emotion
์ด ์์ ๋ค๋ ๋ถ์์ด ์์ง๋ง styled-components
์ญ์ ์ต์ ํ๊ฐ ์ด๋ฃจ์ด์ง๊ณ ์๊ณ , ์ ์ด์ ๊ทธ๋ ๊ฒ ํฐ ํญ์ผ๋ก ์ฐจ์ด๊ฐ ๋์ง ์๊ธฐ ๋๋ฌธ์, ์์ ์กํ๋ ๊ฒ ์๋ฌด๊ฑฐ๋ ์ฌ์ฉํด๋ ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ ๋ emotion
์ด ๋ ์์ ์ต๋ค๋ ์ด์ ๋ก emotion
์ ๊ณจ๋์ต๋๋ค. styled๋ผ๋ ๋จ์ด๊ฐ ํค๋ณด๋๋ก ์ ์ ์ณ ์ง๋๋ผ๊ตฌ์.
npm i @emotion/styled @emotion/babel-plugin
@emotion/babel-plugin
์ babel์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ง ์ค์น ํ configํ์ผ์ plugins์ @emotion
์ ์ถ๊ฐํด ์ค๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ชจ๋ ์ค๋น๊ฐ ๋๋ฉ๋๋ค. ์ฌ์ฉ ์์๋ฅผ ํ์ธํ๊ธฐ ์ํด ์์ ์ฝ๋๋ฅผ ์ค๋นํ์ต๋๋ค.
export default function TestRecoil() {
const [count, setCount] = useRecoilState(counterState);
return (
<div>
<div>
<button
type="button"
onClick={() => {
setCount(count - 1);
}}
>
-
</button>
<div>{count}</div>
<button
type="button"
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
<button
type="button"
onClick={() => {
setCount(0);
}}
>
์ด๊ธฐํ
</button>
</div>
);
}
์์ฃผ ์ฐธ์ ์ ์๊ฒ ๋ชป์๊ธด ์ปดํฌ๋ํธ๊ตฐ์. ์ด์ ์ด ์ปดํฌ๋ํธ์ ์คํ์ผ์ ์ง์ ํด ์ฃผ๊ฒ ์ต๋๋ค. ํด๋น tsxํ์ผ์ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ถ๊ฐํ์์ต๋๋ค. ๋ชจ๋ ์คํ์ผ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํ๋ ์ ์ฃผ์ํ์ธ์. ์๋๋ฉด ์ด ๋ ์๋ค์ด ์ปดํฌ๋ํธ์ ์ด๋ฆ์ผ๋ก์ ์ทจ๊ธ๋ ์์ ์ด๊ฑฐ๋ ์!
import styled from '@emotion/styled';
...
const WrapperDiv = styled.div`
display: flex;
width: 100%;
flex-direction: column;
background-color: #ff0000;
`;
const ButtonContainer = styled.div`
display: flex;
flex-direction: row;
width: 30%;
background-color: #00ff00;
`;
const ResetButton = styled.button`
width: 50%;
`;
์ด์ ๊ธฐ์กด div์ button ํ๊ทธ๋ค์ ๋ฐ๊ฟ์ค ์๊ฐ์ ๋๋ค.
return (
<WrapperDiv>
<ButtonContainer>
<button
type="button"
onClick={() => {
setCount(count - 1);
}}
>
-
</button>
<div>{count}</div>
<button
type="button"
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</ButtonContainer>
<ResetButton
type="button"
onClick={() => {
setCount(0);
}}
>
์ด๊ธฐํ
</ResetButton>
</WrapperDiv>
);
์ง์! ์คํ์ผ์ด ์ ์ฉ๋์์ต๋๋ค. ๋ชป์๊ธด ๊ฑด ๋๊ฐ์ง๋ง ์ด์จ๋ ์ ์๋๋๋ก ๋ชป์๊ฒผ๋ค์.
๐emotion์ ํน์ง
๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฒ์ ์์์ผ๋, ์์๋์ด์ผ ํ ์ ์ ์ ๋ฆฌํด๋ด ์๋ค.
- styled component์ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํฉ๋๋ค. (CamelCase) ํ์ ์คํฌ๋ฆฝํธ์ ๊ท์น์ด ์์ธ์ธ๋ฐ, ์คํ์ผ์ด ์ง์ ๋ ํ๊ทธ ๊ฐ๊ฐ์ด ํ๋์ ์ปดํฌ๋ํธ๋ก์ ์ทจ๊ธ๋๊ธฐ ๋๋ฌธ์ ์นด๋ฉ ์ผ์ด์ค๋ก ์์ฑํ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ ๋ถ๋ถ์ด ์ผ๊ด์ฑ ์๊ธฐ๋ ํ๊ตฌ์.
- ์คํ์ผ์ ์ง์ ํ๋ ์ฝ๋๋ฅผ ๋ณ๋์ style ํ์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ต๋๋ค. ๋ณ๋์ .ts ํ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ๊ฐ๊ฐ์ ์คํ์ผ์ exportํ๊ณ importํ๋ ๊ฒ์ผ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค. css ํ์ผ๊ณผ์ ์ฐจ์ด๋ ํด๋น ์ปดํฌ๋ํธ์ ์คํ์ผ ์ ์๋ฅผ IDE๊ฐ ๋ฐ๋ก ์ฐพ์์ค ์ ์๋ค๋ ์ ์ด ์์ต๋๋ค. VS Code ๊ธฐ์ค, Ctrl + ํด๋ฆญ์ผ๋ก ๋ฐ๋ก๊ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค!
- scss ๋ฌธ๋ฒ์ ์ง์ํฉ๋๋ค. scss์ nesting ๋ฌธ๋ฒ์ ์ง์ํฉ๋๋ค. backquote ์์์๋ ์์ scss์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค!
- class / id ์ ํ์๋ฅผ ์ง์ํฉ์๋ค! ๊ธฐ๋ณธ์ ์ผ๋ก scss์ ๋ชจ๋ ์ ํ์๋ฅผ ์ง์ํ์ง๋ง, ํด๋์ค ๋ช ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ถ์ฒ๋์ง ์์ต๋๋ค. ์ ์ด์ ์ปดํฌ๋ํธ ์ด๋ฆ ์์ฒด๊ฐ ํ๋์ ์ ํ์๋ก์์ ์ญํ ์ ํ๋๊น์. ์ด๋ ์บ ํผ๋ถ์๊ฒ ๋ค์๋ ๋ด์ฉ์ธ๋ฐ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐพ์ง ๋ชปํ๊ณ ์์ต๋๋ค.
โ ์๋ ๊ทธ๋ผ
.selected
์ฒ๋ผ ์ฌ์ฉํ๋ ํด๋์ค์ ์ญํ ์ ๋๊ฐ ํ๋์? emotion์ ๋๋๊ฒ๋ CSS props๋ฅผ ์ง์ํฉ๋๋ค. ๋ง ๊ทธ๋๋ก React Component์์ ์ฌ์ฉํ๋ Props๋ฅผ ๊ทธ๋๋ก CSS์์ ์ฐธ์กฐํ ์ ์๋ค๋ ๋ป์ ๋๋ค.์์ ๊ฐ์ด props๋ฅผ ์ฐธ์กฐํ์ฌ ์ ๋์ ์ธ ์คํ์ผ ์ง์ ์ด ๊ฐ๋ฅํฉ๋๋ค. ๊น๋ํ์ฃ ? ์คํ์ผ์ props interface์ ์ ์ธ๋์๋๋ฐ ์ค์ ์ฌ์ฉ์์ props ๊ฐ์ ์ง์ ํด์ฃผ์ง ์์ผ๋ฉด ๋นจ๊ฐ ์ค์ ๊ทธ์ด ์ฃผ๊ธฐ๋ ํ๋ต๋๋ค.
๐จํจ๊ป ์ฌ์ฉํ๋ฉด ์ข์ ํ์ฅ
VS Code์๋ emotion๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ข์ ํ์ฅ๋ค์ด ์๋๋ฐ์, ์งค๋งํ๊ฒ ๋ช ๊ฐ์ง ์๊ฐํด ๋ณด๊ณ ์ ํฉ๋๋ค.
Auto Rename Tag
tsx, jsx๋ฅผ ํฌํจํ ํ์ผ์์ HTML ํ๊ทธ๋ฅผ ์์ ํ ๋ ์ด๋ฆฐ ํ๊ทธ์ ๋ซ๋ ํ๊ทธ๋ฅผ ๋์์ ์์ ํด ์ฃผ๋ ํ์ฅ์
๋๋ค. ํนํ div
๊ฐ์ด ์ฌ๋ฌ ๋ฒ ์ฌ์ฉ๋๋ ํ๊ทธ๋ฅผ ์ ํํ ์ง์ ์ฐพ์์ ์๋์ผ๋ก ๊ณ ์ณ์ฃผ๊ธฐ ๋๋ฌธ์ ์คํ์ผ ์ ์ฉ์ด ๋งค์ฐ ํธํด์ง๋๋ค.
Highlight Matching Tag
์ฌ๋ ํ๊ทธ์ ๋ซ๋ ํ๊ทธ๊ฐ ๋์ ๋๋๋ก ๋ฐ์ค๋ก ๊ฐ์กฐํด ์ค๋๋ค. Auto Rename Tag
์ ํจ๊ป ์ฌ์ฉํ๊ธฐ ์ข์ต๋๋ค.
vscode-styled-components
styled.tag
๋ฅผ ํตํด ์คํ์ผ์ ์ง์ ํ๋ฉด css ํ๋กํผํฐ๊ฐ ๋จ์ ๋ฌธ์์ด๋ก ์ธ์๋์ด ์๋์์ฑ์ด ์ง์๋์ง ์๋๋ฐ์, ์ด ํ์ฅ์ ์ฌ์ฉํ๋ฉด ํด๋น ๋ถ๋ถ์ด css ํ๋กํผํฐ๋ก ์ธ์๋์ด css ํ์ผ์ ์์ฑํ๋ฏ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฌด์ง ์ข์ฃ ?
Color Highlight
IDE ์ฐจ์์์ ์์์ hex code์ ๋ํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ง์ํด ์ค๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ง์ํด์ฃผ๊ธด ํ์ง๋ง ์กฐ๊ธ ๋ ํฌ๊ฒ ๋ณด์ฌ์ฃผ๋ ์ ์ด ๋ง์์ ๋ค์์ต๋๋ค. ์คํฌ๋กค์ ์ญ ๋ด๋ฆฌ๋ค๊ฐ ๋ฐ๊ฒฌํ๊ธฐ๊ฐ ์ฝ๊ฑฐ๋ ์.
๐ค์ฐ์๊ฒ์?
CSS-in-JS์ ๊ฐ๋ ๊ณผ ๊ทธ ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ CSS-in-JS๋ ๊ณผ์ฐ ์ ๋ต์ผ๊น์? ์ผ๋ง ์ ์ ์ฌ๋์์ ์ด์ ๋ํ ํฅ๋ฏธ๋ก์ด ๊ธ์ ๋ดค์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ CSS-in-JS์ ํค์ด์ง๋ ์ด์ ๋ผ๋ ์ ๋ชฉ์ ๊ธ์ธ๋ฐ์, Emotion์ ๋ฉ์ธ ๊ธฐ์ฌ์ ์ค ํ ๋ช ์ด ์ด๋ฐ ๊ธ์ ์ผ๋ค๋ ์ ์์ ๊ณ ๋ฏผํด ๋ณผ ๊ฐ์น๋ ์ถฉ๋ถํ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
์ฑ๋ฅ ์ธก๋ฉด์์์ ๋จ์ ๊ณผ React์์ ๋ช ๊ฐ์ง ์ญ์๋์ง ๋ฌธ์ ๊ฐ ์๋ค๊ณ ํ๋๋ฐ, ์ ์์ค์์๋ ๋ฌธ์ ์ํฉ์ ์ฒด๊ฐํ๊ธฐ๋, ์ดํดํ๊ธฐ๋ ์ด๋ ค์ด ๋ด์ฉ์ด์ง๋ง ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ๋ ์์ํฌ๊ฐ ๊ทธ๋ฌํ๋ฏ CSS-in-JS๋ ๊ทธ ์ฅ๋จ์ ์ ์ธ์งํ๋ฉด ์ํฉ์ ๋ฐ๋ผ ์ด๋ ์ ํ์ด ์ต์ ์ธ์ง ๊ฒฐ์ ํ๋ ๋ฐ ๋์์ด ๋ ๊ฑฐ๋ผ ์๊ฐํฉ๋๋ค.
(๋ฒ์ญ) ์ฐ๋ฆฌ๊ฐ CSS-in-JS์ ํค์ด์ง๋ ์ด์
๐Refs.
https://github.com/jsjoeio/styled-components-vs-emotion
styled-components ๊ณผ emotion, ๋๋์ฒด ์ฐจ์ด๊ฐ ๋ญ๊ฐ?
[๋ฒ์ญ] CSS-in-JS์ ๊ดํด ์์์ผ ํ ๋ชจ๋ ๊ฒ
does not exist on type ‘jsx.intrinsicelements’ ๋ฌธ์ ํด๊ฒฐ
(๋ฒ์ญ) ์ฐ๋ฆฌ๊ฐ CSS-in-JS์ ํค์ด์ง๋ ์ด์
ํ์ด ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๊ฐ๋์ ์ ๊ฐ ๊ฒ์ ํ ๋ฒ ์์ด emotion์ ๋ฅ์ํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ์ธ๊ฐ ๋ ํผ๋ฐ์ค๊ฐ ๋์ด์ฃผ์ J154 ์ด์ ์ฑ ์บ ํผ๋๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๐