Study/React

[React_study] styled-components (CSS in JS)

갈푸라떼 2022. 6. 9. 18:37

* styled-components

- 컴포넌트가 많은 경우 스타일링을 하다보면 불편함이 생긴다.

  • class를 만들고 까먹거나 중복해서 만든경우
  • 갑자기 다른 컴포넌트에 원하지 않는 스타일이 적용되거나
  • CSS 파일이 너무 길어져서 수정이 어렵거게 된다.

이런 경우가 발생 할 수 있다.

 

그래서 스타일을 바로 입혀서 컴포넌트를 만들어버릴 수도 있는

styled-components 라는 라이브러리를 설치하여 이용하면 된다.

 

* styled-components 설치

- 터미널에 아래의 명령어를 입력해주어서 설치한다.

npm install styled-components


- 사용하고 싶은 컴포넌트 상단에 아래의 명령어처럼 import해준다.

import styled from 'styled-components'

* styled-components 기본적인 사용방법

  • 이 라이브러리를 이용하게되면 컴포넌트를 만들 때 스타일을 미리 주입해서 만들 수 있다.
  • 아래의 예시처럼 작성하기
import styled from 'styled-components';

let Box = styled.div`
  padding : 20px;
  color : grey
`;
let YellowBtn = styled.button`
  background : yellow;
  color : black;
  padding : 10px;
`;

function Detail(){
  return (
    <div>
      <Box>
        <YellowBtn>Button</YellowBtn>
      </Box>
    </div>
  )
}
  • <div>를 하나 만들고 싶으면 위의 예시처럼 styled.div라는 걸 사용하면 된다.
  • 다른 마크업도 동일하게 사용하면 된다. ex) styled.p
  • ``backtick 기호를 이용해서 CSS 스타일을 넣을 수 있다.
  • 그럼 그 자리에 컴포넌트를 남겨주는데 변수에 저장해서 사용하면된다.

* styled-components의 장점

  1. CSS파일을 오픈할 필요없이 JS파일에서 바로 스타일을 넣을 수 있다.
  2. 여기 적은 스타일이 다른 JS파일로 오염되지 않는다. (그냥 CSS파일은 오염될 수 있다.)
  3. 페이지 로딩시간이 단축된다.(styled component를 이용하면 <style>태그에 속성을 넣어준다)

* props로 재활용가능

  • props를 이용하면 기존의 컴포넌트를 살짝 다르게 이용할 수 있다.
  • 아래의 예시코드를 확인
import styled from 'styled-components';

let ColorBtn = styled.button`
  background : ${ props => props.bg };
  color : black;
  padding : 10px;
`;

function Detail(){
  return (
    <div>
        <ColorBtn bg="orange">orange button</YellowBtn>
        <ColorBtn bg="blue">blue button</YellowBtn>
    </div>
  )
}
  • ${ props => props.bg } 이게 styled-components 에서의 props를 이용하는 문법이다.
  • bg가 아닌 다름 이름으로 자유롭게 작명해도된다.
  • 컴포넌트 쓸 때 bg라는 props를 입력가능하다.

* 삼항연산자를 이용한 조건에 맞는 스타일 지정도 가능

let YellowBtn = styled.button` 
  background : ${ props => props.bg };
  color : ${ props => props.bg == 'blue' ? 'white' : 'black' };
  padding : 10px; 
`; 

 

* 기존의 스타일을 상속 또한 가능하다

let YellowBtn = styled.button` 
  background : ${ props => props.bg };
  color : ${ props => props.bg == 'blue' ? 'white' : 'black' };
  padding : 10px; 
`; 

// 기존 스타일을 상속
const NewBtn = styled(YellowBtn)``;

// 기존 스타일 복사후 추가로 속성 넣기도 가능
const NewBtn = styled(YellowBtn)`
  margin : 10px;
`;

 

* 기존의 스타일을 상속 받으면서 다른 태그로 사용할 경우

let YellowBtn = styled.button` 
  background : ${ props => props.bg };
  color : ${ props => props.bg == 'blue' ? 'white' : 'black' };
  padding : 10px; 
`; 

// 기존 스타일을 상속
const NewBtn = styled(YellowBtn)``;

// 기존 스타일을 상속받고 a태그로 변경
return (
  <>
    <NewBtn as="a" href="/">Login</NewBtn>
  </>
)

 

* attrs를 이용해 속성을 전달해 줄 수 있다.

const Input = styled.input.attrs({ required:true })`
  background-color: "tomato";
`;

return (
  <>
    <input/>
    <input/>
    <input/>
    <input/>
    <input/>
    <input/>
  </>
)

 

* Animation도 줄 수 있다.

  • keyframes를 이용한다.
  • animation은 css에 적용하는 방식과 동일하다.
import { styled, keyframes } from "styled-components"

const animation = keyframes`
  0% {
    transform: rotate(0deg);
    border-radius: 0px;
  }
  50% {
    transform: rotate(360deg);
    border-radius: 100px;
  }
  100% {
    transform: rotate(0deg);
    border-radius: 0px;
  }
`

const rotateAnimation = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`

const Circle = style.div`
  width: 200px;
  height: 200px;
  animation: ${animation} 1s linear infinite;
`

const Box = style.div`
  width: 200px;
  height: 200px;
  background: tomato;
  animation: ${rotateAnimation} 1s linear infinite;
`

return (
  <>
    <Box/>
    <Circle/>
  </>
)

 

* styled-components자체를 선택해줄 수 있다. (Pseudo Selectors)

  • styled-component자체를 선택하여서 해당 속성에 상관없이 항상 코드가 작동하게 만들 수 있다.
  • 아래의 코드는 Emoji가 span이거나 div 등등 어떤 태그가 와도 상관없이 작동한다.
const Emoji = styled.span`
  font-size: 36px;
`

const Box = styled.div`
  width: 100px;
  height: 100px;
  ${Emoji}:hover {
      font-size: 48px;
  }
`

return (
  <>
    <Box>
      <Emoji>😀</Emoji>
    </Box>
  </>
)

 

* styled-components의 단점

  • JS파일이 복잡해진다.
    • 컴포넌트가 styled인지 일반 컴포넌트인지 구분이 어렵다.
  • JS파일간의 중복 디자인이 많이 필요하게 될 경우 export와 import를 이용하게 되는데 그러면 CSS파일 쓰는거랑 차이가 없을 수 도 있다.

* 일반 CSS파일 오염 방지 방법

  • '모듈화' 기능을 이용한다.
  • 컴포넌트명.module.css
  • 컴포넌트명.js 파일에서 import 해서 쓰면 그 스타일들은 컴포넌트명.js 파일에만 적용
  • ex) App.module.css를 만들면 App.js파일에만 종속이 된다.