티스토리 뷰
리액트 스타일드 컴포넌트(Styled Components)는 컴포넌트 기반으로 스타일을 정의할 수 있는 CSS-in-JS 라이브러리다.
컴포넌트 기반 스타일링이 가능하고, 속성이나 글로벌 테마 등으로 동적인 스타일링도 가능하다.
고유한 클래스를 생성해서 클래스 중복 등을 방지할 수도 있다.
전역 스타일링을 위한 GlobalStyles.ts 생성
import { createGlobalStyle } from 'styled-components';
import reset from 'styled-reset';
const GlobalStyle = createGlobalStyle`
${reset}
html { ... }
body { ... }
`;
export default GlobalStyles;
GlobalStyle은 프로젝트 전체에 적용할 전역 스타일을 정의하는 데 사용한다.
styled-components 라이브러리를 설치하면 기본적으로 createGlobalStyle 함수를 사용할 수 있다.
CSS Reset이나 글로벌하게 적용될 폰트스타일 등을 지정하면 된다.
스타일드 컴포넌트는 styled-reset이라는 CSS 리셋 라이브러리도 함께 사용할 수 있어,
npm install styled-reset 등으로 별도로 설치해준 다음 import 해서 사용해주면 별도로 reset style을 작성하지 않아도 된다.
최상위 컴포넌트에 GlobalStyles 적용
import React, {ReactElement} from 'react';
import './common/styles/font.css';
import theme from './common/styles/theme';
import GlobalStyles from './common/styles/globalStyles';
import {ThemeProvider} from 'styled-components';
const App = (): ReactElement => {
return (
<>
<GlobalStyles/>
<ThemeProvider theme={theme}>
<PageRouter></PageRouter>
</ThemeProvider>
</>
);
};
export default App;
최상위 컴포넌트에 GlobalStyle을 적용하여 모든 하위 컴포넌트에 전역 CSS 규칙이 적용될 수 있도록 한다.
그리고 styled-components의 테마를 프로젝트 전체에 적용하는 컴포넌트인 ThemeProvider를 적용해준다.
Theme 적용하기
theme를 사용해서 공통으로 사용할 스타일 등을 정의해줄 수 있다.
const theme = {
colors: {
white: '#FFF',
black: '#000',
}
export default theme;
컬러 등을 theme에 추가해서 사용할 수 있다.
스타일 컴포넌트에서 접근하여 사용하는 경우에는
${({ props.theme }) => props.theme.color.black}
이렇게 props를 통해서 접근하여 사용이 가능하다.
타입스크립트에서의 theme 사용
// styled.d.ts
import 'styled-components';
import { Color } from './theme/color';
declare module 'styled-components' {
export interface DefaultTheme {
color: Color;
}
}
styled-components의 테마 타입을 정의하는 타입 선언 파일을 작성할 수 있다.
// theme/index.ts
import { DefaultTheme } from 'styled-components';
import { color } from './color';
const theme: DefaultTheme = {
color,
};
export default theme;
여기서는 테마 객체를 정의하고, 이 객체를 DefaultTheme 타입을 사용하여 설정한다.
// theme/color.ts
export type Color = {
common: {
black: string;
white: string;
red: string;
}
}
export const color: Color = {
common: {
black: '#000';
white: '#FFF';
red: 'FF0000
}
}
예를 들어 컬러를 정의하는 color.ts 를 만들어서, color의 타입을 명시해주고 색상 값들을 color 객체에 정의한다.
그리고 theme/index.ts에서 color 객체를 포함시켜, ThemeProvider를 통해 스타일 컴포넌트에서 사용되도록 할 수 있다.
export const Text = styled.p`
color: ${({ theme }) => theme.color.common.black};
`;
개별 스타일 컴포넌트에서 접근해서 사용할 때는 위와 같은 방식으로 접근해서 사용해주면 된다.
styled-components 작성 방법
import styled from 'styled-components';
export const Text = styled.p`
color: ${({ theme }) => theme.color.common.black};
font-size: 2.4rem;
font-weight: 700;
line-height: 100%;
letter-spacing: -0.5px;
`;
기본적으로 템플릿 리터럴 (`)을 사용해서 스타일을 지정해준다.
styled-components에서의 props 사용
styled-components에서 props를 사용해서 동적 스타일링을 할 수 있다.
export const StyledInput = styled.input`<{
$isError?: boolean;
}>
color: ${({ theme, $isError }) => $isError ? theme.color.common.red : theme.color.common.black};
`
input의 기본 컬러는 black이고, isError라는 props에 해당할 경우에는 컬러를 red로 적용되도록 하려면
위와 같이 props를 적용해주고, 조건문을 사용해서 작성해주면 된다.
export const Box = styled.div<{
$size: 'small' | 'medium' | 'large';
}>`
width: ${(props) => {
switch (props.$size) {
case 'small':
return '30px';
case 'medium':
return '40px';
case 'large':
return '50px';
default:
return '20px';
}
}};
`;
이런 식으로 switch문을 사용해서 조건문을 작성할 수도 있다.
transient props의 사용
styled-components에서는 props를 사용할 때 props의 앞에 $ 기호를 붙이는 방식인 transient props를 사용한다.
스타일 정의에서만 사용되도록 하고 HTML 요소로 전달되지 않도록 하기 위해서 이런 방식을 사용하고 props를 실제 DOM 요소의 속성으로 전달되지 않도록 한다.
이걸 사용하지 않으면 콘솔창에서 '이 props는 스타일 정의하는데만 사용되는데 DOM요소로 직접 전달이 되고 있다'는 대충 그런 내용의 경고 문구가 엄청 뜬다....
스타일드 컴포넌트의 props에는 $를 꼭 붙여주자.
Link 컴포넌트를 styled-components로 스타일링하기
import { Link } from 'react-router-dom';
import styled from 'styled-components';
export const LinkButton = styled(Link)`
....
`;
react-router-dom의 Link 컴포넌트를 스타일링 할 때는 스타일드 컴포넌트 파일에서 Link를 import해서 사용해주면 된다.
마찬가지로 다른 외부 라이브러리의 컴포넌트를 스타일드 컴포넌트로 적용하고자 할 때도 위와 같은 방식을 사용하면 된다.
스타일드 컴포넌트에서 다른 컴포넌트 스타일 재사용하기
예를 들면 부모 컴포넌트에 어떤 클래스가 추가되었을 때
하위의 자식 컴포넌트에 별도의 스타일링을 주고 싶을 때 사용할 수 있는 방법이다.
export const Item = styled.div``;
export const Wrapper = styled.div`
display: flex;
&.active {
${Item} {
color: red;
}
}
`;
부모 컴포넌트인 Wrapper가 있고 그 안에 자식 컴포넌트인 Item이 있다고 할 때,
부모 컴포넌트에 클래스 active가 추가되면 자식 컴포넌트의 스타일링을 변경하고 싶다고 하자.
그럴 때는 위와 같은 방식으로 스타일을 작성해줄 수 있다.
단 재사용하려는 컴포넌트가 반드시 먼저 선언되어 있어야 한다.
예를 들어 위 경우에서 Item 컴포넌트가 Wrapper 컴포넌트보다 나중에 작성되어 있으면,
Block-scoped variable 'Item' used before its declaration. 이라는 오류가 발생하는데
JavaScript의 블록 스코프에서는 변수가 선언되기 전에 참조할 수 없기 때문에 발생하는 오류이다.
가상선택자/가상클래스 사용하기
const ListItem = styled.li`
position: relative;
padding: 10px;
background-color: lightgrey;
border: 1px solid grey;
&:hover {
background-color: darkgrey;
cursor: pointer;
}
&:first-child {
font-weight: bold;
color: blue;
}
&::before {
content: '';
display: block;
.....
}
`;
가상클래스, 가상선택자를 사용하는 경우에는 상위선택자를 사용해서 작성해주면 된다.
애니메이션 사용하기
import { keyframes } from 'styled-components';
const fadeIn = keyframes`
from {
opacity: 0;
}
to {
opacity: 1;
}
`;
const Box = styled.div`
animation: ${fadeIn} 2s ease-in-out;
`;
CSS Keyframes를 styled-components에서 사용하려면
keyframes를 import해서 작성해주면 된다.
'개발 > react' 카테고리의 다른 글
[React] 버튼 클릭 시 특정 영역으로 스크롤 이동 (1) | 2024.09.26 |
---|---|
[styled-components] keyframes 공통으로 사용하기 (0) | 2024.08.29 |
[React] 토글 메뉴 외부 영역 클릭 시 닫기 (0) | 2024.02.20 |
[React] 토글 클릭이벤트 구현 (0) | 2023.07.03 |
[React] 반복문으로 시간이 30분 간격으로 표시된 테이블 구현 (0) | 2023.07.02 |
- Total
- Today
- Yesterday