$ npm i styled-components
그리고 이걸 styled라는 이름으로 가져와서 사용
import styled from 'styled-components';
유의할 점 세가지
- 컴포넌트 이름은 대문자로 시작
- styled 뒤에 사용해야 할 HTML 태그명 입력
- 백틱(``)으로 감싸서 스타일시트 작성
컴포넌트 단위이기 때문에 컴포넌트 내에 컴포넌트를 넣을 수도 있고,
sass의 중첩 문법이나 부모 선택 참조자 &
를 사용할 수도 있어요!
뿐만 아니라 다른 컴포넌트를 ${}
로 데려와 하위에 작성할 수도 있고요.
import styled from 'styled-components';
const Title = styled.div`
color: darkolivegreen;
h1 {
font-size: 30px;
margin: 0 0 10px 0;
}
`;
const Notice = styled.div`
padding: 20px;
border: 2px solid #aaa;
${Title}:hover {
color: crimson;
}
`;
const Button = styled.button`
display: block;
padding: 6px 10px;
color: #fff;
font-size: 18px;
border-radius: 3px;
background-color: crimson;
border: 0;
&:hover {
background-color: teal;
}
`;
function App() {
return (
<div>
<Notice>
<Title>
<h1>아아 공지를 읽으세요 📢</h1>
<h2>작성자: nykim</h2>
</Title>
<Button>확인</Button>
</Notice>
</div>
);
}
export default App;
한편, 컴포넌트를 확장해서 쓸 수도 있어요.
Sass의 @mixin은 공통 속성을 정의하고 인자로 스타일을 살짝 다르게 설정해 줄 수 있었는데,
이와 유사하게 스타일드 컴포넌트에서도 props로 이래라저래라 해줄 수 있습니다
import styled from 'styled-components';
const Button = styled.button`
background-color: ${(porps) => porps.bgColor || 'lightgray' };
display: block;
// ...
`;
function App() {
return (
<div>
<Button bgColor="skyblue">확인</Button>
<Button bgColor="salmon">취소</Button>
</div>
);
}
export default App;
그럼 props로 bgColor가 있을 경우 그 값이 적용되고, 아니라면 ‘lightgray’ 값이 적용 됩니다.
이렇게 하면 우리는 컴포넌트내 클래스를 전혀 달지 않았음에도 불구하고, 리액트에서 알아서 클래스네임을 각각 적용해줍니다.
새로운 컴포넌트를 만들 때, 거기에 쓰일 기본 속성들을 다른 스타일드 컴포넌트로부터 확장해서 쓸 수 있습니다.
사용법은 간단합니다. styled 뒤에 점 대신 괄호()로 기본형이 될 컴포넌트를 넣습니다.
import styled from 'styled-components';
const Button = styled.button`
//...
`;
const FullButton = styled(Button)`
width: 100%;
border-radius: 4px;
`;
function App() {
return (
<div>
<FullButton bgColor="skyblue">확인</FullButton>
<Button bgColor="salmon">취소</Button>
</div>
);
}
export default App;
스타일드 컴포넌트 내 애니메이션을 적용하려면 keyframes를 가져와야 합니다.
import styled, { keyframes } from "styled-components";
그런 다음 keyframes``;
으로 애니메이션을 작성하고, ${} 으로 가져와서 사용합니다.
const animation = keyframes`
50% {
transform: scale(1.3);
}
`;
const FullButton = styled(Button)`
width: 100%;
border-radius: 4px;
animation: ${animation} 1s infinite;
`;
{ ThemeProvider } 를 활용해 스타일에 ‘테마’를 적용해 봅시다.
무슨 테마를 쓸 것인가는 테마를 적용할 컴포넌트의 상위(index.js)에서 지정해 주면 됩니다.
/* 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')
);
App이 ThemeProvider 아래에 있기 때문에 darkTheme 또는 whiteTheme의 속성에 접근할 수 있습니다.
이미 Theme={darkTheme}를 적용해놨기 때문에, backgroundColor 는 #111 값이 됩니다.
const Title = styled.div`
color: ${(props) => props.theme.textColor};
`;
const Notice = styled.div`
background-color: ${(props) => props.theme.backgroundColor};
`;
만약 새롭게 pastelTheme를 추가하고 싶다면, 동일하게 객체를 만들어주고 Theme={} 부분을 바꿔주면 됩니다.
const pastelTheme = {
textColor: 'lightpink',
backgroundColor: 'beige'
};
ReactDOM.render(
<React.StrictMode>
<ThemeProvider theme={pastelTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById('root')
);
CSS 초기화 또는 통일화를 위해 reset.css나 normalize.css를 쓰곤 하는데 스타일드 컴포넌트에서도 관련 패키지를 제공하고 있습니다.
한편 전역으로 적용되는 CSS(common.css 등)가 필요하다면 스타일드 컴포넌트에서 제공하는 { createGlobalStyle } 을 사용합니다.
reset이나 normalize를 불러오고 ${} 를 이용해 쓱 넣어줄 수도 있겠죠.
/* GlobalStyle.js */
import { createGlobalStyle } from 'styled-components';
import Normalize from 'styled-normalize';
const GlobalStyle = createGlobalStyle`
${Normalize};
* {
margin: 0;
padding: 0;
}
body {
background-color: #f0f0f0;
}
`;
export default GlobalStyle;
전역으로 적용될 스타일을 작성하고 export 한 다음, 상위 컴포넌트에 위치시킵니다.
/* index.js */
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from 'styled-components';
import GlobalStyle from './GlobalStyle';
import App from './App';
const darkTheme = {
textColor: 'whitesmoke',
backgroundColor: '#111'
};
const lightTheme = {
textColor: '#111',
backgroundColor: 'whitesmoke'
};
const pastelTheme = {
textColor: 'lightpink',
backgroundColor: 'beige'
};
ReactDOM.render(
<React.StrictMode>
<GlobalStyle />
<ThemeProvider theme={pastelTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById('root')
);