image

emotion 설치 & 사용법

태그
Emotion
상세설명emotion 설치 & 사용법
작성일자2023.10.07

emotion은 css-in-js (JavaScript코드에서 CSS를 작성하는 방식) 라이브러리 중 하나로 다음의 특징이있다.

  • 자동적으로 vendor-prefix 를 붙여준다.
  • 기본적으로 고유한 이름을 생성한다.
  • JavaScript와 CSS사이에 상수와 함수를 쉽게 공유할 수 있다.
  • React 스타일 컴포넌트로 사용할 수 있는 것
  • CSS 로드 우선 순위 이슈를 해결할 수 있다
  • javascript runtime에서 필요한 CSS를 동적으로 만들어 적용한다.
  • 패키지 설치

    npm install --save @emotion/react
    
    // styled 방식 사용할시
    npm install --save @emotion/styled
    
    // 스타일을 압축하고 끌어 올려 스타일을 최적화하고 
    // 소스 맵과 레이블을 사용하여 더 나은 개발자 환경을 만드는 선택적 Babel 플러그인
    npm install --save-dev @emotion/babel-plugin

    아래와 같이 루트에 .babelrc를 작성하면 /* @jsxImportSource @emotion/react / 를 매 페이지마다 작성 안 해도 됨

    // .babelrc 
    
    {
      "presets": [
        [
          "next/babel",
          {
            "preset-react": {
              "runtime": "automatic",
              "importSource": "@emotion/react"
            }
          }
        ]
      ],
      "plugins": ["@emotion/babel-plugin"]
    }

    사용법

    import { css } from "@emotion/react";
    
    //css 1
    function Home() {
      return (
        <div
          css={css({
            color: "red",
          })}
        >
          css 1
        </div>
      );
    }
    
    
    //css 2
    function Home() {
      return (
       <div
          css={css`
            color: red;
          `}
        >
          css 2
        </div>
      );
    }
    
    //css 3
    // 여러개일 경우 예) css={[abc, def, { paddingBottom: 0 }]}
    function Home() {
      return (
       <div
         css={homeContainer}
        >
          <p>css 3 </p>
        </div>
      );
    }
    
    const homeContainer = css`
    	width: 100%;
    
    	p {
    		font-size: 1.4rem;
    	}
    `;

    Global 스타일

    //Global.ts
    import { css } from "@emotion/react";
    
    export const reset = css`
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: "Pretendard";
        font-weight: 400;
      }
      html {
        font-size: 62.5%;
      }
      body {
        width: 100%;
        height: 100%;
        font-size: 1.6rem;
        color: ${colors.black};
        background: ${colors.white};
        word-break: keep-all;
      }
      ul,
      li {
        list-style: none;
      }
      input,
      select,
      textarea {
        border: 1px solid ${colors.black};
        color: ${colors.black};
        background: ${colors.white};
      }
      input:focus,
      select:focus,
      textarea:focus {
        outline: none;
      }
      a {
        text-decoration: none;
        color: ${colors.black};
      }
      button {
        border: none;
        outline: 0;
        background-color: transparent;
        cursor: pointer;
      }
      input:autofill,
      input:autofill:hover,
      input:autofill:focus,
      input:autofill:active {
        box-shadow: 0 0 0 100rem ${colors.white} inset;
        -webkit-box-shadow: 0 0 0 3rem ${colors.white} inset !important;
        -webkit-text-fill-color: ${colors.black} !important;
        transition: background-color 5000s ease-in-out 0s;
      }
    `;
    
    //_app.tsx
    import type { AppProps } from "next/app";
    import { Global } from "@emotion/react";
    import { reset } from "@/styles/Global";
    
    export default function App({ Component, pageProps }: AppProps) {
      return (
        <>
           <Global styles={reset} />
           <Component {...pageProps} />
        </>
      );
    }

    참고