JS Library/React

CSS Module

원2 2022. 8. 1. 16:21
728x90
반응형

CSS Module을 사용하면 CSS 클래스가 중첩되는 것을 완벽히 방지할 수 있다

CRA로 만든 프로젝트에서 CSS Module을 사용할 땐 CSS 파일의 확장자를. module.css로 설정

 

.Role {
 background: black;
 color: white;
 padding: 2rem;
}

이런 식으로 하나 만들게 되면 해당 CSS 파일을 불러올 때 선언한 클래스 이름들이 모두 고유해진다

고유 CSS 클래스 이름이 만들어지는 과정에서는 파일 경로, 파일 이름, 클래스 이름, 해쉬값 등이 사용될 수 있다

 

 

className을 설정할 때에는 import로 불러온 styles 객체 안에 있는 값을 참조해야 함

import React from "react";
import styles from "./Box.module.css";

function Box() {
  return <div className={styles.Box}>{styles.Box}</div>;
}

export default Box;

https://react.vlpt.us/styling/02-css-module.html

클래스 이름에 대하여 고유한 이름들이 만들어져서 다른 관계없는 곳에서 사용한 CSS 클래스 이름과 중복되는 것에 신경 쓸 필요가 없음

 

아래의 상황에 유용

  • 레거시 프로젝트에 리액트를 도입할 때 (기존 프로젝트에 있던 CSS 클래스와 이름이 중복되어도 스타일이 꼬이지 않게 해줌.)
  • CSS 클래스를 중복되지 않게 작성하기 위하여 CSS 클래스 네이밍 규칙을 만들기 귀찮을 때

 

각설하고 새프로젝트를 만들어보자

커스텀 체크박스 컴포넌트를 만들것!

$ npx create-react-app 프로젝트명

* 별도로 설치해야 할 라이브러리는 없음

webpack에서 사용하는 css-loader 에서 지원됨

 

CheckBox.js

import React from "react";

function CheckBox({ children, checked, ...rest}) {

    return (
        <div>
            <label>
                <input type="checkbox" checked={checked} {...rest} />
                <div>{checked ? "체크됨" : "체크 ㄴ"}</div>
            </label>
            <span>{children}</span>
        </div>
    );
}

export default CheckBox;

App.js

import './App.css';
import {useState} from "react";
import CheckBox from "./components/CheckBox";

function App() {
  const [check, setCheck] = useState(false);

  const onChange = e => {
    setCheck(e.target.checked);
  }

  return (
      <div>
        <CheckBox onChange={onChange} checked={check}>
          다음 약관에 모두 동의하거라
        </CheckBox>
        <p>
          <b>check: </b>
          {check ? 'true' : 'false'}
        </p>
      </div>
  );
}

export default App;

체크 전
체크 후

...rest 의 경우는 전 글에도 게시했듯이 onChange 같은것을 바로 input에게 적용하기 위함

 

스타일링

$ yarn add react-icons

이 라이브러리는 프론트엔드프레임워크 icon들을 컴포넌트형태로 쉽게 사용할 수 있다.

 

CheckBox.js

import React from "react";
import {MdCheckBox, MdCheckBoxOutlineBlank} from "react-icons/md";
import styles from './CheckBox.module.css';

function CheckBox({children, checked, ...rest}) {

    return (
        <div className={styles.checkbox}>
            <label>
                <input type="checkbox" checked={checked} {...rest} />
                <div className={styles.icon}>
                    {checked ? (
                        <MdCheckBox className={styles.checked}/>
                    ) : (
                        <MdCheckBoxOutlineBlank/>
                    )}
                </div>
            </label>
            <span>{children}</span>
        </div>
    );
}

export default CheckBox;

 

CheckBox.module.css

.checkbox {
    display: flex;
    align-content: center;
}

.checkbox label {
    cursor: pointer;
}

/* 실제 input 을 숨기기 */

.checkbox input {
    width: 0;
    height: 0;
    position: absolute;
    /* 불투명 */
    opacity: 0;
}

.checkbox span {
    font-size: 1.125rem;
    font-weight: bold;
}

.icon {
    display: flex;
    align-items: center;
    /* 아이콘의 크기는 폰트 사이즈로 조정 가능 */
    font-size: 2rem;
    margin-right: 0.25rem;
    color: #adb5bd;
}

.checked {
    color: #339af0;
}

.icon 처럼 짧고 단순하게 해도 어차피 .module.css 덕분에 다른곳에서 중복 될 일이 전혀 없기 때문

대충 지어도 된다.

새로운 아이콘과 함께 고유한 클래스 이름(.module.css 의 힘)이 만들어진다. ㅗㅜㅑ

 

 

* 클래스 이름에  -  가 있다면 ? styles['my-class'] 이런식으로 사용

* 여러개라면 ? ${styles.one} ${styles.two}

* 조건부라면 ? ${styles.one} ${condition ? styles.two : ''}

 

이런식으로 까다로워진다....

이전에 적었던 게시글의 classnames 라이브러리에서는 bind 기능이 있음!!!

 

응 라이브러리 설치

$ yarn add classnames

 

App.js

import React from "react";
import {MdCheckBox, MdCheckBoxOutlineBlank} from "react-icons/md";
import styles from './CheckBox.module.css';
import classNames from "classnames/bind";

const cx = classNames.bind(styles);

function CheckBox({children, checked, ...rest}) {

    return (
        <div className={cx('checkbox')}>
            <label>
                <input type="checkbox" checked={checked} {...rest} />
                <div className={cx('icon')}>
                    {checked ? (
                        <MdCheckBox className={cx('checked')}/>
                    ) : (
                        <MdCheckBoxOutlineBlank/>
                    )}
                </div>
            </label>
            <span>{children}</span>
        </div>
    );
}

export default CheckBox;

훨씬 간결해졌다

cx('one', 'two')
cx('my-component', {
  condition: true
})
cx('my-component', ['another', 'classnames'])

위 처럼 사용하면 된닿

 

 

** 기타내용

CSS Module 은 Sass 에서도 사용가능 확장자를 .module.sass 로 하기만 하면 됨 (sass 설치 필수)

 

전역화

:global .my-global-name {

}

sass 의 전역화

:global {
  .my-global-name {

  }
}

 

로컬

:local .make-this-local {

}

sass 의 로컬

:local {
  .make-this-local {

  }
}

 

출처 https://react.vlpt.us/styling/02-css-module.html

728x90
반응형

'JS Library > React' 카테고리의 다른 글

todolist 만들기  (0) 2022.08.03
styled-components  (0) 2022.08.02
react-icons link  (0) 2022.08.01
Sass  (0) 2022.08.01
useReducer 요청 상태 관리  (0) 2022.06.09
API 연동하기, axios  (0) 2022.06.09