Styled-components
๋?
JS ๋ด์์ CSS ์ฝ๋๋ฅผ ์ ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ. ๋ฆฌ์กํธ๋ก ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ๊ต์ฅํ ๋ง์ ํ์ด์ง ํ์ผ๋ค๊ณผ ํ๊ทธ๋ค์ด ์๊ธธ ์๋ฐ์ ์๋๋ฐ, CSS ํ์ผ์ ๋ฐ๋ก ์ถ๊ฐํ๊ฑฐ๋ Class name์ ๊ณ ๋ฏผํ์ง ์์๋ ๋๋ฏ๋ก ๋งค์ฐ ํธ๋ฆฌํ๋ค. โจ
npm install styled-components
yarn add styled-components
์ค์น ํ ์ฌ์ฉํ๊ณ ์ ํ๋ JS ํ์ผ ๋ด์
๐๐ป ย import styled from 'styled-components';
const (์ฌ์ฉํ ์ปดํฌ๋ํธ๋ช
) = styled.(ํ๊ทธ๋ช
)`
CSS code ~ ..
โ CSS ์ฝ๋๋ ๊ผญ ๋ฐฑํฑ ``์ผ๋ก ๊ฐ์ธ์ค์ผ ํ๋ค. ๋ํ ์ปดํฌ๋ํธ ์ด๋ฆ์ด๊ธฐ ๋๋ฌธ์ ์์์ ๋๋ฌธ์๋ก!
import styled from "styled-components";
function App() {
const Father = styled.div`
display: flex;
`;
const BoxOne = styled.div`
background-color: teal;
width: 100px;
height: 100px;
`;
const BoxTwo = styled.div`
background-color: tomato;
width: 100px;
height: 100px;
`;
const Text = styled.span`
color: white;
`;
return (
<Father>
<BoxOne>
<Text>Hello</Text>
</BoxOne>
<BoxTwo />
</Father>
);
}
export default App;
์ถ๋ ฅ ํ๋ฉด
์ ์ฝ๋๋ ํ๋ฉด๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ค. ๊ธฐ์กด์ CSS ํ์ผ์ ์ถ๊ฐํด์ style์ ์ฃผ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ์ง๊ด์ ์ด๊ณ ํ๊ทธ์ ์ค๋ณต์ฑ์ด ์์ด์ง๋ฏ๋ก ๊น๋ํด์ง๋ค! ๋ํ ์ปดํฌ๋ํธ๋ค์ ์ฌ์ฌ์ฉํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ฏ๋ก, ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๋ค.
๐ก ์ ์ฝ๋์ BoxOne๊ณผ BoxTwo๋ background-color
๋ง ๋ค๋ฅธ ์ฌ์ค์ ๊ฑฐ์ ๊ฐ์ ์ฝ๋์ด๋ค. ์ด ์ฝ๋๋ค์ ์ข ๋ ๊ฐ๊ฒฐํ๊ณ ์ค๋ณต ์์ด ์์ฑํ ์๋ ์์๊น?
const Father = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
border-radius: 50px;
`;
function App() {
return (
<Father>
<Box bgColor="teal" />
<Circle bgColor="tomato" />
</Father>
);
}
๋ค์๊ณผ ๊ฐ์ด ์์ ํ์ฌ, ๊ฐ ์ปดํฌ๋ํธ์ bgColor
๋ผ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ์ด ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฐฐ๊ฒฝ์์ ์ ์ฉํ ์ ์๋๋ก ํจ! ๋ค์ํ ๊ฐ๋ค์ props
๋ก ๋๊ฒจ์ฃผ์ด ์กฐ๊ฑด๋ถ ์คํ์ผ๋ง์ด ๊ฐ๋ฅํ๋ค. ๋ํ Box ์ปดํฌ๋ํธ์ border-radius
์์ฑ์ ์ถ๊ฐํ์ฌ Box ์ปดํฌ๋ํธ๋ฅผ ํ์ฅํ Circle ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ ์ ์๋ค.
์ถ๋ ฅ ํ๋ฉด
๐ก ์ด๋ค ์ปดํฌ๋ํธ์ ์คํ์ผ์ ๊ทธ๋๋ก, ํ๊ทธ๋ช ๋ง์ ๋ฐ๊พธ์ด ์ฌ์ฉํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
< ์ปดํฌ๋ํธ๋ช as = "์ํ๋ ํ๊ทธ๋ช " />
const Btn = styled.button`
color: white;
background-color: tomato;
border: 0;
border-radius: 15px;
`;
function App() {
return (
<>
<Btn>Log in</Btn>
<Btn as="a" href="/">
Log in
</Btn>
</>
);
}
export default App;
๐ญ ์์ฑ์ ์ค ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฌ์ฉํ ๋, ์์ฑ์ ์ปดํฌ๋ํธ๋ง๋ค ์ ์ฉํด์ฃผ์ด์ผ ํจ. ๐คจ Attrs๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์ค๋ณต ์ฝ๋๋ฅผ ์ค์ผ ์ ์๋ค.
const (์ฌ์ฉํ ์ปดํฌ๋ํธ๋ช ) = styled.(ํ๊ทธ๋ช ).attrs( {์ ์ฉํ๋ ค๋ ์์ฑ} )``
const Father = styled.div`
display: flex;
`;
const Input = styled.input.attrs({ required: true })`
background-color: tomato;
`;
function App() {
return (
<Father as="header">
<Input />
<Input />
<Input />
<Input />
<Input />
</Father>
);
}
๐๐ปย required: true
์์ฑ์ ์ผ์ผํ ๋ถ์ฌํ์ง ์์๋ ๋จ!
๐ก ์ ๋๋ฉ์ด์ ์ ์ฉํ๊ธฐ
import styled, { keyframes } from "styled-components";
const rotationAnimation = keyframes`
0% {
transform:rotate(0deg);
border-radius:0px;
}
50% {
border-radius:100px;
}
100%{
transform:rotate(360deg);
border-radius:0px;
}
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: lightblue;
display: flex;
justify-content: center;
align-items: center;
animation: ${rotationAnimation} 1s linear infinite;
span {
font-size: 36px;
&:hover {
font-size: 48px;
}
&:active {
opacity: 0;
}
}
`;
๐๐ปย animation: ${keyframes๋ก ์ ์ํ ์คํ์ผ ์ปดํฌ๋ํธ๋ช } ์ผ๋ก ์ ๋๋ฉ์ด์ ์ ์ฉ ๊ฐ๋ฅํ๋ค.
function App() {
return (
<Wrapper>
<Box>
<span>๐ฌ</span>
</Box>
</Wrapper>
โ Box๋ผ๋ ์คํ์ผ ์ปดํฌ๋ํธ ๋ด์ ์คํ์ผ ์ปดํฌ๋ํธ๊ฐ ์๋ ์์๋ ์ ํ์๋ก ์ง์ ํ์ฌ ์คํ์ผ๋ง์ด ๊ฐ๋ฅํจ!
&:
: ์๊ธฐ ์์ ์ ์ง์ ํ๋ ์ ํ์.(ํ๊ทธ๋ช
)
: ํด๋น ์คํ์ผ ์ปดํฌ๋ํธ ๋ด์ ํ๊ทธ๋ฅผ ์ง์ ํ๋ ์ ํ์.${์คํ์ผ ์ปดํฌ๋ํธ๋ช
}
: ํด๋น ์คํ์ผ ์ปดํฌ๋ํธ ๋ด์ ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ์ง์ ํ๋ ์ ํ์. ์ถ๋ ฅ ํ๋ฉด
๐ก ๋คํฌ ๋ชจ๋, ๋ผ์ดํธ ๋ชจ๋ ํ ๋ง ๋ณํ ๋ฑ์ ์ฌ์ฉํ๋ theme. ๊ฐ์ฒด ํ์์ผ๋ก index.js์ import ํ์ฌ ๋ชจ๋ ํ์ด์ง์์ ์คํ์ผ์ ๊ฐ์ ธ๋ค ์ฌ์ฉํ ์ ์๋ค.
์ถ์ ์ฌ์ดํธ ๋ง๋ค ๋ ์ฒ์ ์ฌ์ฉํด ๋ดค๋๋ฐ, ํ์ดํฌ๋ผ๋ ์ง ์์ฃผ ์ฌ์ฉ๋๋ ํ ๋ง ์์ด๋ผ๋ ์ง ์ค๋ณต๋๋ ์คํ์ผ๋ค์ ๋ฏธ๋ฆฌ ์ง์ ํด๋๊ณ ๊ฐ๋จํ๊ฒ ๊ฐ์ ธ๋ค ์ธ ์ ์์ด ๋งค์ฐ ํธ๋ฆฌํ์! ๐ฅน
index.js
import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";
const darkTheme = {
textColor: "whitesmoke",
backgroundColor: "#111",
};
const lightTheme = {
textColor: "#111",
backgroundColor: "whitesmoke",
};
ReactDOM.render(
<React.StrictMode>
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById("root")
);
โ
themeProvider
์ props๋ก theme ๋๊ฒจ์ฃผ๊ธฐ!
์ ์ฉ
const Title = styled.h1`
color: ${(props) => props.theme.textColor};
`;
const Wrapper = styled.div`
display: flex;
height: 100vh;
width: 100vw;
justify-content: center;
align-items: center;
background-color: ${(props) => props.theme.backgroundColor};
๐๐ปย ๋คํฌ ๋ชจ๋, ๋ผ์ดํธ ๋ชจ๋๊ฐ props๋ก ๋๊ฒจ์ค theme์ ๋ฐ๋ผ ๊ตฌ๋ถ๋๊ฒ ๋๋ค.