설치
npm i styled-components
tip: vscode-styled-components
vscode extension인 vscode-styled-components를 받으면 자동 완성 및 하이라이트 기능 제공
without styled-components
function App() {
return (
<div style={{ display: "flex" }}>
<div style={{ backgroundColor: "teal", width: 100, height: 100 }}></div>
<div style={{ backgroundColor: "tomato", width: 100, height: 100 }}></div>
</div>
);
}
export default App;
with styled-components
- styled 뒤에 속성 값을 back tick 사이에 입력
- back tick 안에 들어간 내용은 일반 css로 작성
- 실제 페이지에서 검사도구로 확인할 경우, 임의의 class 이름이 부여된 것을 확인 가능
import styled from "styled-components";
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;
`;
function App() {
return (
<Father>
<BoxOne />
<BoxTwo />
</Father>
);
}
export default App;
Problem
styled-components내에 중복되는 부분을 어떻게 효율적으로 작성할 수 있을까?
Scratch1; component에 props 받기
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
function App() {
return (
<Father>
<Box bgColor="teal" />
<Box bgColor="tomato" />
</Father>
);
}
export default App;
```
Scratch 2; 기존의 styled-component 상속
상속 전
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
border-radius: 9999px;
`;
function App() {
return (
<Father>
<Box bgColor="teal" />
<Circle bgColor="tomato" />
</Father>
);
}
export default App;
상속 후: Cicle에서 기존 Box를 상속 받음
import styled from "styled-components";
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: 9999px;
`;
function App() {
return (
<Father>
<Box bgColor="teal" />
<Circle bgColor="tomato" />
</Father>
);
}
export default App;
Scratch3; as
as는 기존의 만들어진 styled-components를 html tag만 변경하여 사용할 수있게 해준다
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Btn = styled.button`
color: white;
background-color: tomato;
border: 0;
border-radius: 15px;
`;
function App() {
return (
<Father>
<Btn>Log-in</Btn>
<Btn as="a">Log-in</Btn>
</Father>
);
}
export default App;
Scratch 4; attrs
attrs를 사용하여 각 styled-components에 속성 부여를 해준다
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Input = styled.input.attrs({ required: true, minLength: 10 })`
background-color: tomato;
`;
function App() {
return (
<Father>
<Input />
<Input />
<Input />
<Input />
</Father>
);
}
export default App;
keyframe
keyframe을 사용한 애니메이션 적용 예시
import styled, { keyframes } from "styled-components";
const Wrapper = styled.div`
display: flex;
`;
const rotationAnimaiton = keyframes`
0% {
transform: rotate(0deg);
border-radius: 0px;
}
50% {
transform: rotate(720deg);
border-radius: 100px;
}
100% {
transform: rotate(0deg);
border-radius: 0px;
}
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: salmon;
animation: ${rotationAnimaiton} 1s linear infinite;
`;
function App() {
return (
<Wrapper>
<Box />
</Wrapper>
);
}
export default App;
Pseudoelements, pseudoselectors, and nesting
styled-components 안에서 일반 html tag를 선택할 수 있음
styled-components 안에서 pseudo selector를 선택할 수 있음
import styled from "styled-components";
const Wrapper = styled.div`
display: flex;
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: salmon;
display: flex;
justify-content: center;
align-items: center;
span {
font-size: 36px;
&:hover {
font-size: 72px;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<span>🤪</span>
</Box>
</Wrapper>
);
}
export default App;
styled-components 안에서 styled-components를 선택할 수도 있음
import styled, { keyframes } from "styled-components";
const Wrapper = styled.div`
display: flex;
`;
const rotationAnimaiton = keyframes`
0% {
transform: rotate(0deg);
border-radius: 0px;
}
50% {
transform: rotate(360deg);
border-radius: 100px;
}
100% {
transform: rotate(0deg);
border-radius: 0px;
}
`;
const Emoji = styled.span`
font-size: 36px;
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: salmon;
display: flex;
justify-content: center;
align-items: center;
animation: ${rotationAnimaiton} 1s linear infinite;
${Emoji} {
&:hover {
font-size: 72px;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<Emoji>🤪</Emoji>
</Box>
</Wrapper>
);
}
export default App;
theme
- 기본적으로 모든 색상을 가지고 있는 object
- local estate management와 응용하면 다크모드 구현 가능
- App을 ThemeProvider로 감싸줌
- theme 간의 property 이름은 같아야함
// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { ThemeProvider } from "styled-components";
import App from "./App";
const darkTheme = {
textColor: "whitesmoke",
backgroundColor: "#111",
};
const lightTheme = {
textColor: "#111",
backgroundColor: "whitesmoke",
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
);
ThemeProvider의 값에 접근 가능
// App.js
import styled from "styled-components";
const Wrapper = styled.div`
background-color: ${(props) => props.theme.backgroundColor};
`;
const Title = styled.h1`
color: ${(props) => props.theme.textColor};
`;
function App() {
return (
<Wrapper>
<Title>Title</Title>
</Wrapper>
);
}
export default App;
'React' 카테고리의 다른 글
[React] 가상화폐시세 사이트 1 - CSS reset (0) | 2023.08.29 |
---|---|
[React] TypeScript (0) | 2023.08.17 |
[React 기초] 08. 예제 - Movie info (0) | 2023.08.10 |
[React 기초] 07. 예제 - Coin tracker (0) | 2023.08.10 |
[React 기초] 06. 예제 - Todo List (0) | 2023.08.10 |