[Styled Components] Styled Components

Styled Components

CSS in JS(JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법)
Tagged Template Literal 문법
스타일파일과 js파일을 분리하여 작성하는 것을 권장

특징

  • CSS → JS 스타일 객체 자동 변경
  • 고유한 class 속성 설정
  • 벤더 프리픽스 자동 설정
  • 간편한 동적 스타일링(props,theme)

설치

$ npm i styled-components
$ npm i -D babel-plugin-styled-components

Babel 설정

module.exports = {
  plugins: ['babel-plugin-styled-components'],
}

기본 사용법

import styled from 'styled-components'

const App = () => <Button primary/>

// 방법 1
const Button = styled.button`
  // scss 문법으로 작성
  width: 100%;

  // props를 통한 속성 값 적용
  background-color: ${props => props.danger ? 'red' : 'green'};

  // props를 통한 속성 적용
  ${props => props.primary && css`
    background: white;
    color: black;
  `}
`

// 방법 2
const Button = styled('button')``

Tagged Template Literal
template literals의 발전된 형태
``안의 내용을 문자열 값의 배열로 받아 함수를 재실행

function styled(selector){
  const styledEl = document.querySelector(selector)
  return function(cssText){
    const cssStyles = cssText.toString().trim().split(';')
    const cssKeyValues = cssStyles.map(style => style.split(':'))
    cssKeyValues.forEach(([key, value]) => {
      if(key && value){
        styledEl.style[key]=value
      }
    })
    return styledEl
  }
}

styled('h1')`
  color: red;
  width: 100px;
`

injectGlobal

전역 css 설정

import { injectGlobal } from 'styled-components'

injectGlobal`
  body{
    padding: 0;
    margin: 0;
  }
`

extend

기존 컴포넌트 속성을 상속받아 확장

const TomatoButton = styled(Button)`
  color: tomato;
`;

const Anchor = Button.withCompont("a").extend`
  text-decoration: none;
`;

단순히 다른 태그로 변경하여 사용하는 것도 가능하다

<Button as="a" href="/"/>

keyframes

애니메이션 keyframes 생성

import styled, { keyframes } from 'styled-components'

const Button = styled.button`
  ${props => props.danger && css`
    animation: ${rotation} 2s liner infinite;
  `}
`

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

attrs

HTML 태그 요소에 속성 추가

const Input = styled.input.attrs({
  required: true
})`
  border: 1px solid gray;
`

mixin

재사용 가능한 css 그룹

import { css } from 'styled-components'

const awesomCard = css`
  width: 100px;
  height: 100px;  
`

const Card = styled.div`
  ${awesomCard};
`

Nesting

하위컴포넌트 중첩 선택 가능

const App = () => (
  <Wrapper>
    <Item>1</Item>
  </Wrapper>
)

const Wrapper = styled.div`
  ${Item} {
    color: red;
  }
`

const Item =  styled.div`
  width: 100px;
`

내장함수 사용

polished 라이브러리 사용

import { darken, lighten } from 'polished';

const Btn = styled.button`
  &:hover {
    color: ${lighten(0.1, 'red')}
  }
  &:active {
    color: ${darken(0.1, 'gray')}
  }

`

Theming

theme.js

const theme = {
  mainColor: "green",
  dangerColor: "red"
}
export default themes

app.js

import styled, { ThemeProvider } from 'styled-components'
import theme from './theme'

const App = () => (
  <ThemeProvider theme={theme}>
    <Button>hi</Button>
  </ThemeProvider>
)

const Button = styled.button`
  color: ${props => props.theme.mainColor};
`

global-style

reset
Component 단위가 아닌 HTML Elements 단위로 적용되는 style을 global style에서 관리

npm i styled-reset

createGlobalStyle

import { createGlobalStyle, css } from "styled-components";
import reset from "styled-reset";
import customReset from "./customReset.scss";

const GlobalStyle = createGlobalStyle`
    ${reset};
    ${customReset}; // 사용자 정의 스타일

    html {
      font-size: 62.5%; //1rem = 10px;
    }

    ${({ theme }) => {
      return css`
        body {
          font-family: ${theme.fonts.family.base};
          font-weight: ${theme.fonts.weight.normal};
          font-size: ${theme.fonts.size.base};
        }
      `;
    }}
`;

export default GlobalStyle;

적용
정의된 GlobalStyle 컴포넌트는 theme을 props으로 받을 수 있도록 ThemeProvider의 하위 컴포넌트로 배치

const App = () => (
  <ThemeProvider theme={theme}>
    <GlobalStyle />
    <Header switchTheme={switchTheme} />
    <Container currentThemeText={currentThemeText} />
  </ThemeProvider>
)

[React] Styled Components 사용기

좋은 웹페이지 즐겨찾기