다라다라V
article thumbnail
728x90
반응형

리액트 컴포넌트를 스타일링할 때는 다양한 방법이 있습니다. 자신이 필요하거나 회사가 원하는 방식으로 만들면 됩니다. 이번 포스트에서 알아볼 스타일링 방식은 다음과 같습니다.

  • 일반 CSS : 컴포넌트를 스타일링하는 가장 기본적인 방식
  • Sass : 자주 사용되는 CSS 전처리기(prev-processor) 중 하나로 확장된 CSS 문법을 사용하여 CSS를 더욱 쉽게 작성할 수 있음
  • CSS Module : 스타일을 작성할 때 CSS 클래스가 다른 CSS 클래스의 이름과 충돌하지 않도록 고유의 이름을 지정하는 옵션
  • styled-components : 스타일을 자바스크립트 파일에 내장시킴, 해당 스타일이 적용된 컴포넌트를 스타일을 작성함과 동시에 만듦

 

이번 실습은 다음과 같은 순서로 진행합니다.

  1. 프로젝트 준비하기
  2. 일반 CSS 사용하기
  3. Sass 사용하기
  4. CSS Module 사용하기
  5. styled-components 사용하기

 

터미널에 다음의 코드를 입력하여 프로젝트를 새로 만들어 봅시다.

$ yarn create react-app styling-react
$ cd styling-react
$ yarn start

📌 가장 흔한 방식, 일반 CSS

프로젝트는 일반 CSS 방식으로 만들어져 있습니다. 기존의 스타일링이 불편하지 않다면 일반 CSS를 계속 사용해도 됩니다.

 

방금 만든 프로젝트를 보면 src 디렉터리에 App.js 파일과 App.css 파일이 있습니다.

CSS를 작성할 때 가장 중요한 것은 CSS 클래스가 중복되지 않게 만들어야합니다. 이름을 지을 때 특별한 규칙을 사용하거나, CSS Selector 를 활용하여 중복되지 않는 이름을 지을 수 있습니다.


📚 이름 짓는 규칙

/* App.css */

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

( ... )
  • 프로젝트에 자동 생성된 App.css를 읽어보면 클래스 이름이 컴포넌트 이름-클래스 형태로 지어져 있음 (예: App-logo) 
  • 클래스 이름에 컴포넌트 이름을 포함하여 중복되는 클래스를 만드는 것을 방지함

 

비슷한 방식으로 BEM 네이밍(BEM Naming)이라는 방식도 있습니다. CSS 방법론 중 하나로, 이름을 지을 때 일종의 규칙을 준수하여 클래스가 어디에서 어떤 용도로 쓰이는지 명확히 밝힙니다. (예: .card_title-primary)


📚 CSS Selector

CSS Selector 를 사용하면 CSS 클래스가 특정 클래스 내부에 있는 경우에만 스타일을 적용합니다.

.App 안에 들어있는 .logo에 스타일을 적용하려면 다음과 같이 작성해야합니다.

.App .logo {
    animation: App-logo-spin infinite 20s linear;
    height: 40vmin;
}

 

다음의 규칙을 적용하여 App.css와 App.js를 다시 작성해봅시다.

/* App.css */

.App {
  text-align: center;
}

/*A pp 안에 있는 .logo */
.App .logo {
  height: 40vmin;
  pointer-events: none;
}

/* .App 안에 들어 있는 header
   header 클래스가 아닌 header 태그 자체에 
   스타일을 적용하기 때문에 .이 생략되었습니다. */
.App header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

/* .App 안에 들어 있는 a 태그 */
.App a {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

 

수정된 컴포넌트에 맞게 App.js 역시 컴포넌트의 JSX 부분을 수정해야합니다.

// App.js

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header> // 변경
        <img src={logo} className="logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

컴포넌트 최상위 html 요소에는 컴포넌트 이름으로 클래스 이름을 짓고(.App), 그 내부에서는 소문자를 입력하거나(.logo), header와 같은 태그를 사용하여 클래스 이름을 생략할 수도 있습니다.


📌 Sass 사용하기

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

  • CSS 전처리기로 복잡한 작업을 쉽게하도록 하고,
  • 스타일 코드의 재활용성을 높여주며,
  • 코드의 가독성을 높여 유지 보수를 쉽게 해줍니다.

 

Sass 에서는 두 가지 확장자 .scss .sass를 지원합니다. 두 확장자는 문법이 꽤 다릅니다. 코드를 확인하여 문법 차이를 느껴보세요

/* .sass */

$front-stack: Helvetica, sans-serif
$primary-color: #333

body
    font: 100% $front-stack
    color: $primary-color
/* .scss */

$front-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
    font: 100% $front-stack;
    color: $primary-color;
}

주요 차이점으로는

  • .sass : 중괄호({})와 세미콜론(;)을 사용하지 않음
  • .scss : 기존 CSS를 작성하는 방식과 비교해서 문법이 크게 다르지 않음
  • .scss가 더 많이 사용되므로 이 방식을 사용할 예정

Sass를 CSS로 변환시켜주는 sass라는 라이브러리를 설치해봅시다.

(터미널에서 해당 디렉터리로 이동 하여 설치 후, 서버를 재 부팅해야합니다.)

$ yarn add sass

설치 후 SassComponent.scss 를 작성해보세요.

/* 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;
  .box { // 일반 CSS에서는 .SassComponent .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);
    }
    // .box에 마우스를 올렸을 때
    &:hover {
      background: black;
    }
  }
}

 

이 Sass 스타일 시트를 사용하는 SassComponent.js도 만들어봅시다.

// 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;

 

이 컴포넌트를 App 컴포넌트에서 보여줍시다.

// App.js

import { Component } from "react";
import SassComponent from "./SassComponent";

class App extends Component {
  render() {
    return(
      <div>
        <SassComponent />
      </div>
    );
  }
}

export default App;

 

서버를 재부팅하면 다음과 같은 결과를 얻을 수 있습니다.

 

 


📚 utils 함수 분리하기

여러 파일에서 사용되는 Sass 변수와 믹스인은 다른 파일로 분리하여 작성하고, 필요한 곳에서 불러와 사용할 수 있습니다.

src 디렉터리에 styles라는 디렉터리를 생성하고, 그 안에 utils.scss 파일을 만들어 봅시다. 이 파일에는 기존 SassComponent.scss에 적힌 변수와 믹스인을 옮겨둡니다.

/* src/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.scss 파일에서 선언한 변수와 믹스인을 다시 SassComponent.scss 에서 사용해봅시다.

/* SassComponent.scss */

@import './styles/utils';
.SassComponent {
  display: flex;
  .box { // 일반 CSS에서는 .SassComponent .box와 마찬가지
  ( ... )
  }
}
  • @import 구문을 이용하여 다른 scss 파일을 불러올 수 있습니다.

📚 sass-loader 설정 커스터마이징하기

이 작업은 필수는 아니지만 하면 좋은 작업입니다.

@import를 할 때 절대 주소나 상대 주소로 파일의 경로를 지정할 때, 구조가 깊어지면 상위폴더를 한참 올라가야합니다.

@import '../../../styles/utils'

 

sass-loader의 설정을 커스터마이징하여 이 문제를 해결할 수 있습니다. create-react-app으로 만든 프로젝트는 프로젝트 구조의 복잡성을 낮추기 위해 세부 설정이 모두 숨어져 있습니다. yarn eject 명령어를 통해 세부설정을 밖으로 빼 커스터마이징할 수 있습니다.

 

create-react-app에는 기본적으로 Git 설정이 되어있어 먼저 커밋을 진행해봅시다.

VS Code 좌측에 있는 Git UI를 사용하거나 명령어를 통해 작업을 커밋할 수 있습니다.

$ git add .
$ git commit -m 'Commit before yarn eject'

이후 yarn eject 명령어를 사용해봅시다

$ yarn eject
$ react-scripts eject

 

이제 프로젝트 디렉터리에는 config라는 디렉터리가 생겼을 것입니다. webpack.config.js를 열어 "sassRegex"라는 키워드를 찾아보세요(ctrl+F) 두 번재 탐색 결과에서 다음과 같은 코드를 찾을 수 있을 것입닏나.

{
  test: sassRegex,
  exclude: sassModuleRegex,
  use: getStyleLoaders(
    {
      importLoaders: 2,
      sourceMap: isEnvProduction && shouldUseSourceMap,
    },
    ‘sass-loader‘
  ),
  sideEffects: true,
},

여기서 use:에 있는 'sass-loader' 부분을 지우고, 뒷부분에 concat을 커스터마이징된 sass-loader 설정을 넣으세요.

          {
            test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders({
                importLoaders: 3,
                sourceMap: isEnvProduction 
                ? shouldUseSourceMap
                : isEnvDevelopment,
              }).concat({
                loader: require.resolve('sass-loader'),
                options: {
                  sassOptions: {
                    includePaths: [paths.appSrc+'/styles'],
                  },
                  additionalData: "@import 'utils';",
                },
              }),
              sideEffects: true
            },
  • 설정 파일을 저장하고 서버를 재부팅하면 utils.scss 파일을 불러올 때 앞부분에 상대 경로를 입력할 필요가 없습니다.

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

Sass 의 장점은 라이브러리르 쉽게 불러올 수 있다는 것 입니다. yarn 을 통해 설치한 라이브러리는 상대 경로를 통해 node_modules에서 불러와야합니다. 때문에 ../를 많이 적어야하는데 대신 물결 문자(~)를 사용할 수 있습니다.

@import '../../../node_modules/library/styles'
@import '~/library/styles'

 

연습삼아 유용한 Sass 라이브러리를 설치해봅시다.

  • 반응형 디자인 : include-media (https://include-media.com)
  • 색상 팔래트 : open-color (https://www.npmjs.com/package/open-color)

yarn 명령어로 다음의 라이브러리를 설치해봅시다.

$ yarn add open-color include-media

 

설치를 마쳤다면 utils.scss 파일을 열고 물결 표시를 열어 라이브러리를 불러오면 됩니다.

// utils.scss

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

Sass 라이브러리를 불러올 때는 node_modules 내부 라이브러리 경로 안에 있는 scss 파일을 불러야합니다. 직접 경로로 들어가 확인해보는 과정이 필요합니다.

.SassComponent {
  display: flex;
  background: $oc-gray-2;
  @include media('<768px') {
    background: $oc-gray-9;
  }
  • 이 코드는 SassComponent의 배경색을 open-color 팔레트 라이브러리에서 불러온 후 설정
  • 화면 가로 크기가 768px 미만이 되면 배경을 어둡게 만듭니다.

반응형
profile

다라다라V

@DaraDaraV

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!