import
해오지 않은 CSS 파일에서도 같은 클래스 이름이 사용된 부분이 있으면 그곳의 스타일이 함께 적용됨Styled Components는 클래스 이름을 아예 쓰지 않음
CSS 코드로 React 컴포넌트를 바로 만드니까 애초에 클래스 이름이 겹칠 일이 없음
const StyledApp = styled.div`
background-color: #000000;
`;
const Dashboard = styled.div`
font-size: 16px;
`;
function App() {
return (
<StyledApp>
<Dashboard> ... </Dashboard>
</StyledApp>
);
}
shadow20
만을 보고는 이게 어디에서 사용되는 스타일인지 알기 어렵다는 단점이 있음Styled Components에서는 스타일 재사용이 필요한 상황에서 클래스가 아니라 JavaScript 변수를 만듦
JavaScript라서 언제 어디서 쓰고 있는지 에디터를 통해 확인하기 쉽고, 이름을 바꾸거나 삭제를 하는 것도 코드 에디터를 통해 쉽게 할 수 있음
// src/shadows.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);
`;
// src/Card.js
import { shadow20 } from '../shadows';
const Card = styled.div`
${shadow20}
...(다른 CSS 코드)
`;
export default Card;
npm install styled-components
import styled from 'styled-components';
<button>
태그에 스타일을 지정한 컴포넌트를 만드는 코드임styled.tagname
의 tagname
부분에는 스타일을 적용할 HTML 태그 이름을 쓰고, 바로 뒤에 템플릿 리터럴 문법으로 CSS 코드를 적음 const Button = styled.button`
background-color: #6750a4;
border: none;
color: #ffffff;
padding: 16px;
`;
&
는 부모 선택자를 의미함.Button
이라는 클래스 이름을 쓸 때 &: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;
&
와 자손 결합자를 사용하는 경우에는 &
를 생략할 수 있음${Icon}
만 써도 똑같이 동작함 ${Icon} {
margin-right: 4px;
}
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;
`;
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: px
같은 잘못된 CSS 코드를 방지하기 위해서 가능하면 기본 값을 정해주는 게 좋음font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
const Button = styled.button`
...
${({ round }) => round && `
border-radius: 9999px;
`}
`;
border-radius: ${({ round }) => round ? `9999px` : `3px`};
styled()
함수를 사용하면 됨// src/Button.js
import styled from 'styled-components';
const SIZES = {
large: 24,
medium: 20,
small: 16,
};
const Button = styled.button`
background-color: #6750a4;
border: none;
color: #ffffff;
font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
padding: 16px;
${({ round }) =>
round
? `
border-radius: 9999px;
`
: `
border-radius: 3px;
`}
&:hover,
&:active {
background-color: #463770;
}
`;
export default Button;
// src/App.js
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;
TermsOfService
라는 컴포넌트가 있다고 할 때function TermsOfService() {
return (
<div>
<h1>㈜코드잇 서비스 이용약관</h1>
<p>
환영합니다.
<br />
Codeit이 제공하는 서비스를 이용해주셔서 감사합니다. 서비스를
이용하시거나 회원으로 가입하실 경우 본 약관에 동의하시게 되므로, 잠시
시간을 내셔서 주의 깊게 살펴봐 주시기 바랍니다.
</p>
<h2>제 1 조 (목적)</h2>
<p>
본 약관은 ㈜코드잇이 운영하는 기밀문서 관리 프로그램인 Codeit에서
제공하는 서비스를 이용함에 있어 이용자의 권리, 의무 및 책임사항을
규정함을 목적으로 합니다.
</p>
</div>
);
}
export default TermsOfService;
styled()
로 지정한 스타일이 적용되지 않음styled()
함수가 적용될 className에 대한 정보가 없기 때문임import styled from 'styled-components';
import Button from './Button';
import TermsOfService from './TermsOfService';
const StyledTermsOfService = styled(TermsOfService)`
background-color: #ededed;
border-radius: 8px;
padding: 16px;
margin: 40px auto;
width: 400px;
`;
const SubmitButton = styled(Button)`
background-color: #de117d;
display: block;
margin: 0 auto;
width: 200px;
&:hover {
background-color: #f5070f;
}
`;
function App() {
return (
<div>
<StyledTermsOfService />
<SubmitButton>계속하기</SubmitButton>
</div>
);
}
export default App;
className
값을 Prop으로 따로 내려줘야 styled()
함수를 사용할 수 있음function TermsOfService({ className }) {
return (
<div className={className}>
...
</div>
);
}
<div>
태그에 className
을 내려줬기 때문에 styled(TermsOfService)
에서 작성한 코드는 TermsOfService
안에 있는 <div>
태그에 적용됨스타일 상속을 하려면
styled()
함수를 사용하면 되는데,styled.tagname
으로 만든 컴포넌트는styled()
함수로 바로 상속하면 되고, Styled Components를 사용하지 않고 직접 만든 컴포넌트에는 클래스 이름을 내려준 후에styled()
함수로 상속해야 함
// 똑같은 코드를 두번 작성하고 있음
import styled from 'styled-components';
const SIZES = {
large: 24,
medium: 20,
small: 16
};
const Button = styled.button`
...
font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
`;
const Input = styled.input`
...
font-size: ${({ size }) => SIZES[size] ?? SIZES['medium']}px;
`;
// 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}
`;