[TIL 220115] CSS rem과 em의 차이점, WebAPI의 ResizeObserver란?

Ko Seoyoung·2022년 1월 15일
1

✅ Today I Learned

목록 보기
14/16

1. css rem과 em의 차이는 무엇일까?

절대단위와 상대단위

css에서 요소의 크기를 결정하는 단위는 2종류로 구분할 수 있다.
첫째는 다른 요소에 상대적이지 않고 고정된 값을 갖는 절대단위다. Ex) cm, mm, px 등
둘째는 부모 요소의 크기 또는 기본 html에 상대적인 상대단위가 있다. Ex) em, rem, vw, vh 등

vw, vh의 경우 viewport의 크기에 따른 %를 나타낸다. 따라서 50vw은 화면의 50%에 해당하는 크기다.
반면, rem과 em의 차이점은 정확히 몰랐기에 오늘 잠시 시간을 내어 알아보았다.

rem과 em의 차이

em 단위상위 요소의 글꼴 크기에 상대적이다.
반면 rem에서 "r"은 "root"를 나타내기 때문에, rem 단위HTML 문서의 루트 글꼴 크기에만 상대적이라는 차이가 있다.

예시

body {
  font-size:14px;
}

div {
  font-size: 2.5rem;
  height: 3rem;
}

위 예제에서 height:3rem의 단위가 rem인 경우와 em인 경우 어떤 차이가 있는지 알아보자.

div의 height가 3rem이라는 것은 div의 높이가 body 폰트 사이즈인 14px의 3배라는 뜻이다. 즉, 14px*3 = 42px

height가 3em인 경우 div의 높이가 div의 폰트 사이즈 2.5rem의 3배라는 뜻이다. 따라서 2.5rem3 = 7.5rem = 14px7.5rem = 105px

2. ResizeObserver

ResizeObserver는 요소의 content 또는 border box의 크기 변화를 감지하는 Web API다.
사용법: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver

진행중인 리액트 프로젝트에서 div의 크기가 변함에 다라 canvas를 resize시켜줘야해서 요소의 크기가 변화될때 canvas크기를 가져오는 로직을 짜고 싶었다.
그런데 창크기가 변경되는 경우는 window의 resize이벤트를 사용하면 되지만, 요소의 크기 변화를 알아내는 onResize같은 이벤트는 존재하지 않았다. 그러다 stack overflow에서 https://www.npmjs.com/package/react-resize-detector 이 npm package를 사용하면 된다고 했다.

그런데, 생각보다 간단할 것 같은데, 내가 구현할 수 있지않을까 라는 생각이 들어 깃허브 코드를 확인해봤다.
그리고 ResizeObserver가 사용되었다는 것을 알 수 있었고, ResizeObserver를 사용해 요소의 크기를 알아내는 커스텀 훅을 작성했다.

useResizeDetector 커스텀 훅

import { RefObject, useEffect, useRef, useState } from "react";

type SizeType = {
  width: number | undefined;
  height: number | undefined;
};

export const useResizeDetector = <T = any>(): SizeType & {
  ref: RefObject<T>;
} => {
  const ref = useRef<T>(null);

  const [size, setSize] = useState<SizeType>({
    width: undefined,
    height: undefined,
  });

  useEffect(() => {
    const callback: ResizeObserverCallback = (entries) => {
      entries.forEach((entry) => {
        const { width, height } = (entry && entry.contentRect) || {};
        setSize({ width, height });
      });
    };

    const resizeObserver = new ResizeObserver(callback);
    ref.current && resizeObserver.observe(ref.current as any);
    return () => resizeObserver.disconnect();
  }, []);

  return { width: size.width, height: size.height, ref };
};

사용법은 react-resize-detector npm 패키지와 같다.
물론 react-resize-detector는 ssr 등 여러가지 상황을 더욱 고려한 견고한 훅이다.
하지만 이렇게도 간단히 구현할 수 있다는 것을 기록해둔다.


Refs

https://www.geeksforgeeks.org/difference-between-em-and-rem-units-in-css/

profile
Web Frontend Developer 👩🏻‍💻 #React #Nextjs #ApolloClient

0개의 댓글