npm i styled-components를 입력하여 설치한다.
import styled from "styled-components";
사용할때 반드시 import를 해주자
예를 들어 이런 코드가 있다고 해보자.
<div style={{ display: "flex" }}>
<div style={{ backgroundColor: "teal", width: 100, height: 100 }}></div>
<div style={{ backgroundColor: "tomato", width: 100, height: 100 }}></div>
</div>
이 코드를 Styled Component 로 정리해보자
다음 선언을 할땐
const Father=styled.div``;
styled뒤에 사용하고자하는 태그와 백틱 사이에 css코드를 넣는 형식으로 사용한다.
text에 css를 넣고 싶을땐 다음과 같이 하자
const Text = styled.span`
color: white;
`;
styled Component를 사용하면 다음과 같이 정리된다.
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;
`;
const Text = styled.span`
color: white;
`;
function App() {
return (
<Father>
<BoxOne>
<Text>Hello</Text>
</BoxOne>
<BoxTwo />
</Father>
);
}
export default App;
<div>
투성이인 이세계에 구원이 있으랴
그런데 위의 코드에서 BoxOne과 BoxTwo는 background-color를 제외하고는 같은 코드다
이를 해결해보자
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 Text = styled.span`
color: white;
`;
function App() {
return (
<Father>
<Box bgColor="teal" />
<Box bgColor="tomato" />
</Father>
);
}
export default App;
BoxTwo를 없애고 Box로 통일 시켰다 그다음 컴포넌트에서 색을 따로 지정하고 styled.div 쪽 background-color에서 props로bgColor를 받게 했다.
또 이러한 사용법도 있다.
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
border-radius:50px
`
위의 Box의 모든 내용을 들고와서 border-radius만 추가하는 형식이다
너무 좋아 이게 바로 styled component의 확장이다.
ASS..가 아니라 As
컴포넌트의 태그를 바꾸고 싶은데 스타일은 바꾸고 싶지 않을때 어떤게 해야할까?
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;
`;
const Link = styled(Btn) ``
function App() {
return (
<Father>
<Btn>Log in</Btn>
</Father>
);
}
export default App;
여기 평범함(버튼)이 있다.
근데 다음에 만들 컴포넌트에선 styled를 사용하되 butten 태그를 사용 하고 싶지 않다.
<Btn as="a">Log in</Btn>
짜잔 as를 사용하면 스타일은 사용하면서도 내가 원하는 태그로 지정이 된다.
또 다른 트릭이 있는데 attrs를 이용한 트릭이다.
만약 우리가 <Input>
이 쥰내 많이 필요한데 이 input에 required속성을 넣는다고 가정해보자
input마다 다 넣고 있을수는 없자나.
그래서 우리는 styled component를 이용해서 속성을 지정하는 방법을 배우겠다.
const Input = styled.input.attrs({required:true})`
background-color: tomato;
`
쥰내 쉽지?
다음은 animation이다.
import styled, { keyframes } from "styled-components";
const Wrapper = styled.div`
display: flex;
`;
const animation = 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: tomato;
animation: ${animation} 1s linear infinite;
`;
function App() {
return (
<Wrapper>
<Box />
</Wrapper>
);
}
export default App;
import로 styled 옆에 {keyframes}를 추가해주고
const animation = keyframes`
0%{
transform: rotate(0deg);
border-radius:0px ;
}
50%{
border-radius:100px ;
}
100%{
transform: rotate(360deg);
border-radius:0px ;
}
`;
다음과 같이 한다.
gif를 딸만큼의 열정은 없어서 화면은 첨부하지 않겠다.
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${animation} 1s linear infinite;
`;
<Wrapper>
<Box>
<span>😊</span>
</Box>
</Wrapper>
다음은 셀렉터에 대해서 알아보자
애니메이션 안에 이모지를 넣어봤다. 근데 이 이모지의 크기를 키우고 싶을때 ?
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${animation} 1s linear infinite;
span {
font-size: 36px;
}
`;
컴퍼넌트안에 span이란 target을 설정해서 따로 설정해줄수있따. 으메이징
근데 만약에 니가 span이라는 태그에 의존하고 싶지 않을때 우리는 다른 방법을 사용할 수 있다.
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${animation} 1s linear infinite;
${Emoji} {
&:hover {
font-size: 45px;
}
}
`;
이렇게 만약 이렇게되면 return쪽 컴포넌트에서 as로 p를 지정하든 span을 지정하든 상관없다
이미 Emoji라는 컴포넌트가 타겟팅 되고있으니까
마지막으로
Theme에 대해서 배워보고자한다.
Theme라고하면 뭐 여러가지가 있겠지만 여기선 dark/light 모드다.
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")
);
index페이지에 다음과 같이 코드를 작성해준다.
ThemeProvider를 import해 준뒤 다크모드와 라이트모드를 선언해주고 글씨색과 배경색을 지정해 주었다.
App 을 감싸는 ThemeProvider 는 하나의 prop을 받는데 이게 darkTheme와 lightTheme다
다음 app.js로 넘어가서
import styled, { keyframes } from "styled-components";
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};
`;
function App() {
return <Wrapper>
<Title>Hello</Title>
</Wrapper>;
}
export default App;
앞서 index에서 설정한 theme는
{(props) => props.theme.backgroundColor};
처럼 컴포넌트로 전달할수도 있다.