styled-components 정리

김대운·2022년 9월 28일
0

React

목록 보기
1/1
post-thumbnail

styled-components

1. 설치

1-1. 설치

$ npm i styled-components

그리고 이걸 styled라는 이름으로 가져와서 사용

import styled from 'styled-components';

유의할 점 세가지

  1. 컴포넌트 이름은 대문자로 시작
  2. styled 뒤에 사용해야 할 HTML 태그명 입력
  3. 백틱(``)으로 감싸서 스타일시트 작성

컴포넌트 단위이기 때문에 컴포넌트 내에 컴포넌트를 넣을 수도 있고,

sass의 중첩 문법이나 부모 선택 참조자 &를 사용할 수도 있어요!

뿐만 아니라 다른 컴포넌트를 ${}로 데려와 하위에 작성할 수도 있고요.

import styled from 'styled-components';
 
const Title = styled.div`
  color: darkolivegreen;
 
  h1 {
    font-size: 30px;
    margin: 0 0 10px 0;
  }
`;
 
const Notice = styled.div`
  padding: 20px;
  border: 2px solid #aaa;
 
  ${Title}:hover {
    color: crimson;
  }
`;
 
const Button = styled.button`
  display: block;
  padding: 6px 10px;
  color: #fff;
  font-size: 18px;
  border-radius: 3px;
  background-color: crimson;
  border: 0;
 
	&:hover {
    background-color: teal;
  }
`;
 
function App() {
  return (
		<div>
      <Notice>
        <Title>
          <h1>아아 공지를 읽으세요 📢</h1>
          <h2>작성자: nykim</h2>
        </Title>
        <Button>확인</Button>
      </Notice>
    </div>
  );
}
 
export default App;

1-2. 확장하기

한편, 컴포넌트를 확장해서 쓸 수도 있어요.

Sass의 @mixin은 공통 속성을 정의하고 인자로 스타일을 살짝 다르게 설정해 줄 수 있었는데,

이와 유사하게 스타일드 컴포넌트에서도 props로 이래라저래라 해줄 수 있습니다

import styled from 'styled-components';
 
const Button = styled.button`
  background-color: ${(porps) => porps.bgColor || 'lightgray' };
  display: block;
  // ...
`;
 
function App() {
  return (
    <div>
      <Button bgColor="skyblue">확인</Button>
      <Button bgColor="salmon">취소</Button>
    </div>
  );
}
 
export default App;

그럼 props로 bgColor가 있을 경우 그 값이 적용되고, 아니라면 ‘lightgray’ 값이 적용 됩니다.

이렇게 하면 우리는 컴포넌트내 클래스를 전혀 달지 않았음에도 불구하고, 리액트에서 알아서 클래스네임을 각각 적용해줍니다.

1-2-1. Sass의 @extend

새로운 컴포넌트를 만들 때, 거기에 쓰일 기본 속성들을 다른 스타일드 컴포넌트로부터 확장해서 쓸 수 있습니다.

사용법은 간단합니다. styled 뒤에 점 대신 괄호()로 기본형이 될 컴포넌트를 넣습니다.

import styled from 'styled-components';
 
const Button = styled.button`
	//...
`;
 
const FullButton = styled(Button)`
  width: 100%;
  border-radius: 4px;
`;
 
function App() {
  return (
    <div>
      <FullButton bgColor="skyblue">확인</FullButton>
      <Button bgColor="salmon">취소</Button>
    </div>
  );
}
 
export default App;

1-3. 애니매이션 사용하기

스타일드 컴포넌트 내 애니메이션을 적용하려면 keyframes를 가져와야 합니다.

import styled, { keyframes } from "styled-components";

그런 다음 keyframes``; 으로 애니메이션을 작성하고, ${} 으로 가져와서 사용합니다.

const animation = keyframes`
  50% {
    transform: scale(1.3);
  }
`;
 
const FullButton = styled(Button)`
  width: 100%;
  border-radius: 4px;
  animation: ${animation} 1s infinite;
`;

2. Theme 적용하기

{ ThemeProvider } 를 활용해 스타일에 ‘테마’를 적용해 봅시다.

무슨 테마를 쓸 것인가는 테마를 적용할 컴포넌트의 상위(index.js)에서 지정해 주면 됩니다.

/* index.js */
 
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from 'styled-components';
import App from './App';
 
const darkTheme = {
  textColor: 'whitesmoke',
  backgroundColor: '#111'
};
 
const lightTheme = {
  textColor: '#111',
  backgroundColor: 'whitesmoke'
};
 
ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider Theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

App이 ThemeProvider 아래에 있기 때문에 darkTheme 또는 whiteTheme의 속성에 접근할 수 있습니다.

이미 Theme={darkTheme}를 적용해놨기 때문에, backgroundColor 는 #111 값이 됩니다.

	
const Title = styled.div`
  color: ${(props) => props.theme.textColor};
`;
 
const Notice = styled.div`
  background-color: ${(props) => props.theme.backgroundColor};
`;

만약 새롭게 pastelTheme를 추가하고 싶다면, 동일하게 객체를 만들어주고 Theme={} 부분을 바꿔주면 됩니다.

const pastelTheme = {
  textColor: 'lightpink',
  backgroundColor: 'beige'
};
 
ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={pastelTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

3. 응용하기

3-1. 공통 css 적용하기

CSS 초기화 또는 통일화를 위해 reset.css나 normalize.css를 쓰곤 하는데 스타일드 컴포넌트에서도 관련 패키지를 제공하고 있습니다.

한편 전역으로 적용되는 CSS(common.css 등)가 필요하다면 스타일드 컴포넌트에서 제공하는 { createGlobalStyle } 을 사용합니다.

reset이나 normalize를 불러오고 ${} 를 이용해 쓱 넣어줄 수도 있겠죠.

/* GlobalStyle.js */
 
import { createGlobalStyle } from 'styled-components';
import Normalize from 'styled-normalize';
 
const GlobalStyle = createGlobalStyle`
  ${Normalize};
 
  * {
    margin: 0;
    padding: 0;
  }
 
  body {
    background-color: #f0f0f0;
  }
`;
 
export default GlobalStyle;

전역으로 적용될 스타일을 작성하고 export 한 다음, 상위 컴포넌트에 위치시킵니다.

/* index.js */
 
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from 'styled-components';
import GlobalStyle from './GlobalStyle';
import App from './App';
 
const darkTheme = {
  textColor: 'whitesmoke',
  backgroundColor: '#111'
};
 
const lightTheme = {
  textColor: '#111',
  backgroundColor: 'whitesmoke'
};
 
const pastelTheme = {
  textColor: 'lightpink',
  backgroundColor: 'beige'
};
 
ReactDOM.render(
  <React.StrictMode>
    <GlobalStyle />
    <ThemeProvider theme={pastelTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

참고

0개의 댓글