// styled-components
- css 문법을 사용하며, 결과물을 컴포넌트 형태로 만들어주는 오픈 소스 라이브러리
- 설치
npm i --save styled-components
yarn add styled-components
const 컴포넌트명 = styled.HTML요소명`
color: #6b7280;
`;
<컴포넌트명></컴포넌트명>
- tagged template literal을 사용하여 구성 요소의 스타일을 지정한다.
~ tagged template literal : 템플릿 리터럴 앞에 함수를 두는 형태 > 파라미터로 템플릿 리터럴 사용
const 컴포넌트명 = styled.HTML요소명`
color: ${(props) => props.props명? 값1: 값2};
`;
const 컴포넌트명 = styled.HTML요소명`
color: ${({props명}) => props명? 값1: 값2};
`;
<컴포넌트명 props명={조건}></컴포넌트명>
- 동적으로, 조건적으로 스타일링 하기 위해서는 props를 받아 함수로 처리할 수 있다.
const 컴포넌트명 = styled.HTML요소명`
color: ${($props) => $props.props명? 값1: 값2};
`;
const 컴포넌트명 = styled.HTML요소명`
color: ${({$props명}) => $props명? 값1: 값2};
`;
<컴포넌트명 $props명={조건}></컴포넌트명>
※ 동적으로 속성을 삽입할 때, 기본 내장 속성과 충돌하지 않도록 주의해야 한다.
styled components 스타일링 코드에서만 사용하고 싶은 속성에는 일반적으로 $ 기호를 사용한다.
import { useState } from 'react';
import { styled } from 'styled-components';
const ControlContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 1.5rem;
`;
const Label = styled.label`
display: block;
margin-bottom: 0.5rem;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: ${({ $invalid }) => ($invalid ? '#f87171' : '#6b7280')};
`;
const Input = styled.input`
width: 100%;
padding: 0.75rem 1rem;
line-height: 1.5;
background-color: ${({ $invalid }) => ($invalid ? '#fed2d2' : '#d1d5db')};
color: ${({ $invalid }) => ($invalid ? '#ef4444' : '#374151')};
border: 1px solid ${({ $invalid }) => ($invalid ? '#f73f3f' : 'transparent')};
border-radius: 0.25rem;
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.1),
0 1px 2px 0 rgba(0, 0, 0, 0.06);
`;
export default function AuthInputs() {
return (
<div id="auth-inputs">
<ControlContainer>
<p>
<Label $invalid={emailNotValid}>Email</Label>
<Input
type="email"
$invalid={emailNotValid}
onChange={(event) => handleInputChange('email', event.target.value)}
/>
</p>
<p>
<Label $invalid={passwordNotValid}>Password</Label>
<Input
type="password"
$invalid={passwordNotValid}
onChange={(event) =>
handleInputChange('password', event.target.value)
}
/>
</p>
</ControlContainer>
</div>
);
}
// 자식 요소 선택
- styled.HTML요소로 사용할 때, 해당 요소의 하위에 있는 요소들까지 styling 하고자 할 때, & 기호를 사용한다.
(필수는 x)
const 컴포넌트명 = styled.HTML요소명`
color: #6b7280;
& 하위HTML요소명 {
color: #ffffff;
}
`;
<컴포넌트명>
<하위HTML태그>
</하위HTML태그>
</컴포넌트명>
- pseudo 선택자를 사용할 때는 &뒤에 빈 공간을 남기지 않고 이어서 사용한다.
const 컴포넌트명 = styled.HTML요소명`
color: #6b7280;
& 하위HTML요소명:pesudo선택자 {
color: #ffffff;
}
`;
<컴포넌트명>
<하위HTML태그>
</하위HTML태그>
</컴포넌트명>
import logo from '../assets/logo.png';
import { styled } from 'styled-components';
const StyleHeader = styled.header`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 2rem;
margin-bottom: 2rem;
&:hover {
background-color: white;
}
& img {
object-fit: contain;
margin-bottom: 2rem;
width: 11rem;
height: 11rem;
}
& h1 {
font-size: 1.5rem;
font-weight: 600;
letter-spacing: 0.4em;
text-align: center;
text-transform: uppercase;
color: #9a3412;
font-family: 'Pacifico', cursive;
margin: 0;
}
& p {
text-align: center;
color: #a39191;
margin: 0;
}
@media (min-width: 768px) {
margin-bottom: 4rem;
& h1 {
font-size: 2.25rem;
}
}
`;
export default function Header() {
return (
<StyleHeader>
<img src={logo} alt="A canvas" />
<h1>ReactArt</h1>
<p>A community of artists and art-lovers.</p>
</StyleHeader>
);
}
// extends
- 기존 styled-components를 확장하여 재사용할 수 있다.
const 컴포넌트명1 = styled.HTML요소`
//내용
`;
const 컴포넌트명2 = styled(컴포넌트명1)`
//추가
`;
const Box = styled.div`
background-color: ${({ bgColor }) => bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
border-radius: 50%;
`;
// as
- 확장해서 추가하지 않고, 같은 컴포넌트인데 HTML 요소만 바꾸고 싶을 때 사용한다.
<컴포넌트명 as="바꾸고싶은HTML요소명">
function App() {
return (
<Father>
<Btn as="a" href="/">
Log in
</Btn>
</Father>
);
}
// attiribute
- styled component 자체에 속성을 추가할 수 있다.
const 컴포넌트명 = styled.HTML요소.attrs({ 추가할attribute: 값 })`
//내용
`;
const Input = styled.input.attrs({ required: true })`
background-color: tomato;
`;
// animation
import styled, { keyframes } from 'styled-components';
- keyframes를 추가로 import 해준다.
const 애니메이션명 = keyframes`
from{ }
to { }
`;
- 애니메이션을 정의한다.
const 컴포넌트명 = styled.HTML요소`
animation: ${애니메이션 요소} 기타설정;
`;
- 사용하고자 하는 styled-component의 animation에 ${} 로 추가해준다.
const rotationAnimation = keyframes`
0% {
transform: rotate(0);
border-radius: 0;
}
50% {
transform: rotate(360deg);
border-radius: 100px;
}
100% {
transform: rotate(0);
border-radius: 0;
}
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${rotationAnimation} 1s linear infinite;
span {
font-size: xxx-large;
}
`;
// theme
- 전체적인 테마를 결정한다.
1. 설정
const 테마명 = {
//내용
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ThemeProvider theme={테마명}>
<App />
</ThemeProvider>
</React.StrictMode>,
);
- ThemeProvider로 App 컴포넌트를 감사고, theme property에 원하는 테마변수를 넘겨준다.
const styled-component명 = styled.HTML요소`
property명: ${(props) => props.theme.테마변수의property명};
`;
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ThemeProvider } from 'styled-components';
const lightTheme = {
textColor: '#111',
backgroundColor: 'whitesmoke',
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
);
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
background-color: ${(props) => props.theme.backgroundColor};
`;
const Title = styled.h1`
color: ${(props) => props.theme.textColor};
`;
'클라이언트 > React' 카테고리의 다른 글
[리액트(React)] CSS 스타일링 및 동적 스타일링 (0) | 2024.01.18 |
---|---|
[리액트(React)] React 18 버전 변경 및 추가 사항 (0) | 2024.01.11 |
[리액트(React)] Context API (0) | 2024.01.09 |
[리액트(React)] Composition (0) | 2024.01.08 |
[리액트(React)] Form (0) | 2024.01.06 |