CSS in JS

Jelkov Ahn·2021년 10월 27일
0

React

목록 보기
10/10
post-thumbnail

CSS in JS 등장배경

CSS 구조화를 위한 다양한 시도중에 CSS in JS(Styled-Component) 가 나오게 되었다.

  • 기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전 분리해 사용할 수 있는 아주 단순한 패턴을 제공합니다.

CSS 방법론들의 특징, 장단점

Styled Component

사용 목적

  • 기존 CSS 문법으로 스타일 속성이 추가된 React 컴포넌트를 만들 수 있다.

예시

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
`;

Styled Component 특징

  • Automatic critical CSS ; 해당하는 컴포넌트를 자동 추적에서 삽입해준다.
    Styled Component 는 화면에 어떤 컴포넌트가 렌더링 되었는지 추적해서 해당하는 컴포넌트에 대한 스타일을 자동으로 삽입합니다. 따라서 코드를 적절히 분배해 놓으면 사용자가 어플리케이션을 사용할 때 최소한의 코드만으로 화면이 띄워지도록 할 수 있습니다.

  • No class name bugs ; 유니크한 이름 생성으로 중복이나 오타 확률 줄임.
    Styled Component 는 스스로 유니크한 className 을 생성합니다. 이는 className 의 중복이나 오타로 인한 버그를 줄여줍니다.

  • Easier deletion of CSS ; 컴포넌트 사용을 안할시에 컴포넌트를 삭제하면 스타일속성도 삭제 된다.
    기존에는 더 이상 사용하지 않거나 삭제한 컴포넌트에 해당하는 스타일 속성을 제거하기위해 CSS 파일 안의 className을 이리저리 찾아야 했습니다. 하지만 Styled Component 는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제됩니다.

  • Simple dynamic styling ; 직관적!!
    className을 일일이 수동으로 관리할 필요 없이 React 의 props 나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적입니다.

  • Painless maintenance; 유지보수가 좋다!!
    컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않습니다.

  • Automatic vendor prefixing
    개별 컴포넌트마다 기존의 CSS 를 이용하여 스타일 속성을 정의하면 될 뿐입니다. 이외의 것들은 Styled Component 가 알아서 처리해 줍니다.

Styled Component 설치

# with npm
$ npm install --save styled-components

# with yarn 
$ yarn add styled-components

Styled Component 에서는 package.json에 다음 코드를 추가하도록 권장하고 있습니다. 아래의 코드를 추가하면 여러 버전의 Styled Component가 설치되어 발생하는 문제를 줄여줍니다.

{
  "resolutions": {
    "styled-components": "^5"
  }
}

예시

import styled from "styled-components";

// <h1> 태그를 렌더링 할 title component를 만듭니다.
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// <section> 태그를 렌더링 할 Wrapper component를 만듭니다.
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

export default function App() {
  // 일반적으로 컴포넌트를 사용하는 것처럼 Title과 Wrapper를 사용하시면 됩니다!
  return (
    <Wrapper>
      <Title>Hello World!</Title>
    </Wrapper>
  );
}

Adapting based on props & Extending Styles

  • 스타일 속성을 지닌 컴포넌트를 정의할 때에 함수를 전달하고, 그 함수 안에서 props 를 사용할 수도 있습니다.

<Button> 컴포넌트의 background 와 color 속성은 primary 라는 props 의 전달 여부에 따라 컬러값을 정의하고 있습니다.

// Button component
...
  background: ${(props) => (props.primary ? "palevioletred" : "white")}; // primary props가 있는 경우/ 없는경우
  color: ${(props) => (props.primary ? "white" : "palevioletred")}; // primary props가 있는 경우/ 없는경우
...

// App component
...
  <Button>Normal</Button>
  <Button primary>Primary</Button>
...
  • 같은 스타일 속성을 지닌 여러개의 컴포넌트들 중 몇 개의 컴포넌트에는 약간의 변화를 주고 싶은 경우
    이때에는 상속받고자 하는 스타일 속성을 지닌 컴포넌트를 styled() 로 감싼 뒤, 변경하고 싶은 속성만 새로 정의해 주면 기존 속성을 확장하여 사용할 수 있습니다.
// 기존의 Button 컴포넌트에 Tomato 컴포넌트만을 위한 새로운 속성 추가
const Tomato = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

예시)

import "./styles.css";
import styled from "styled-components";

const Button = styled.button`
  /* Adapt the colors based on primary prop */
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

const Tomato = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

export default function App() {
  return (
    <div className="App">
      <Button>Normal</Button>
      <Button primary>Primary</Button>
      <Tomato>Tomato</Tomato>
    </div>
  );
}

Passed props

props 로 color 속성이 전달된 Input 컴포넌트는 해당 color 속성이 글자색에 적용되고, props 가 전달되지 않은 Input 컴포넌트는 기본 색상(여기서는 빨간색)이 적용된 것을 확인.

import styled from "styled-components";

// Styled Component로 만들어진 Input 컴포넌트 입니다.
const Input = styled.input`
 padding: 0.5em;
 margin: 0.5em;
 color: ${(props) => props.inputColor || "red"};
 background: papayawhip;
 border: none;
 border-radius: 3px;
`;

export default function App() {
 return (
   <div>
     {/* 아래 Input 컴포넌트는 styled component인 Input 컴포넌트에 지정된 inputColor(red)가 적용되었습니다.  */}
     <Input defaultValue="김코딩" type="text" />
     {/* 아래 Input 컴포넌트는 props로 전달된 커스텀 inputColor(blue)가 적용되었습니다. */}
     <Input defaultValue="박해커" type="text" inputColor="blue" />
   </div>
 );
}

출처 : 코드스테이츠

profile
끝까지 ... 가면 된다.

0개의 댓글