- global css
./style.css
와 같이 모두에게 적용되는 css파일을 사용하는 방식- direct 방식
해당html
에 직접 style을 입력하는 방식- module css
각각의 파일에 module css를 생성하여 적용하는 방식. 현재로서는 가장 합리적으로 보이는?
왜냐하면className
을 사용하면 render했을 때 클래스 이름을 랜덤으로 만들어 주기 때문에 겹치는 일이 생기지 않음.
설치
npm i styled-components
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.h1`
color: white;
`;
function App() {
return (
<Father>
<BoxOne>
<Text>HEllo</Text>
</BoxOne>
<BoxTwo></BoxTwo>
</Father>
);
}
export default App;
백틱 사이에 css를 넣어준다.
시멘틱 태그인 것처럼 사용할 수 있기 때문에 가독성이 훨씬 좋다. html
구조를 알아보기 좋고, css스타일을 그대로 사용할 수 있어서 편리해보인다. 심지어 중복을 방지하기 위한 해결방법 또한 마련되어 있다. 이는 props를 통해 가능하다.
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
${}
를 사용하여 props를 받아온다.
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
//Box의 속성들을 기본적으로 가지고 있다.
//추가로 아래와 같이 속성을 더해줄 수 있다.
border-radius: 50px;
`;
만들어둔 styled를 사용하여 속성을 그대로 가져오고 추가할 내용만 더할 수 있다. awsome!
속성을 더 추가하진 않고 태그만 변경하고 싶을 때는
as
를 사용한다.
import styled from 'styled-components';
const Father = styled.div`
display: flex;
`;
const Btn = styled.button`
background-color: tomato;
color: white;
border: 0;
border-radius: 15px;
`;
function App() {
return (
<Father>
<Btn>Log in</Btn>
<Btn
as="a"
href="https://github.com/iteach12/react_master"
target="_blank"
>
Github
</Btn>
</Father>
);
}
export default App;
html 속성을 바로 넣어주기 위해서 attrs를 사용한다.
const Input = styled.input.attrs({ required: true })`
background-color: tomato;
`;
import styled, {keyframes} from 'styled-components';
const rotateAnimation = keyframes`
0% {
transform:rotate(0deg);
border-radius:0px;
}
50% {
transform:rotate(360deg);
border-radius:100px;
}
100%{
transform:rotate(0deg);
border-radius:0px;
}
`;
const Box = styled.div`
background-color: tomato;
width: 200px;
height: 200px;
animation: ${rotateAnimation} 0.2s linear infinite;
`;
styled-components 안에 직접 html 태그를 사용할 수 있다. 모든 컴포넌트를 styled로 하지 않을테니. 일반 태그도 쉽게 삽입할 수 있다.
const Box = styled.div`
background-color: tomato;
width: 200px;
height: 200px;
animation: ${rotateAnimation} 1s linear infinite;
display: flex;
justify-content: center;
align-items: center;
span {
font-size: 30px;
transition: all ease-in 0.2s;
&:hover {
font-size: 45px;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<span>😚</span>
</Box>
</Wrapper>
);
}
특히 &:hover와 같은 방식으로 가상선택자를 넣어줄 수도 있다. 여기서 &기호는 자기 자신을 의미한다.
span {
&:hover {
font-size: 45px;
}
}
span:hover {
font-size: 45px;
}
위와 아래는 동일한 코드이다.
styled-components안에 태그가 아닌 styled-components를 직접 넣을 수도 있다. 이 때는 태그 이름 대신 ${components이름}을 사용하면 된다.
const Emoji = styled.span`
font-size: 30px;
transition: all ease-in 0.2s;
`;
const Box = styled.div`
background-color: tomato;
width: 200px;
height: 200px;
animation: ${rotateAnimation} 1s linear infinite;
display: flex;
justify-content: center;
align-items: center;
${Emoji} {
&:hover {
font-size: 45px;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<Emoji>😚</Emoji>
</Box>
<Emoji>😚</Emoji>
</Wrapper>
);
}
<Box>
바깥에 있는 <Emoji>
는 hover가 적용되지 않는다. hover가 적용되는 <Emoji>
는 <Box>
엘리먼트 안에 있는 <Emoji>
뿐이다.
lightMode, darkMode를 쉽게 변경할 때 사용하면 좋다. 물론, 다양한 theme을 적용하기 위한 것이겠으나. 그럴 일이 많을런지..?
//App.js
const Wrapper = styled.div`
display: flex;
width: 100vw;
height: 100vh;
justify-content: center;
align-items: center;
background-color:${(props) => props.theme.backgroundColor}
`;
//index.js
const darkTheme = {
textColor:"whitesmoke",
backgroundColor:"#111",
}
const lightTheme = {
textColor:"#111",
backgroundColor: "whitesmoke",
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
</React.StrictMode>
);
prop을 불러와서 사용하는 것과 동일하다. 단, darkTheme과 lightTheme을 가지고 다크모드 라이트모드를 구현한다면 두 객체의 구조가 동일해야 한다. 그래야 컴포넌트에서 변경할 일이 없다. 동일한 객체를 생성해두고 theme에 적용하는 것만으로 전체 컴포넌트를 관리한다.