본문 바로가기

💻 개발자/✈️ React

[React] CSS in JS 방법론 (feat. Styled-Component)

반응형

1. CSS 방법론들의 특징 및 장단점

  특징 장점 단점
CSS 기본적인 스타일링 방법 - 일관된 패턴을 갖기 어려움,
!important의 남용
SASS
(preprocessor)
프로그래밍 방법론을 도입하여,
컴파일된 CSS를 만들어내는
전처리기
변수/함수/상속 개념을 활용하여 재사용 가능
CSS의 구조화
전처리 과정이 필요,
디버깅의 어려움이 있음
컴파일한 CSS 파일이 거대해짐
BEM CSS 클래스명 작성에 일관된 패턴을 강제하는 방법론 네이밍으로 문제 해결,
전처리 과정 불필요
선택자의 이름이 장황하고,
클래스 목록이 너무 많아짐
Styled-Component
(CSS-in-JS)
컴포넌트 기반으로 CSS를 작성할 수 있게 도와주는 라이브러리 CSS를 컴포넌트 안으로 캡슐화,
네이밍이나 최적화를 신경 쓸 필요가 없음
빠른 페이지 로드에 불리함

 

출처: https://orezytivarg.github.io/css-evolution-from-css-sass-bem-css-modules-to-styled-components/

 

2. 컴포넌트 기반 CSS 작성에 적합한 Styled-Component

Styled Component

Styled Component는 React의 컴포넌트 기반 개발 환경에서 스타일링을 위한 CSS의 성능 향상을 위해 탄생했다. Styled Componen를 사용하면 CSS 문법으로도 스타일 속성이 추가된 React 컴포넌트를 만들 수 있다. 예를 들어 Styled Component를 이용하여 애플리케이션 내에 다른 웹페이지로 이동하는 기능을 가진 Button을 하나 만든다면 아래 코드와 같을 것이다. 하나하나 살펴보면 JS(React), CSS와 크게 다르지 않다. JS에서 변수를 선언하듯(React에서 컴포넌트를 만들듯) Button을 만들고, tag의 속성을 정의하고, back-tick(``) 안에 기존 CSS 문법을 이용하여 스타일 속성을 정의해 주는 것뿐이다.

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

 

Styled Component 특징

  • Automatic critical CSS

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

 

 

  • No class name bugs

Styled Component는 스스로 유니크한 className을 생성한다. 이는 className의 중복이나 오타로 인한 버그를 줄여준다.

 

 

  • Easier deletion of CSS

Styled Component는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제된다.

 

 

  • Simple dynamic styling

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

 

 

  • Painless maintenance

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

 

 

  • Automatic vendor prefixing

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

 

 

Adapting based on props & Extending Styles

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

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

// Button component
...
  background: ${(props) => (props.primary ? "black" : "white")};
  color: ${(props) => (props.primary ? "white" : "black")};
...

// App component
...
  <Button>Normal</Button>
  <Button primary>Primary</Button>
...

또한 같은 스타일 속성을 지닌 여러 개의 컴포넌트들 중 몇 개의 컴포넌트에는 약간의 변화를 주고 싶은 경우도 있다. 이때에는 상속받고자 하는 스타일 속성을 지닌 컴포넌트를 style()로 감싼 뒤, 변경하고 싶은 속성만 새로 정의해 주면 기존 속성을 확장하여 사용할 수 있다.

// 기존의 Button 컴포넌트에 Apple 컴포넌트만을 위한 새로운 속성 추가

const Apple = styled(Button)`
  color: red;
  border-color: red;
`;

 

Passed props

아래의 코드에서 props로 color 속성이 전달된 Input 컴포넌트는 해당 color 속성이 글자색에 적용되고, props가 전달되지 않은 Input 컴포넌트는 기본 색상이 적용된다. 이처럼 컴포넌트에 props로 스타일 속성이 전달된다면 해당 컴포넌트는 props로 전달된 속성을 우선 적용하며, 전달되는 속성이 없다면 기본으로 설정된 속성을 적용한다. 이는  Styled Component가 개발자에 의해 설정된 속성과 기본 속성을 구분할 수 있기 때문이다.

...
// Input component
const Input = styled.input`
  padding: 1rem;
  margin: 0.5em;
  color: ${(props) => props.inputColor || "pink"};
  background: skyblue;
  border: none;
  border-radius: 2px;
`;
...

...
// App component
  <div>
    <Input defaultValue="아담" type="text" />
    <Input defaultValue="이브" type="text" inputColor="blue" />
  </div>
...

위와 같은 경우 Input(아담)의 글자색은 pink, Input(이브)의 글자색은 blue로 나타난다.

반응형