재사용하는 CSS 코드를 관리할 수 있다.
ex)
shadow.js
import { css } from 'styled-components';
const shadow20 = css`
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);
`;
const shadow40 = css`
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.4);
`;
에서 스타일을 만들고
import { shadow20 } from '../shadows';
const Card = styled.div`
${shadow20}
...(다른 CSS 코드)
`;
export default Card;
이렇게 적용시킬 수 있다.
npm install styled-components
Nesting에서 &는 부모 선택자를 의미한다.
const Button = styled.button`
background-color: #6750a4;
border: none;
color: #ffffff;
padding: 16px;
&:hover,
&:active {
background-color: #463770;
}
`;
다음과 같은 코드에서 &:hover
는 .Button:hover
와 같은 의미이다.
컴포넌트를 선택자로 쓰고 싶을 때는 ${Icon}
과 같이 컴포넌트 자체를 템플릿 리터럴 안에 넣어주면 된다.
import styled from 'styled-components';
import nailImg from './nail.png';
const Icon = styled.img`
width: 16px;
height: 16px;
`;
const StyledButton = styled.button`
background-color: #6750a4;
border: none;
color: #ffffff;
padding: 16px;
& ${Icon} {
margin-right: 4px;
}
&:hover,
&:active {
background-color: #463770;
}
`;
function Button({ children, ...buttonProps }) {
return (
<StyledButton {...buttonProps}>
<Icon src={nailImg} alt="nail icon" />
{children}
</StyledButton>
);
}
export default Button;
Nesting은 다음과 같이 여러 겹으로 할 수도 있다.
const StyledButton = styled.button`
...
&:hover,
&:active {
background-color: #7760b4;
${Icon} {
opacity: 0.2;
}
}
`;
JavaScript 변수를 넣는 것처럼 사용하면 된다.
const SIZES = {
large: 24,
medium: 20,
small: 16
};
const Button = styled.button`
...
font-size: ${SIZES['medium']}px;
`;
함수의 파라미터로 Props를 받고 리턴 값으로 스타일 코드를 리턴하는 것
const SIZES = {
large: 24,
medium: 20,
small: 16
};
const Button = styled.button`
...
font-size: ${(props) => SIZES[props.size]}px;
`;
구조 분해를 하면 아래처럼 쓸 수도 있다.
font-size: ${({ size }) => SIZES[size]}px;
기본 값을 정해주고 싶을 때는 이렇게 쓰면 된다.
font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
const Button = styled.button`
...
${({ round }) => round && `
border-radius: 9999px;
`}
`;
round 값이 참이면 그 뒤의 코드가 실행되고, round가 거짓이면 아무 값도 적용되지 않는다.
border-radius: ${({ round }) => round ? `9999px` : `3px`};
Styled Components로 만들어진 컴포넌트를 상속하려면 styled() 함수를 사용하면 된다.
import styled from 'styled-components';
import Button from './Button';
const SubmitButton = styled(Button)`
background-color: #de117d;
display: block;
margin: 0 auto;
width: 200px;
&:hover {
background-color: #f5070f;
}
`;
function App() {
return (
<div>
<SubmitButton>계속하기</SubmitButton>
</div>
);
}
export default App;
Styled Components는 내부적으로 className을 따로 생성하고 자체적으로 생성된 className이 있는 부분에 styled() 함수의 스타일이 입혀진다.
그런데, JSX 문법으로 직접 만든 컴포넌트는 styled() 함수가 적용될 className에 대한 정보가 없는데요. styled() 함수에서 지정한 스타일이 입혀질 부분이 어딘지 알 수 없으니 스타일이 적용되지 않는다.
Styled Components를 사용하지 않고 직접 만든 컴포넌트는 className 값을 Prop으로 따로 내려줘야 styled() 함수를 사용할 수 있다.
function TermsOfService({ className }) {
return (
<div className={className}>
...
</div>
);
}
반복되는 코드를 한 곳에서 지정하고 여러 군데서 활용하고 싶을 때 css함수를 사용하면 된다.
import styled, { css } from 'styled-components';
const SIZES = {
large: 24,
medium: 20,
small: 16
};
const fontSize = css`
font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
`;
const Button = styled.button`
...
${fontSize}
`;
const Input = styled.input`
...
${fontSize}
`;
Props를 받아서 사용하는 함수가 들어있기 때문에 반드시 css 함수를 사용해야 한다.