본문 바로가기

Computer Science/CS 스터디

컴포넌트 스타일링 관리 : CSS-in-JS, CSS-in-CSS

반응형

들어가며

 

HTML이 처음 등장한 1991년에는 CSS가 없었으나, 디자인에 대한 요구가 커지며 CSS 탄생함

그러나 웹이 복잡해지고 동작 기능 요구가 증가하며 HTML과 CSS만으로는 모든 스타일을 제어할 수 없어짐

이를 해결하기 위해 여러 가지 스타일 구성 방식이 나타났으며 크게 CSS-in-JSCSS-in-CSS가 생김

 

CSS 문제점

  • Global namespace: 모든 스타일이 global에 선언되어 중복되지 않는 class 이름을 적용해야 하는 문제
  • Dependencies: css 간의 의존관계를 관리하기 힘든 문제
  • Dead Code Elimination: 기능 추가, 변경, 삭제 과정에서 불필요한 CSS를 제거하기 어려운 문제
  • Minification: 클래스 이름의 최소화 문제
  • Sharing Constants: JS 코드와 상태 값을 공유할 수 없는 문제
  • Non-deterministic Resolution: CSS 로드 순서에 따라 스타일 우선 순위가 달라지는 문제
  • Isolation: CSS와 JS가 분리된 탓에 상속에 따른 격리가 어려운 문제

 

CSS-in-CSS란?

 

CSS 파일 내부에서 CSS 스타일을 작성하는 방식

  1. CSS Module
    • CSS를 모듈화하여 사용하는 방식으로, CSS 클래스 이름 충돌 문제를 해결하는 방법 중 하나이다.
    • .module.css 확장자 사용
    .Box {
      background: black;
      color: white;
      padding: 2rem;
    }
    
    import React from "react";
    import styles from "./Box.module.css";
    
    function Box() {
      return <div className={styles.Box}>{styles.Box}</div>;
    }
    
    export default Box;
    
     
  2. SCSS
    • CSS 전처리기 : CSS 코드를 기계가 이해할 수 있는 일반적인 CSS 코드로 컴파일 해주는 역할
    • CSS 전처리기의 종류: Sass, Less, Stylus
    • SCSS는 Sass의 모든 기능을 지원하는 CSS의 상위 집합
    /* Sass : 선택자의 유효 범위를 '들여쓰기'로 구분 */
    
    .list
      width: 100px
      float: left
      li
        color: red
        background: url("./image.jpg")
        &:last-child
          margin-right: -10px
    
    /* SCSS : 선택자의 유효 범위를 '{}'로 구분 */
    
    .list {
      width: 100px;
      float: left;
      li {
        color: red;
        background: url("./image.jpg");
        &:last-child {
          margin-right: -10px;
        }
      }
    }
    
  3. Tailwind CSS
    • 유틸리티 퍼스트 CSS 프레임워크
    • 미리 정의된 클래스를 조합하여 빠르게 UI를 구성
    • 커스터마이징이 쉬워 큰 인기
    <button class="bg-palevioletred rounded-lg text-white p-2">
      Click Me
    </button>
    

 

CSS-in-JS란?

  • 자바스크립트 코드에서 CSS를 작성하는 방식
  • 별도의 파일로 작성하는 것이 아니라, 스타일 정보를 javascript에 포함시켜 컴포넌트 별로 스타일 관리 가능
  1. Styled-component
    • 가장 널리 사용되는 CSS-in-JS 라이브러리 중 하나
    • React와 잘 통합되어 있으며 동적인 스타일링과 테마 관리에 강점을 가지고 있음
    import styled from 'styled-components';
    
    const Button = styled.button`
      background: palevioletred;
      border-radius: 3px;
      border: none;
      color: white;
      padding: 0.5em 1em;
    `;
    
    function App() {
      return <Button>Click Me</Button>;
    }
    
    export default App;
    
    
  2. Emotion
    • 성능과 유연성에 중점을 둔 CSS-in-JS 라이브러리
    • Styled-components와 비슷하지만 더 많은 스타일링 방법을 제공
    • css 함수와 css prop 등을 통해 다양한 스타일 작성 방식이 가능함
    /** @jsxImportSource @emotion/react */
    import { css } from '@emotion/react';
    import styled from '@emotion/styled';
    
    const buttonStyle = css`
      background: palevioletred;
      border-radius: 3px;
      border: none;
      color: white;
      padding: 0.5em 1em;
    `;
    
    const Button = styled.button`
      ${buttonStyle}
    `;
    
    function App() {
      return <Button>Click Me</Button>;
    }
    
    export default App;
    
  3. JSS(Styled-JSS)
    • JavaScript 오브젝트를 사용하여 스타일을 작성하는 방법
    • React JSS와 함께 사용하면 React 컴포넌트 스타일을 적용하기에 용이
    import React from 'react';
    import { createUseStyles } from 'react-jss';
    
    const useStyles = createUseStyles({
      button: {
        background: 'palevioletred',
        borderRadius: 3,
        border: 'none',
        color: 'white',
        padding: '0.5em 1em'
      }
    });
    
    function App() {
      const classes = useStyles();
      return <button className={classes.button}>Click Me</button>;
    }
    
    export default App;
    
  4. Styled-JSX
    • Next.js에서 기본적으로 제공하는 CSS-in-JS 솔루션
    • JSX 내부에 스타일을 직접 작성
    export default function App() {
      return (
        <div>
          <button>Click Me</button>
          <style jsx>{`
            button {
              background: palevioletred;
              border-radius: 3px;
              border: none;
              color: white;
              padding: 0.5em 1em;
            }
          `}</style>
        </div>
      );
    }
    

 

 

마지막으로 장단점

 

 

CSS-in-CSS

장점

  • HTML, CSS, JS 가 구분되어 유지 관리가 쉬움
  • 전역 스타일을 쉽게 정의 및 관리 가능
  • 별도의 CSS 파일을 사용하면 브라우저 캐싱이 가능하여 성능이 향상됨
  • 전통적인 CSS 작성 방식으로 러닝 커브가 적음

단점

  • 전역 범위로 인해 클래스 명 충돌 가능성 있음 (CSS Module 사용하여 극복 가능)
  • CSS 만으로 상태에 따른 동작 스타일링 어려움 (JS를 사용하여 클래스 조작하거나 인라인 스타일을 활용해야 함)
  • 코드 재사용이 어려움 (전처리기로 극복 가능)

 

CSS-in-JS

장점

  • 컴포넌트 기반 구조로, 각 컴포넌트의 스타일을 독립적으로 관리 가능
  • JS를 사용하여 스타일을 생성하므로(=동적 스타일링), 상태에 따라 스타일 쉽게 변경 가능
  • 코드 재사용 및 모듈화가 가능하여 유지 보수 용이
  • 벤더 프리픽스를 자동으로 추가해주기 때문에 브라우저 호환성 유지에 용이

단점

  • CSS-in-CSS에 비해 러닝 커브가 있음
  • 웹 브라우저에서 CSS 파일을 캐싱할 수 없기 때문에 초기 랜더링 속도가 느릴 수 있음

벤더 프리픽스 : 브라우저 호환성을 위해 필요한 접두사를 의미 (transform 속성의 경우 chorme, safari 등의 브라우저에서 각각 -webkit-transform, -moz-transform 과 같은 접두사를 붙여나 하나 CSS-in-JS에서는 이를 자동으로 추가해줌 )

반응형