← 글 목록

notes

style - css framework or css-in-js

CSS Framework와 CSS-in-JS의 방식·장단점·선택 기준 비교 메모.

css framework

CSS framework는 웹 개발에서 사용되는 스타일 및 레이아웃을 구축하는 데 도움이 되는 라이브러리 또는 코드의 모음이다. 이러한 프레임워크는 일반적으로 웹 페이지의 디자인을 일관되게 만들고, 빠르게 개발할 수 있도록 도와주며, 브라우저 간의 호환성(반응형 및 크로스 브라우징 ,이미지 최적화 등등…)도 향상시 준다.

css framework도 사용 방식이나 내부 구조는 상이하게 다르다.

해당 글에선 이들의 특성과 어떤 프로젝트를 진행 하였을때 적합한지 생각하는 시간을 가져보려고 한다.

참고: 2022 기준 css framework 사용도 및 만족도 사이트

Utility-First

Bootstrap, Foundation, Bulma, Tailwind 등에서 사용하는 방식

사전정의 된 유틸리티 클래스를 활용하여 HTML 코드 내에서 스타일링 하는 방식

참고:https://tailwindcss.com/docs/width

예시: tailwind css width

<div class="w-96 ...">w-96</div>
<div class="w-80 ...">w-80</div>
<div class="w-64 ...">w-64</div>
<div class="w-48 ...">w-48</div>
<div class="w-40 ...">w-40</div>
<div class="w-32 ...">w-32</div>
<div class="w-24 ...">w-24</div>

장점

기본적인 UI 가이드가 존재 하므로 반응형 디자인을 쉽게 구현할 수 있습니다.

클래스명칭을 고민하지 않아도 된다.

반복되는 UI는 컴포넌트 추상화를 통해 재사용 가능하며 특정기능을 동작하는 버튼이나 요소를

작업시 용이, 확장성이 좋다.

단점

반복되는 구문이나 규칙성이 없어 가시성이 떨어진다.

다른 CSS 프레임워크 처럼 완성된 스타일 이나 컴포넌트를 사용하기 힘들다.

Component UI

Component가 미리 구현되어 있는형태의 프레임 워크로 스타일과 기능이 사전정의가 되어있다.

대표적으로 material ui , ant design등이 있다.

대부분의 framework가 Compound Pattern으로 되어있다.

참고:https://mui.com/material-ui/react-modal/

예시: material ui Modal Component

<Button onClick={handleOpen}>Open modal</Button>
<Modal
  open={open}
  onClose={handleClose}
  aria-labelledby="modal-modal-title"
  aria-describedby="modal-modal-description"
>
  <Box sx={style}>
    <Typography id="modal-modal-title" variant="h6" component="h2">
      Text in a modal
    </Typography>
    <Typography id="modal-modal-description" sx={{ mt: 2 }}>
      Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    </Typography>
  </Box>
</Modal>

장점

마크업과 스타일이 캡슐화 되어있어 바로 사용하기 용이하다.

기능이 미리 구현되어있어 코드 인라인이 줄어든다.

패키지 매니저로 인스톨후 바로 사용가능하여 추가적인 설정이 필요 없다.

가독성이 좋다.

단점

해당기능에 대한 요소의 확장성과 수정이 힘들다.

라이브러리에 있는 테마 기반으로만 디자인 할수 밖에 없다.

번들링시 리소스가 크다.

Headless UI

직역하면 머리가 없다. 라는 의미인데 기존 componentUI의 단점을 보완하기 위해 스타일이 입혀지지 않은 형태의 다양한 UI 컴포넌트들 제공해주는 framework 이다.

대표적으로 Headless UI,Radix UI , Reach UI 등이 있다.

크게 사용은 Utility-First 방식의 css framework와 합쳐 사용하는 경우가 있다.

참고:https://headlessui.com/react/tabs

예시: headless UI plus tailwind css

import { Fragment } from 'react'
import { Tab } from '@headlessui/react'

function MyTabs() {
  return (
    <Tab.Group>
      <Tab.List>
        <Tab as={Fragment}>
          {({ selected }) => (
            /* Use the `selected` state to conditionally style the selected tab. */
            <button
              className={
                selected ? 'bg-blue-500 text-white' : 'bg-white text-black'
              }
            >
              Tab 1
            </button>
          )}
        </Tab>
        {/* ...  */}
      </Tab.List>
      <Tab.Panels>
        <Tab.Panel>Content 1</Tab.Panel>
        {/* ... */}
      </Tab.Panels>
    </Tab.Group>
  )
}

css-in-js

자바스크립트로 스타일을 구성하여 tag를 생성하는 방식

css in css와 대조되는 형식으로 tag에 css로 스타일을 입히는 방식이 아닌 js로 스타일을 정의 하는 방식

styled-component ,Emotion , tailwind css 의 twin.macro Material UI의@mui/styled-engine 과 같은 기능이 있다.

성능상의 문제 ?

인터넷에 “css in js 성능” 이란 타이틀로 검색만 해도 많은량의 글들이 쏟아진다.

글의 내용들을 보면 css in css 방식이 css in js보다 성능상 이점이 있다.

라는 내용이 주측이다.

이는 브라우저 렌더링 과정을 통해 보면 이해하기 쉽다.

웹사이트 사용시 우리는 하나의 화면만을 보지만 내부를 보면

자바스크립트 엔진( v8 , 라이노, 웹큐 등등…)과

브라우저 엔진(게코,트라이언트 등등…)이 동작하게 된다

참고 이미지 :

javascript deep dive 38장 브라우저 렌더링 참고

브라우저는 html ,css , js 파일등 랜더링에 필요한 리소스를 요청하고 서버로부터 응답을 받는다.

브라우저 렌더링 엔진은 서버로부터 응답된 html과 css를 파싱 dom과 cssom을 생성, 이들을 결합하여 렌더트리를 생성

브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 ASTAbstract Syntax Tree를 생성하고 바이트코드로 변환하여 실행한다.

이때 자바스크립트는 DOM API를 통해 DOM이나 CSSOM을 변경할 수 있다. 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합된다. 렌더 트리를 기반으로 HTML 요소의 레이아웃(위치와 크기)을 계산하고 브라우저 화면에 HTML 요소를 페인팅한다.

참고 이미지 :

javascript deep dive 38장 브라우저 렌더링 참고

우리가 봐야 할점은 cssom이 생성되는 시점과 이를 파싱하는 부분이다.

css in css 방식으로 구현시 cssom 생성후 다시 렌더링 될 때는 해당 스타일 시트를 다시 파싱할 필요가 없다.

즉 랜더링이 발생하더라도 style이 바뀌지않는다면 리페인팅이나 리플로우가 발생하지 않는다.

참고 이미지 :

javascript deep dive 38장 브라우저 렌더링 참고

반대로 생각하면 style을 정의하는 part를 js가 처리하게 되면 화면을 랜더링할때 마다 js엔진이 동작

잦은 랜더링 발생시 성능 상 문제가 발생할 수있다.

그러면 쓰지 말라는 건가 ?

모든 부분에서는 장점과 단점이 있다.

css in js 방식은 css 로드 우선 순위 이슈 해결이나

컴포넌트 단위로 ui를 관리하는 프로젝트에서 css in js를 사용시 단일 파일에서 스타일을 관리

스타일 시트의 의존성을 낮춰 컴포넌트 별 관리가 용이해지는 이점과 Utility-First 방식과 같이

클래스 명칭 최소화 등의 이점을 볼수 있다.