본문 바로가기
JS/React 강의

[React] 11. styled-components 사용하기

by GiraffePark 2023. 3. 27.

안녕하세요. 박기린 입니다.

이번엔 ReactJS의 스타일링 모듈인 styled-components에 대해 알아보겠습니다.

 

공식 사이트 : https://styled-components.com/

 

 


styled-components가 필요한 이유

React 프로젝트의 컴포넌트들을 css 파일을 이용해서 스타일링하는 경우, 비록 컴포넌트 파일(js/ts)에서 css 파일을 import해서 사용한다고 해도, 그 css 파일의 스타일을 해당 컴포넌트에만 국한되지 않고 전역으로 적용시킵니다.

.form-control {
  margin: 0.5rem 0;
}

.form-control label {
  font-weight: bold;
  display: block;
  margin-bottom: 0.5rem;
}

예를 들어, 위와 같은 css 파일이 있다고 가정하자. 우연찮게 전혀 상관없는 컴포넌트에서 'form-control' 클래스를 가지고 있다면, 위의 css 파일에 적용된 '.form-control' 스타일이 같이 적용된다.

비록 selector을 중복되는 이름이 없도록 좀 더 신경써서 만들면 되긴 하지만, 큰 프로젝트는 여러 명의 개발자들이 붙들고 있고, 각자 다른 컴포넌트를 만들다가 이름이 겹칠 수 있다. 이를 방지하기 위해, 컴포넌트 단위로만 스타일을 줄 수 있는 방법으로 'styled-components'를 사용한다.

 

 

 

 

 


styled-components를 적용하기

기존 css 파일을 이용한 방식

더보기
// 기존 Button.js
import React from 'react';

import './Button.css';

const Button = props => {
  return (
    <button type={props.type} className="button" onClick={props.onClick}>
      {props.children}
    </button>
  );
};

export default Button;

 

// 기존 Button.css
.button {
  font: inherit;
  padding: 0.5rem 1.5rem;
  border: 1px solid #8b005d;
  color: white;
  background: #8b005d;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
  cursor: pointer;
}

.button:focus {
  outline: none;
}

.button:hover,
.button:active {
  background: #ac0e77;
  border-color: #ac0e77;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
}

 

styled-components를 사용한 방식

//변화된 Button.js

import styled from "styled-components";

const Button = styled.button`
  font: inherit;
  padding: 0.5rem 1.5rem;
  border: 1px solid #8b005d;
  color: white;
  background: #8b005d;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
  cursor: pointer;

  &:focus {
    outline: none;
  }

  &:hover,
  &:active {
    background: #ac0e77;
    border-color: #ac0e77;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
  }
`;

 

const Button = styled.button`

styled 객체를 styled-components로부터 import 한 후, 뒤에 html tag의 이름을 넣고, 백틱(``)을 넣어서 사용합니다.

 

 

 

 


Tagged Template Literal

styled-componets가 사용하는 백틱(``)Tagged Template Literal이라고 부릅니다. 자바스크립트의 기본 기능으로, 어떤 자바스크립트 프로젝트에서도 사용이 가능하며, 이전에 자바스크립트 강의노트에서 설명을 드린 적이 있습니다. (https://arnopark.tistory.com/475

 

buttonstyled 객체의 메소드입니다. 일반적인 메소드들은 (괄호)를 뒤에 붙이지만, styled 객체의 html 태그 메소드들은 백틱(``)을 붙여서 사용합니다.`백틱`사이에 전달하는 스타일링 값들이 button 메소드로 전달됩니다. 그리고 이 값을 받은 button 메소드가 새로운 Button 컴포넌트를 반환합니다.

(styled-componets는 모든 html element를 메소드로 지원합니다.)

 

 

 

 


Pseudo-class

 &:focus {
    outline: none;
  }

 &:hover,
 &:active {
    background: #ac0e77;
    border-color: #ac0e77;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
  }
`;

styled-componets에서 css의 가상 선택자(pseudo - class / selector)는 '&' 기호를 사용합니다.

 

 

 

 

 


styled-components의 build 출력방식

styled-componets를 적용한 후, build한 html파일을 살펴보면 위처럼 암호같이 생긴 class가 생성된다. 컴포넌트 단위로 css Class를 지정해줘야 하기 때문에, styled-componets가 자동으로 복잡한 class를 생성해서 넣어준다.

 

 

 

 

 


styled-components의 동적 스타일링

const FormControl = styled.div`
  margin: 0.5rem 0;

  & label {
    font-weight: bold;
    display: block;
    margin-bottom: 0.5rem;
    color: ${(props) => (props.invalid ? "red" : "black")};
  }

  & input {
    display: block;
    width: 100%;
    border: 1px solid ${(props) => (props.invalid ? "red" : "#ccc")};
    background-color: ${(props) => (props.invalid ? "#ffd7d7" : "transparent")};
    font: inherit;
    line-height: 1.5rem;
    padding: 0 0.25rem;
  }

  & input:focus {
    outline: none;
    background: #fad0ec;
    border-color: #8b005d;
  }
`;

 

    color: ${(props) => (props.invalid ? "red" : "black")};

styled-components도 동적 스타일링을 완벽히 지원합니다. 

styled 객체로 생성된 컴포넌트도 리액트 컴포넌트이므로 props를 전달받을 수 있습니다. 

 

 

${(props) => (props.prop이름 ? "스타일링1" : "스타일링2")};

`template literal`${string interpolation}을 사용한 후, 그 안에 props가 인수로 전달되는 함수를 넣어주면 됩니다. 이 함수는 css 스타일이 적힌 String을 return해야만 합니다.

 

 

 

 

 


Media Query

const Button = styled.button`
  width: 100%;
  font: inherit;
  padding: 0.5rem 1.5rem;
  border: 1px solid #8b005d;
  color: white;
  background: #8b005d;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
  cursor: pointer;
  
  @media (min-width: 768px) {
    width: auto;
  }

{...}

`

styled-componets에서도 미디어 쿼리(@media)를 이용해서 기기의 화면 크기에 따라 다르게 보이도록 설정할 수 있습니다

 

 

미디어쿼리에 지정된 width보다 좁은 경우(너비가 768px 미만)면 버튼의 width가 100%, 

미디어쿼리에 지정된 width보다 넓은 경우면 버튼의 width가 auto로 동작합니다.

반응형