CSS-in-JS

coolchaem·2021년 11월 22일
1

JavaScript

목록 보기
3/4

CSS-in-JS

  • JavaScript 안에 css를 넣어, component 위주의 컨셉
    • scss, css는 js와 따로 파일을 두면서 다양한 컴포넌트에서 사용하거나 nested 개념도 쓰면서 다양한 스타일 의존성이 생겼다.
    • 의존성이 생기면 하나를 고치면 여러 케이스가 변경되어 확인할 작업과 고려할 작업이 많아진다.
  • 대표적으로 styled-components, emotion.js 가 있다.

styled-components

  • CSS code를 component와 함께 작성할 수 있는 대표적인 library이다.
  • dynamic styling이 가능하다.
    • props로 넘겨주면서 adapting 가능
  • 또한, Style을 확장시키거나 기존처럼 media query, nesting도 가능하다.
import React from 'react';
import styled from 'styled-components';


interface ButtonProps {
  label: string;
}

function RoundButton({label}: ButtonProps) {
  // code
  // ...
  
  return <ButtonStyle label={label}> This is button component </ButtonStyle>;
}

const ButtonStyle = styled.button<ButtonProps>`
  color: turquoise;
  label: ${props => props.label || ""};
`;

Tagged Template Literal

  • Styled Component에서 쓰이는 문법의 원리는 Tagged Template Literal이라는 문법이다.
  • 백틱(``)을 이용해서 template literal을 표현한다.
// syntax
tag `
  string text ${expression} string text
`
// 이 때 tag는 함수라고 한다.
  • 예시로 다음처럼 사용할 수 있으며 console.log로 호출하면 expression과 문자열이 분리된다.
var person = 'NAME';
var age = 20;

function tag(strings, personExp, ageExp) {
  console.log(strings, personExp, ageExp);
}

tag`Person ${person} is a ${age}`;
// [['Person', ' is a ', ''], 'NAME', 20]
  • 그래서 styled component는 위 문법을 이용해서 각 tag마다 function을 실행한다고 생각할 수 있다.

emotion.js

  • css prop을 쓰는 것이 emotion의 주요 특징이다.
import React from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/react';

interface ButtonProps {
  label: string;
  color: string;
  primary: boolean;
}

function Button({ label, color }: ButtonProps) {
  const handleClick = () => {
    alert('Clicked button!');
  };
  return (
    <button
      css={css`
        padding: 32px;
        font-size: 24px;
        color: ${color};
        font-weight: bold;
        background-color: green;
        &:hover {
          background-color: green;
        }
      `}
      onClick={handleClick}
    >
      ${label}
    </button>
  );
}

export default Button;
  • styled prop으로 styled components 처럼도 사용할 수 있다.
import React from 'react';
import styled from '@emotion/styled'

interface ButtonProps {
  label: string;
}

function RoundButton({label}: ButtonProps) {
  // code
  // ...
  
  return <ButtonStyle label={label}> This is button component </ButtonStyle>;
}

const ButtonStyle = styled.button<ButtonProps>`
  color: turquoise;
  label: ${props => props.label || ""};
`;
  • 두 특성을 통해 string style, object style 방식을 모두 사용 가능하다.

비교

  • trend를 봤을 땐 emotion.js 인기가 쉽게 늘지 않고 있다. 실제로도 documentation을 보며 특징을 분석해봤으나 장점이 쉽사리 드러나지 않는다.

  • 웹 상에서 돌아다니는 장점으로 build하였을 때 bundle size가 emotion이 작다고 한다. 그러나 styled component에서 개선 중이어서 비슷해지거나 더 좋아질 수 있는 여지가 있어보인다.

  • 그래도 emotion.js 쓰면서 주관적으로 편했던 것은,
    component에 style을 css prop으로 넘겨주면서 조금 더 직접적으로 HTML tag와 함께 볼 수 있었다. styled component는 component 밖에서 선언하고 component 안에서 tag 호출처럼 사용해서 실제 HTML tag가 뭔지 style이 뭔지 보려면 선언 부분으로 갔어야 했다.

profile
Front-end developer

0개의 댓글