ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CSS] CSS를 대체할 CSS in CSS와 CSS in JS에 대해 알아보자 (CSS Module , SCSS 등)
    웹 개발/HTML & CSS 2021. 5. 11. 19:37
    반응형

     

    프로젝트가 커질수록 모든 html 요소에 클래스 naming을 해줘야하고

    컴포넌트 스타일을 변경할 때 클래스에 맞는 선택자를 일일히 찾아 변경해야하기 때문에 번거롭다.

    또한 JS 파일과 분리되어있기 때문에 컴포넌트의 상태값 변화를 공유하기 힘들다.

     

    CSS 문제점 (Vjeux)

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

     

    이러한 CSS의 불편함을 해결하기 위해 

    CSS-in-CSS 방식의 CSS Modules CSS-in-JS 방식을 사용한다.

     


    CSS-in-CSS 

    CSS Module와 SCSS는 CSS 파일의 단점을 해결해준다. 

    - pure CSS와 마찬가지로 전체 페이지에 필요한 CSS를 처음부터 전부 로딩하여 style 태그를 생성함

     

    1) CSS Module

     

    CSS Module를 사용하면 CSS 파일에 선언한 클래스 이름들이 모두 고유해지기 때문에 

    Global namespace 문제를 해결할 수 있다. 

     

    [예시]

     

    Box.module.css

    .module.css 확장자를 사용하여 CSS 모듈 파일을 생성해준다. 

    .Box {
      background: black;
      color: white;
      padding: 2rem;
    }

    Box.js

    Box component의 클래스 네임은 고유한 값인 _src_Box_module__Box가 된다. 

    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 Preprocessor (전처리기)는 CSS와 유사하지만 중첩, 조건문, 반복문 등 많은 기능을 제공하여

    CSS 작성을 편리하게 해준다.

    CSS 전처리기의 종류는 Sass, Less, Stylus가 있고

    SCSS는 Sass의 모든 기능을 지원하는 CSS의 상위집합(Superset) 이다.

     

    [원리]

     

    CSS 전처리기를 사용해 코드를 작성한 후 렌더링 시 웹에서 구동가능한 CSS로 컴파일하여 사용한다. 

     

    [예시]

     

    - Sass : 들여쓰기로 구분

    - SCSS : {}로 구분 

     

    CSS

    body {
      font: 100% Helvetica, sans-serif;
      color: #333;
    }
    
    

     

    SASS

    ** 상수값을 따로 지정해줌으로 코드 재사용성에 용이하다.

    $font-stack:    Helvetica, sans-serif
    $primary-color: #333
    
    body
      font: 100% $font-stack
      color: $primary-color
    

     

    SCSS

    $font-stack:    Helvetica, sans-serif;
    $primary-color: #333;
    
    body {
      font: 100% $font-stack;
      color: $primary-color;
    }

     

    추가적인 설명 및 코드작성

    https://heropy.blog/2018/01/31/sass/

     

    CSS-in-JS

     

    특정 js 파일에 css style을 추가한다.

     

    - 컴포넌트 라이프 스타일에 맞게 스타일을 적용할 수 있기 때문에 동적 스타일 적용에 자유롭다.

    - 특정 컴포넌트에 컴포넌트에 맞는 스타일이 종속되고, 해당 컴포넌트가 렌더링 될 때만 스타일 태그를 생성하기 때문에 컴포넌트 기반의 프레임워크를 사용할 때 용이함 

     

    [원리]

     

    CSS-in-JS에서는 클래스 이름을 따로 명명해주지 않는다.

    하지만 브라우저 랜더링시 webkit 엔진은 CSS 파일과 classname 태그를 기반으로 랜더링 트리를 생성하기 때문에 

    모든 CSS-in-JS는  CSS preprocessor를 내장한다.

    런타임 시 각 컴포넌트를 hashing하여 

    동적인 클래스 네임을 생성해주고 head 태그에 style 태그를 추가한다. 

     

    ** styled-components는 stylis (CSS preprocessor) 를 이용하고 있다.

     

    //js파일
    const Title = styled.h1 `
    	color : palevioletred;
    	font-size : 24px;
    `;
    
    <Title>
    	CSS-in-JS
    </Title>
    //클래스 네임 생성 후 
    
    .sc-cMWNzn {
    	color : palevioletred;
    	font-size : 24px;
    }
    
    <h1 class = "sc-cMWNzn>
    	CSS-in-JS
    </h1>

     

    [라이브러리]

     

    - Styled-components : 컴포넌트 기반 Framework에 최적화되어 있다.

    - Radium : inline style 방식, React에서 사용한다.

    - JSS : Framework 관계없이 사용가능, material-ui 에서 사용하다.

     


     

    결론

     

    컴포넌트 기반의 프레임워크가 성장하면서 CSS-in-JS 방식이 인기가 더 많아지고 있지만 

    둘 다 장 단점이 있기 때문에 서비스 환경에 맞게 사용해야한다.

     

    컴포넌트 위주의 프레임워크 

    CSS-in-CSS : 사용하지 않는 CSS 스타일 요소까지 로딩하기 때문에 비효율적이다. 

    CSS-in-JS : 필요한 컴포넌트 페이지의 CSS 스타일 요소만 로딩한다. 

     

    인터렉티브한 웹 사이트

     CSS-in-CSS : 랜더링할 때 모든 CSS 스타일 요소를 로딩하기 때문에 컴포넌트 상태가 변하더라도

    바로 적용이 가능하다.

    CSS-in-JS : 상태 변경으로 인한 랜더링 때마다 JS 파일 내의 CSS 코드를 로딩 (파싱 등)해야하기 때문에 성능이 떨어질 수 있다. (컴포넌트 내 인터렉티브한 변화는 다를 수 있다)

     

    콘텐츠가 많은 웹 사이트 

    콘텐츠가 많은 웹사이트의 경우 초기 랜더링 시간이 길어져버리면 유저가 불편함을 느낀다.

    CSS-in-JS를 사용할 경우 라이브러리를 설치해야하기 때문에 번들링 크기가 커져 초기 구동 속도가 늦어질 수 있다.

    이를 해결하기 위해 html이 먼저 렌더링 되는 서버사이드 랜더링을 사용한다고 해도 SSR를 위한 라이브러리를 설치해야하기 때문에 잘 고려해야한다. 

    **서버사이드 렌더링인 nextjs는 9.3버전 부터 CSS Modules 를 권장한다.

     

     

     

     

     


    출처 및 참고

     

    heropy.blog/2018/01/31/sass/

    velog.io/@dev-mish-mash/CSS-in-JS-%EA%B0%80-%EC%A2%8B%EC%9D%80-%EC%9D%B4%EC%9C%A0

    medium.com/@okys2010/%EB%AA%A8%EB%8D%98-css-1-css-in-js-c1c53d9bbbc9'

    www.youtube.com/watch?v=ufPCITfUQnQ&t=261s

    react.vlpt.us/styling/02-css-module.html

    반응형

    댓글

Designed by Tistory.