styled-components vs. emotion

ujin·2022년 8월 8일
0

React

목록 보기
1/8

이모션 vs. 스타일 컴포넌트

리액트에서는 CSS-in-JS을 통해 스타일을 작업을 진행한다.

그중에서는 styled-components, emotion이 가장 유명하고 많이 사용된다.

그래서 우리 모던 애자일 4기 프론트에서는 어떤 라이브러리를 사용할지 선택하기 위해 각각 어떠한 특징과 장점, 단점이 있는지 알아보는 시간을 가지기로 했다.

CSS in JS

CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법이다.

기존에 웹사이트를 개발할 때는 HTML, CSS, JavaScript는 각자 별도의 파일에 두는 것이 best practice로 여겼다. 하지만 React나 Vue, Angular와 같은 모던 자바스크립트 라이브러리가 인기를 끌면서 바뀌고 있다.

여러 개의 컴포넌트로 분리하고, 각 컴포넌트에 HTML. CSS JavaScript를 몽땅 때려 박는 패턴이 많이 사용되고 있다. React는 JSX를 사용해서 이미 JavaScript를 포함하고 있는 형태를 취하고 있는데 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입을 할 수 있다.

일단 둘 다 sass 문법을 사용하기에 스타일 문법에는 차이가 없다.

🧩사용 트랜드

  • styled-components가 더 많이 사용되고 있으나 npm 다운로드 횟수를 보면 emotion이 더 많다

🧩용량

  • emotion이 styled-components보다 조금 가볍고 빠르다

🧩Style components

패키지 설치

$ npm i styled-components

설치 후에 package.jsonstyled-components가 추가 된다.

  "dependencies": {
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "styled-components": "5.3.5"
  },

기본 문법

먼저 styled-components 패키지에 styled() 함수를 임포트한다. styled는 Styled Components의 근간이 되는 가장 중요한 아이이다. HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.

  • HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근한다.
    import styled from "styled-components";
    
    styled.button`
      // <button> HTML 엘리먼트에 대한 스타일 정의
    `;
  • React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘긴다.
    import styled from "styled-components";
    import Button from "./Button";
    
    styled(Button)`
      // <Button> React 컴포넌트에 스타일 정의
    `;

🧩Emotion

패키지 설치

$ npm i @emotion/react

기본 문법

Styled Components에서 styled() 함수가 중요 했다면 Emotion은 css() 함수이다.

현재는 Styled Components도 css() 함수를 사용할 수 있고, Emotion도 styled() 함수를 제공한다.

Emotion이 css() 함수는 위에서 설치한 @emotion/react 패키지에서 불러올 수 있는데 css() 함수는 CSS 스타일 선언 내용을 인자로 받는데 객체형으로 넘겨도 되고, 문자형으로 넘겨도 된다. 그리고 css()함수가 반환 결과를 해당 스타일을 적용하고 싶은 HTML 요소나 React 컴포넌트의 css라는 prop에 넘겨주면 된다.

객체형 스타일을 css() 함수의 인자로 넘기면 아래와 같은 모습이 된다.

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <div
      css={css({
        backgroundColor: "yellow",
      })}>
      노란색 영역
    </div>);
}

문자형 스타일을 css()함수의 인자로 넘기면 아래와 같은 모습이다.

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <div
      css={css`
        background-color: yellow;
      `}>
      노란색 영역
    </div>);
}

Emotion 문서에는 가급적 스타일 객체로 선언해서 css() 함수에 넘기라고 권장한다.

이 방법을 사용하면 css() 함수를 호출을 생략하고 css prop에 바로 객체로 넘길 수 있으며, 타입스크립크를 사용하면 타입 체킹을 통해 오타를 줄일 수 있다.

emotiom의 차별점

css props

  • 인라인 스타일을 작성하면 클래스가 된다 <div style={{color: “red”}} /> 기존 style 속성은 HTML 인라인 스타일로 주입이 된다. 스타일 우선순위를 다루기 어렵고 스타일 재활용도 힘들다. <div css={csscolor: red} > emotion jsx에서 제공해주는 css 속성을 활용하면 이를 클래스로 변환해준다. 기존이라인으로 사용할 수 없었던 media query, pseudo selector, nested selector등을 사용할 수 있다.
  • css props를 결합하여 복잡한 스타일링을 진행 할 수 있다.
    <div css={[style, themes[theme], sizes[size]]} />
      
    const themes = {
      primary: css`
        color: red;
      `,  
      secondary: css`
        color: blue;
      `
    }
    const sizes = {
      small: css`
        fontSize: 0.75rem;
      `,
      medium: css`
        fontSize: 1rem;
      `
    }
    위와 같이 css 변수를 조립하여 컴포넌트 스타일링을 진행할 수 있다.
    type ThemeType = keyof typeof themes;
    type SizeType = keyof typeof size;
    typescript로 자동 타입 지정까지 할 수 있다.

SSR

  • SSR에서 별도의 설정 없이 동작이 된다.
  • 반면 styled-components 같은 경우 ServerStyleSheeet을 설정 해야 한다.
profile
개발공부일기

0개의 댓글