[React] 컴포넌트 스타일링

🌊·2021년 12월 11일
0

React

목록 보기
11/20

리액트에서 스타일링은 다양한 방식을 사용할 수 있다.

스타일링 방식

  • 일반 css: 컴포넌트를 스타일링하는 가장 기본적인 방식

  • Sass: 자주 사용되는 CSS 전처리기(pre-processor)중 하나로 확장된 CSS 문법을 사용하여 CSS 코드를 더욱 쉽게 작성할 수 있도록 해준다.

  • CSS Module: 스타일을 작성할 떄 CSS 클래스가 다른 CSS 클래스의 이름과 절대 충돌하지 않도록 파일마다 고유한 이름을 자동으로 생성해주는 옵션이다.

  • styled-components: 스타일을 자바스크립트에 내장시키는 방식, 스타일을 작성함과 동시에 해당 스타일이 적용된 컴포넌트를 만들 수 있게 해준다.

일반 CSS

프로젝트를 생성하면 기본적으로 App.css 파일처럼 일반 CSS 방식을 사용하고 있다.
실제로 소규모 프로젝트를 개발하고 있다면 새로운 스타일링 시스템을 적용하는 것이 불편할 수 있다.

Sass 사용하기

Sass(Syntactically Awesome Style Sheets) (문법적으로 매우 멋진 스타일시트)

CSS 전처리기로 복잡한 작업을 쉽게 할 수 있도록 해주고, 스타일 코드의 재활용성을 높여줄 뿐만 아니라 코드의 가독성을 높여서 유지 보수를 더욱 쉽게 해준다.

Sass에서는 확장자 .scss와 .sass를 지원한다.

.sass는 중괄호({})와 세미콜론(;)을 사용하지 않는다.
보통 .scss 문법이 더 자주 사용된다.

Sass 추가

$npm add sass

SassComponent.scss

$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;

// 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있다.)
@mixin square($size) {
  $calculated: 32px * $size;
  width: $calculated;
  height: $calculated;
}

.SassComponent {
  display: flex;

  // 일반 CSS: .SassComponent .box
  .box {
    background: red;
    cursor: pointer;
    transition: all 0.3s ease-in;

    // .red 클래스가 .box와 같이 사용되었을 떄
    &.red {
      background: $red;
      @include square(1);
    }

    &.orange {
      background: $orange;
      @include square(2);
    }

    &.yellow {
      background: $yellow;
      @include square(3);
    }

    &.green {
      background: $green;
      @include square(4);
    }

    &.blue {
      background: $blue;
      @include square(5);
    }

    &.indigo {
      background: $indigo;
      @include square(6);
    }

    &.violet {
      background: $violet;
      @include square(7);
    }

    &.hover {
      background: black;
    }
  }
}

여러 파일에서 사용될 수 있는 Sass 변수 및 믹스인은 다른 파일로 따로 분리하여 작성한 뒤 필요한 곳에서 쉽게 불러와서 사용할 수 있다.

utils 함수 분리하기

/styles/utils.scss

$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;

// 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있다.)
@mixin square($size) {
  $calculated: 32px * $size;
  width: $calculated;
  height: $calculated;
}

utils 함수 사용하기

SassComponent.scss

@import './styles/utils';

@import를 사용해서 해당 파일을 가져올 수 있다.

SassComponent.js

import "./SassComponent.scss";

const SassComponent = () => {
  return (
    <div className="SassComponent">
      <div className="box red" />
      <div className="box orange" />
      <div className="box yellow" />
      <div className="box green" />
      <div className="box blue" />
      <div className="box indigo" />
      <div className="box violet" />
    </div>
  );
};

export default SassComponent;

sass-loader 커스터마이징

Sass를 사용할 때 반드시 해야하는 것은 아니지만 해두면 유용하다.

프로젝트의 디렉터리 구조가 깊어져서 해당 파일을 찾으려면 한참 올라가야 하는 경우에도 커스터마이징을 통해서 해결할 수 있다.

sass-loader의 설정을 커스터마이징해서 해결할 수 있다.

$yarn eject, $react-scripts eject를 통해서 config 디렉터리에 접근할 수 있다.
webpack.config.js파일을 통해서 설정을 바꾸면 숨겨져 있는 설정들을 모두 볼 수 있다.

webpack.config.js 파일을 통해서 scss파일을 가져올 때 @import 'utils.scss' 식으로 표시하면 해당 scss 파일을 불러올 수 있다.
또한 해당 scss 파일을 자동으로 포함시킬수도 있다.
sass-loader의 additional Data 옵션을 설정하면 된다.

node_modules에서 라이브러리 불러오기

Sass의 장점 중 하나는 라이브러리를 쉽게 불러와서 사용할 수 있다는 것이다.

라이브러리를 사용하는 가장 기본적인 방법: node_modules까지 들어가서 불러오는 방법
디렉터리가 깊숙한 경우에는 물결 문자(~)를 사용할 수 있다.

@import '~library/styles';

물결 문자를 사용하면 자동으로 node_modules에서 라이브러리 디렉터리를 탐지하여 스타일을 불러올 수 있다.

include-media

반응형 디자인을 쉽게 만들어주는 라이브러리

open-color

색상 팔레트 라이브러리

라이브러리 사용

@import '~include-media/dist/include-media';
@import '~open-color/open-color';

CSS Module

CSS를 불러와서 사용할 때 클래스 이름을 고유한 값 ([파일 이름]_[클래스 이름]__[해시값])으로 자동으로 만들어주어서 컴포넌트 스타일 클래스 이름이 중첩되는 현상을 방지해주는 기술
v2 버전 이상부터는 .module.css 확장자로 파일을 저장하기만 하면 CSS Module이 적용된다.

자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 사용해도 된다.

CSSModule.module.css

.wrapper {
  background: black;
  padding: 1rem;
  color: white;
  font-size: 2rem;
}

/* 글로벌 CSS */

:global .something {
  font-weight: 800;
  color: aqua;
}

클래스 이름을 지을 때 고유성에 대해서 고민하지 않아도 된다.
직접 불러온 컴포넌트 내부에서만 작동하기 떄문이다.

웹페이지에서 전역적으로 사용되는 경우라면 :global을 앞에 입력하면 된다.

CSSModule.js

import styles from "./CSSModule.module.css";

const CSSModule = () => {
  return (
    <div className={styles.wrapper}>
      안녕하세요. 저는 <span className="something">CSS Module!</span>
    </div>
  );
};

export default CSSModule;

CSS Module이 적용된 스타일 파일을 불러오면 객체를 하나 전달받게 된다.
CSS Module에서 사용한 클래스 이름과 해당 이름을 고유화한 값이 키-값 형태로 들어 있다.
고유한 클래스 이름을 사용하려면 className= {styles.[클래스 이름]} 형태로 전달해주면 된다. :global`의 경우에는 문자열로 넣어주면 된다.

CSS Module을 사용한 클래스 이름을 두 개 이상 적용할 때

<div className={`${styles.wrapper} ${styles.inverted}`}>
      안녕하세요. 저는 <span className="something">CSS Module!</span>    </div>

ES6 문법 템플릿 리터럴(Template Literal)을 사용하여 문자열을 합해주었다.
문자열 안에 자바스크립트 레퍼런스를 쉽게 넣어줄 수 있다.

classnames

CSS 클래스를 조건부로 설정할 때 매우 유용한 라이브러리
CSS Module을 사용할 때 이 라이브러리를 사용하면 여러 클래스를 적용할 때 매우 편리하다.

$ yarn add classnames

classnames 간략 사용법

import classNames from 'classnames';

classNames("one", "two"); // 'one two'
classNames("one", { two: true }); 'one two'
classNames("one", { two: false }); 'one'
classNames("one", ["two", "three"]); 'one two three'

const myClass = "hello";

여러종류의 파라미터를 조합해 CSS 클래스를 설정할 수 있다.

const MyComponent = ({ highlighted, theme }) => {
  <div className={classNames("MyComponent", { highlighted }, theme)}>Hello</div>;
};

highlighted 값이 true이면 highlighted 클래스가 적용되고, theme`로 전달받은 문자열은 그대로 클래스에 적용된다.

CSS Module과 함께 사용하면 CSS Module이 훨씬 쉬워진다.
classnames에 내장되어 있는 bind 함수를 사용하면 클래스를 넣어줄 때마다 styles.[클래스 이름] 형태로 사용할 필요가 없다.

CSSModule.js

import classNames from "classnames/bind";
import styles from "./CSSModule.module.css";

const cx = classNames.bind(styles);

const CSSModule = () => {
  return (
    <div className={cx("wrapper", "inverted")}>
      안녕하세요. 저는 <span className="something">CSS Module!</span>
    </div>
  );
};

export default CSSModule;

Sass와 함께 사용하기

Sass를 사용할 때도 파일 이름 뒤에 .modules.scss 확장자를 사용해주면 CSS Module로 사용할 수 있다.

CSS Module이 아닌 파일에서 CSS Module 사용하기

styled-components

0개의 댓글