ABOUT ME

-

오늘
-
어제
-
-
  • [React] styled-components로 스타일 적용해보기
    Front-end/React 2020. 11. 30. 12:52

    styled-components

    styled-componentCSS in JS의 개념을 가지고 있는데요, 말 그대로 JS 안에 CSS를 넣는다는 의미입니다.

    예전부터 웹에 스타일을 적용하기 위해서 일반적으로 전역에 CSS 파일을 두어 하나의 파일에서 관리하는 방식을 지속적으로 사용되어 왔고, 현재까지도 이용되고 있습니다.

     

    하지만 이 방식의 경우 CSS 파일이 전역에 존재하기 때문에 클래스 명이 의도치 않게 겹치게 되거나, 같아야 하는 경우를 관리 하는 것이 쉽지 않았습니다. 그래서 최근에는 모듈화를 통해 각 컴포넌트 별로 묶어 Scope를 관리하는 방식도 존재합니다.

     

    styled-component는 이런 고민을 해결함과 동시에 편리함을 제공하게 되는데요, 말 그대로 스타일을 컴포넌트처럼 관리하고 사용할 수 있습니다.

     

    핵심적인 기능 위주로 간단하게 살펴보겠습니다.

     

    ❗️ 이 글은 개인적으로 학습한 정보와 지식을 토대로 작성된 글입니다. 혹시 잘못된 부분이 있거나 수정사항이 있다면 말씀해주시면 반영하겠습니다. 🙏

     

    전체 코드

     

    Import

    npm i styled-components

    npm을 통해 패키지를 설치합니다.

     

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

    사용할 컴포넌트에서 styled라는 네이밍으로 import 후 사용할 수 있습니다.

    styled는 컴포넌트를 다루는 용도로 사용되며, css는 말 그대로 css를 다루는데 사용됩니다.

     

    이제 import한 styled를 사용하여 본격적으로 사용법을 알아보겠습니다.

    Create (생성)

    컴포넌트를 생성할 때의 문법은 아래와 같습니다.

     

    const 컴포넌트명 = styled.태그명

    import React from 'react';
    import styled from 'styled-components';
    
    const Button = styled.button`
      padding: 6px 12px;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      background-color: #74b9ff;
      :hover {
        background-color: #99c6f5;
      }
    `;
    

    CSS 속성들을 가지고 있는 버튼을 하나 만들었습니다. 이제 이걸 사용해볼까요?

    Usage (사용)

    import React from 'react';
    import styled from 'styled-components';
    
    const Button = styled.button`
      padding: 6px 12px;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      background-color: #74b9ff;
      :hover {
        background-color: #99c6f5;
      }
    `;
    
    function App() {
      return <Button>click</Button>;
    }
    
    export default App;
    

    사용은 기존 컨테이너와 동일하게 사용할 수 있습니다. 결과를 한 번 볼까요?

    .

    .

    .

     

    짜잔! 위 CSS 속성을 가진 컨테이너가 만들어진게 보이시죠?

    이처럼 태그명 뒤에 백틱(``)을 붙여 내부에 CSS를 선언해서 그 스타일을 가지고 있는 컴포넌트를 하나 만들게 됩니다.

    태그명에는 다양한 HTML Element(div, h1, p, a 등..)를 사용할 수 있으며 해당되는 CSS 문법은 모두 사용할 수 있습니다.

     

    그러면 만들어낸 버튼은 어떻게 스타일이 적용될까요?

    Internal (내부 구조)

    생성된 버튼의 클래스명을 보면 유니크한 클래스인 dIKXJQ가 적용된 것이 보이시죠?

    이 클래스명을 통해 <html> 내의 <style> 태그에 스타일을 정의합니다. 그리고 렌더링을 시키기 때문에 스타일이 적용되는 방식입니다.

    Extend (상속)

    기존에 만들었던 컴포넌트(예제는 버튼)를 상속받아 사용할 수 있습니다.

     

    const 컴포넌트명 = styled(상속할 컴포넌트명)

    import React from 'react';
    import styled from 'styled-components';
    
    const Button = styled.button`
      padding: 6px 12px;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      background-color: #74b9ff;
      :hover {
        background-color: #99c6f5;
      }
    `;
    
    const RedButton = styled(Button)`
      background-color: #f53e3e;
      :hover {
        background-color: #ff7268;
      }
    `;
    
    function App() {
      return (
        <>
          <Button>click</Button>
          <RedButton>click</RedButton>
        </>
      );
    }
    
    export default App;
    

    기존에 있는 Button 컴포넌트를 상속받아 배경에 대한 CSS만 바꾸어주었습니다. 이러면 어떻게 될까요?

    .

    .

    .

     

    나머지 CSS는 그대로 있고 오버라이딩한 속성만 반영된 버튼이 만들어졌습니다!

     

    Compose (조립)

    기존에 존재하던 컴포넌트도 가져와서 조립을 할 수 있습니다.

    import React from 'react';
    import styled, { css } from 'styled-components';
    
    const BlackFont = css`
      color: black;
    `;
    
    const Button = styled.button`
      padding: 6px 12px;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      background-color: #74b9ff;
      :hover {
        background-color: #99c6f5;
      }
    `;
    
    const RedButton = styled(Button)`
      background-color: #f53e3e;
      :hover {
        background-color: #ff7268;
      }
    
      ${BlackFont}
    `;
    
    function App() {
      return (
        <>
          <Button>click</Button>
          <RedButton>click</RedButton>
        </>
      );
    }
    
    export default App;
    

    css를 활용해서 폰트 색상을 검정색으로 선언해주었고,  빨간색 버튼에 적용해주었습니다.

    .

    .

    .

     

    정상적으로 잘 작동하네요!

    Prop Style

    생성된 컴포넌트의 props를 받아서 스타일을 선택적으로 적용할 수 있습니다.

    import React, { useState } from 'react';
    import styled, { css } from 'styled-components';
    
    const BlackFont = css`
      color: black;
    `;
    
    const Button = styled.button`
      padding: 6px 12px;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      background-color: #74b9ff;
      :hover {
        background-color: #99c6f5;
      }
    `;
    
    const RedButton = styled(Button)`
      background-color: #f53e3e;
      :hover {
        background-color: #ff7268;
      }
    
      ${(props) => (props.clicked ? BlackFont : '')}
    `;
    
    function App() {
      const [clicked, setClicked] = useState(false);
    
      const onClick = () => {
        setClicked(!clicked);
      };
    
      return (
        <>
          <Button>click</Button>
          <RedButton clicked={clicked} onClick={onClick}>
            click
          </RedButton>
        </>
      );
    }
    
    export default App;
    

    onClick 이벤트를 통해 상태값을 바꾸어주는 clicked를 만들었고, 이 prop을 가져와서 css를 다룰 수 있습니다.

    clicked가 true일 경우 BlackFont CSS를, false일 경우는 아무 행동도 하지 않는 의미입니다.

    .

    .

    .

     

    prop 값에 따라서 잘 작동해 주네요!!

     

    Global (전역)

    이렇게 개별 컴포넌트 뿐만 아니라 글로벌에 적용할 수도 있습니다.

     

    const 컴포넌트명 = createGlobalStyle

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import { createGlobalStyle } from 'styled-components';
    
    const GlobalStyle = createGlobalStyle`
      * {
        box-sizing: border-box;
        background-color: black
      }
    `;
    
    ReactDOM.render(
      <React.StrictMode>
        <GlobalStyle />
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    reportWebVitals();
    

    createGlobalStyle을 활용해서 최초 렌더링 될 때 반영하여 전체 컴포넌트에 영향을 줄 수 있도록 할 수 있습니다.

    .

    .

    .

     

    전체를 감싸는 root 컨테이너에 스타일이 적용된걸 확인 할 수 있습니다.

     

     

    지금까지 설명한 것 이외에도 반응형, ThemeProvider, attribute, animation 등 다양한 기능이 공식 홈페이지에 소개가 되어있으니 필요한 부분이 있다면 참고하시면 좋을 것 같습니다.

    댓글