[CSS in JS] Styled-Components란?
Styled-Components란?
CSS보다 더 강력한 추상화로 자바스크립트를 사용해 스타일을 선언하고 유지보수가 가능하게 해주는 대표적인 CSS-in-JS 라이브러리다. 컴포넌트 단위로 추상화되어 모듈성을 갖는다. CSS는 명시적 정의가 없어서 부모 요소에서 자동으로 상속되는 속성이 있지만 CSS-in-JS의 경우 부모 요소 속성이 상속되지 않으므로 진정한 분리 법칙을 따른다.
App.js
import "./App.css";
import { Fragment } from "react";
function App() {
return (
<div className="App">
<Fragment>
<button className="button button--success">Hello</button>
<button className="button button--danger">Hello</button>
</Fragment>
</div>
);
}
App.css
.button{
border-radius: 50px;
padding: 5px;
min-width: 120px;
color: white;
font-weight: 600;
-webkit-appearance: none;
cursor: pointer;
}
.button:active,
.button:focus {
outline: none;
}
.button--success{
background-color:#2ecc71;
}
.button--danger {
background-color: #e74c3c;
}
CSS파일을 별도로 두어 import해오는 고전적인 방식이다.
Styled-Components 적용하기
그럼 이제 styled-components를 이용해보자.
yarn add styled-components
App.js (App.css가 필요없다)
import styled from 'styled-components';
function App() {
return (
<div className="App">
<Container>
<Button success>Hello</Button>
<Button danger>Hello</Button>
</Container>
</div>
);
}
const Button = styled.button`
border-radius: 50px;
padding: 5px;
min-width: 120px;
color: white;
font-weight: 600;
-webkit-appearance: none;
cursor: pointer;
&:active,
&:focus {
outline: none;
}
background-color: ${props => props.danger ? "#e74c3c" : "#2ecc71"}
`;
export default App;
createGlobalStyle, withComponent(extend), keyframes
App.js
import styled, { createGlobalStyle, css, keyframes } from 'styled-components';
// 전역스타일
const GlobalStyle = createGlobalStyle`
body{
padding:0;
margin:0;
}
`;
function App() {
return (
<div className="App">
<Container>
<GlobalStyle />
<Button success>Hello</Button>
<Button danger rotationTime={5}>Hello</Button>
<Anchor href="http://google.com">Go to google</Anchor>
</Container>
</div>
);
}
const Container = styled.div`
height:100vh;
width:100%;
background-color:#FBD786;
`
const Button = styled.button`
border-radius: 50px;
border: none;
padding: 5px;
min-width: 120px;
color: white;
font-weight: 600;
-webkit-appearance: none;
cursor: pointer;
&:active,
&:focus {
outline: none;
}
background-color: ${props => (props.danger ? "#e74c3c" : "#2ecc71")};
${props => {
if(props.danger){
return css`animation: ${rotation} ${props.rotationTime}s linear infinite`;
}
}};
`;
// extend
const Anchor = styled(Button.withComponent("a"))`
text-decoration:none;
`;
// Animations
const rotation = keyframes`
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
`;
export default App;
createGlobalStyle: 어플리케이션에 전체적으로 적용하고 싶은 속성들이 있을 때
styled(컴포넌트명.withComponent("a")): extend처럼 그대로 상속하고 싶을 때
keyframes: 애니메이션을 이용할 때 css와 함께 써준다
attrs, mixin
App.js
import styled, { createGlobalStyle, css } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body{
padding:0;
margin:0;
}
`;
// mixin 생성
const awesomeCard = css`
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0 , 0, 0, 0.08);
background-color: white;
border-radius: 10px;
padding: 20px;
`;
// Attributes
const Input = styled.input.attrs({
required: true
})`
border: none;
${awesomeCard}; // mixin 적용
`;
function App() {
return (
<div className="App">
<Container>
<GlobalStyle />
<Input placeholder="입력하세요."/>
</Container>
</div>
);
}
const Container = styled.div`
height:100vh;
width:100%;
background-color:#FBD786;
`;
export default App;
attrs: Attributes 속성을 부여하고 싶을 때
mixin: CSS 그룹화하여 여러 곳에서 쓰고 싶을 때
theme, nesting
theme.js
const theme = {
mainColor: "#74b9ff",
dangerColor: "#ff7675",
successColor: "#55efc4"
}
export default theme;
App.js
import styled, { createGlobalStyle, ThemeProvider } from 'styled-components';
import theme from './theme';
const GlobalStyle = createGlobalStyle`
body{
padding:0;
margin:0;
}
`;
function App() {
return (
<div className="App">
<ThemeProvider theme={theme}> // theme
<Container>
<GlobalStyle />
<Form />
</Container>
</ThemeProvider>
</div>
);
}
const Card = styled.div`
background-color: ${props => props.theme.dangerColor}; // theme 적용
`;
const Container = styled.div`
height:100vh;
width:100%;
background-color: ${props => props.theme.successColor};
// nesting
${Card}{
background-color: blue;
}
`
const Button = styled.button`
border-radius:30px;
border:none;
padding:25px 15px;
background-color: ${props => props.theme.mainColor};
`;
const Form = () => (<Card><Button>Hello</Button></Card>)
export default App;
theme: Redux처럼 글로벌하게 색상의 정의가 필요할 때
nesting: 특정 부모 컴포넌트에서 자식 컴포넌트 스타일 속성을 부여하고 싶을 때
해당 소스코드
github.com/ianlee92/Styled-Components-practice
ianlee92/Styled-Components-practice
Contribute to ianlee92/Styled-Components-practice development by creating an account on GitHub.
github.com