CSS in JS (emotion.js)

Jung Hyun Kim·2020년 7월 23일
0

CSS-in-JS

emotion.js를 사용하여 styling 적용

CSS in JS

  • 현재의 웹은 페이지가 아니라 컴포넌트로 작성 되었고, CSS는 컴포넌트 기반을 위해 만들어 진 적이 없었다. 그래서 컴포넌트 마다 별도의 CSS 파일이 있었고, 복잡성을 가증 시켰다!
  • JavaScript 내에서 스타일을 선언 함으로서, JS와 CSS사이에 상수와 함수를 쉽게 공유 할 수 있게 되었다.
  • 고유한 className을 CSS 로 컴파일할 때 자동 생성 해줌으로서, className의 중복에서 오는 코드의 충돌을 막을 수 있다.

출처 블로그

Why emotion.js?

css props

  • 기존에 정의한 컴포넌트 스타일을 쉽고 안전하게 확장 가능
  • UI 컴포넌트를 구현하면서, 변경되어선 안되는 최소한의 상태를 props를 통해 제어 가능
  • styled component 만들지 않고 인라인 스타일 적용 가능

확장성

@emotion/styled를 통해 styled-components와 동일한 기능을 제공 하고, @emotion/core를 통해 확장성을 갖춤

가벼운 용량

TypeScript와의 좋은 호환성

출처 블로그

React 에서 emotion.js 사용하기

@emotion/core

  • 사용하려는 컴포넌트 상단에 /** @jsx jsx */를 입력해 준다
    이거 안해서 바벨 설치하고 난리하고 결국 몇 번 다시 설치하는 문제가 있었다 ㅠㅠ
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
  • 아래 emotion/core를 사용하기 위해 import 한다
import { css, jsx } from '@emotion/core';
  • css = {css `css내용`}의 형태로 입력하면 적용된다.
function CakeContainer(props) {
  return (
    <div>
      <h2 css={ css`
    border: 1px solid pink;
    color: pink;
  `}>Number of Cakes - {props.numOfCakes}</h2>
    </div>
  );
}

@emotion/styled

  • 상단에 styled로 사용하겠다고 import 한다. 따로 npm i @emotion/styled설치 해야함
  • 사용법은 styled component와 거의 같다.
  • 버튼 컴포넌트를 만들어 주고 스타일을 준 뒤, 아래 버튼 태그를 맞게 수정하면 됨
import styled from "@emotion/styled"

const PinkButton= styled.button`
color: pink;
`

function CakeContainer(props) {
  return (
    <div>
      <h2 css={ css`
    border: 1px solid pink;
    color: pink;
  `}>Number of Cakes - {props.numOfCakes}</h2>
      <PinkButton onClick={props.buyCake}>Buy Cake</PinkButton>
    </div>
  );
}

Styles type

Object Styles

  • className 자리에 css 가 위치하고 그 속성을 { } 객체형태에 담는 형식
  • Object Style로 지정해줄때는 css속성을 camelCase로 작성해야 한다.
 <h2 css={{
    border: 1px solid pink;
    color: pink;
  }}>hello</h2>

String Styles

 <h2 css= {css `
    border: 1px solid pink;
    color: pink;
  `}>hello</h2>

css props

  • 컴포넌트의 props 값으로 css 를 넘겨주어 스타일을 일정하게 관리하고 확장 할 수 있다.

  • 먼저 부모의 컴포넌트에 자식 컴포넌트와 넘겨줄 props를 정해준다.

function Parent() {
  return (
    <div>
      <Child />
      <Child small />
      <Child
        small
        css={{border: "1px solid red"}}
        onClick={() => console.log('clicked')}
       />
    </div>
  )
}
  • 자식 컴포넌트에서 props를 받아 적용해준다.
function Child(props) {
  //부모로 부터 props를 가져오기 위해 parameter에 props 입력 
  return (
    <div
      css={{
        color: "orange",
        fontSize: props.small ? 24 : 36
        //props로 small을 가지고 있는 <Child small/>이라면 폰트를 24로 그게 아니라
        //<Child />라면 36으로 적용해준다.
      }}
      {...props}
      //spread operater를 통해 부모의 props 값을 자식에게 전달해주는 의미, 
      //즉 css, onClick 같은 이벤트가 전달 되는 것이다. 
    >
      Hello World!
    </div>
  )
}

출처 블로그

Composition

  • style을 combine 할 때,베이스인 css가 있고 선택하여 적용하고 싶을 때 유용하게 사용된다.
import {css, jsx} from @emotion/core

  const red = css`
    color: red;
  `;

  const yellowBase = css`
    color: yellow;
    background-color: black;
  `;

  return (
    <div>
        <h1 css={yellowBase}>이건 노란색</h1>
        <h1 css={[red, yellowBase]}>이것도 노란색</h1>
        <h1 css={[yellowBase, red]}>이건 빨간색</h1>


공식 문서

Nested Selectors

  • scss에서 적용하는 nesting 기능 또한 emotion.js에서도 접목 가능하다.
  const red = css`
    color: red;

    p {
      border-bottom: 1px solid red;
    }
  `;

  const yellowBase = css`
    color: yellow;
    background-color: black;
  `;

  return (
    <div>
      <h1 css={red}>
        <p>나는 nesting 된 p </p>
      </h1>
      <p>나는 그냥 p</p>
  • nesting한 p tag에만 원하는 효과가 적용된다.

Global Styles

  • 전역에서 적용시키고 싶은 요소들은(보통 scss에서 reset.scss로 관리되던 아이들) 아래와 같이 관리 된다.
  • 먼저 상위에서 import 하고
import { Global, css, jsx } from '@emotion/core';
  • 적용 시키려는 return문 상단에 위치 시킨다. 이렇게 바로 적용할 수도 있고, 컴포넌트로 만들어서 따로 관리 할 수도 있다.

  return (
    <div>
        <Global styles = {css ` * {box-sizing : border-box; }`}/>
profile
코린이 프론트엔드 개발자💻💛🤙🏼

0개의 댓글