em과 rem은 언제 사용해야 할까


  • rm과 rem에 대해서 공부하고 정리한 내용입니다

  • size를 결정하는 단위는 크게 absolute length unit과 relative length unit 두가지로 나눌 수 있다

absolute length unit

  • absolute length unit에서 가장 많이 사용되는 단위는 px이다.

  • px는 모니터 위에서 화면에 나타낼 수 있는 가장 작은 단위로써 절대적인 값이다.

  • 따라서 font-sizepx로 설정한 경우 브라우저에서 글꼴 크기를 바꾸더라도 크기가 바뀌지 않는다

  • 또한 컨테이너의 사이즈가 변경되어도 컨텐츠가 고정된 값으로 유지되기 때문에 %를 이용해서 컨테이너의 크기에 상대적으로 변할 수 있도록 설정해준다

  • 이러한 문제점을 해결하기 위한 방법으로 %, vh, vw, em, rem과 같은 단위를 쓴다


relative length unit

  • em

    • relative to parent element

    • 현재 지정된 폰트 사이즈를 나타내는 단위

    • 같은 폰트 사이즈라고 해서 어떤 폰트 패밀리를 쓰느냐에 따라 사용자에게 보여지는 텍스트의 크기는 달라질 수 있다

    • 예를 들어 open sans 를 사용할 때와 roboto 사용할 때 알파벳 m이 사용자에게 보여지는 크기가 달라진다

    • em은 선택된 폰트 패밀리에 상관 없이 항상 고정된 폰트 사이즈를 가지고 있다

    • 예를 들어 폰트 사이즈가 16px이면 1em16px이 된다

    • em 단위는 사용된 요소의 폰트 크기에 따라 그 변환된 값이 정해진다

    • 아래와 같은 코드에서 padding 값을 확인해보면 폰트 사이즈와 같은 20px인 것을 확인할 수 있다

    ```html

    ```html

Parent


  - `em`은 부모의 폰트 사이즈에 상대적으로 크기가 계산이 되어진다

  - 아래 예제에서 기본적으로 브라우저에서 `html`에 할당되는 폰트사이즈는 `16px`이므로, 별도로 폰트 사이즈를 변경하지 않으면 `1em`은 `16px`이 된다.

  - 따라서 `parent`의 폰트 사이즈는 `16*8`인` 128px`, `child`의 폰트 사이즈는 `128px`의 절반인 `64px`이 된다

```html
<style>
  .parent {
    font-size: 8em;
  }
  .child {
    font-size: 0.5em;
  }
</style>

<body>
  <div class="parent">
    Parent
    <div class="child">Child</div>
  </div>
</body>

  • rem

    • relative to root element

    • 부모에 따라 폰트 사이즈가 결정되는 것이 아니라 루트에 지정된 폰트 사이즈에 따라서 크기가 결정된다.

    • 즉, html 요소의 폰트 사이즈가 rem 크기의 기준이 된다

    • 아래와 같은 경우, parent의 폰트 사이즈는 16*8 128px, child의 폰트 사이즈는 em을 사용했을 때와 달리 16px의 절반인 8px이 된다

<style>
  .parent {
    font-size: 8rem;
  }
  .child {
    font-size: 0.5rem;
  }
</style>

<body>
  <div class="parent">
    Parent
    <div class="child">Child</div>
  </div>
</body>
  • 기본적으로 html은 다음과 같은 폰트사이즈의 속성이 지정되어 있기 때문에 브라우저에서 지정된 폰트 사이즈에 따라 폰트 사이즈가 정해진다
html {
  font-size: 100%;
}
  • 따라서 브라우저 세팅에서 폰트 사이즈 변경하면 가변적으로 변한다

  • 반대로 html에서 폰트 사이즈 속성의 값을 변경해서 고정된 폰트사이즈를 사용하면 반응형으로 폰트 사이즈가 변경되지 않는다

html {
  font-size: 32px;
}

  • vhvw

    • 브라우저 너비와 높이에 대한 속성
    • 100vh는 브라우저 높이의 100을 나타낸다
    • 50vh는 브라우저 높이의 절반을 나타낸다
  • vmin

    • 브라우저의 높이와 너비중 작은 값을 기준으로 100분의 1을 한 값이다
    • 50 vmin 브라우저 너비와 높이 중에 작은 값의 50%
  • vmax

    • 브라우저의 높이와 너비중 큰 값을 기준으로 100분의 1을 한 값이다

    • 50 vmax는 브라우저 너비와 높이 중에 큰 값의 50%

  • 아래와 같은 예제에서 width:50% 인 경우에는 브라우저의 크기가 변할 때 부모 요소의 50%로 크기가 유지되지만 width: 50vw인 경우에는 부모 요소에 상관없이 브라우저의 너비에 따라 변한다

    <style>
      .parent {
        font-size: 8em;
        width: 500px;
      }
      .child {
        font-size: 0.5em;
        width: 50vw;
        background-color: beige;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      Parent
      <div class="child">Child</div>
    </div>
  </body>

상황에 따른 단위 선택

  • 부모 요소의 너비나 높이에 따라서 사이즈가 변경이 되어야 하는 경우 %em 를 사용하고

  • 부모와는 상관없이 브라우저 사이즈에 대해서 변경되어야 하는 겨우 v*rem 같은 단위 사용한다

  • 요소의 너비나 높이에 따라 사이즈가 변경이 되어야 한다면 %v* 같은 단위를 사용하고 폰트 사이즈에 따라 사이즈가 변경되어야 하는 경우 emrem을 사용한다


em vs rem

  • emrem은 디자인이나 구현해야 하는 기능에 따라 선택해서 사용한다

  • 예를 들어 Like 글자가 있는 버튼 컴포넌트를 만든다고 했을 때 해당 버튼이 가장 상위 컴포넌트에서 사용될 때와 자식 컴포넌트에서 사용될 때 모두 폰트 사이즈가 같아야 하는 경우처럼 어디에서 사용되던지 같은 폰트 사이즈를 가져야 하는 경우에는 rem 단위를 사용한다

  • 하지만 부모 요소에 따라서 사이즈가 변경되어야 하는 경우에는 em 단위를 사용한다

  • 그리고 아래 예제처럼 많은 부모 요소가 있는 경우 폰트사이즈가 레벨별로 바로 계산하기 쉽지 않다

  • 따라서 이러한 경우 em대신 rem 단위를 사용하면 폰트사이즈를 바로 계산을 할 수 있다

.level1 {
  font-size: 2em;
}

.level2 {
  font-size: 2em;
}

.level3 {
  font-size: 2em;
}

.level4 {
  font-size: 2em;
}
<body>
  <div class="level1">
    <h1>level1</h1>
    <div class="level2">
      <h2>level2</h2>
      <div class="level3">
        <h3>level3</h3>
        <div class="level4">
          <h1>level4</h1>
        </div>
      </div>
    </div>
  </div>
</body>
  • 또 다른 예제로 아래처럼 패딩으로 em 값을 사용할 수 있다
h1 {
  font-size: 5em;
  background-color: burlywood;
  padding: 0.1em;
  display: inline-block;
}
<body>
  <h1>Hello</h1>
</body>
  • 만약 패딩의 크기가 px로 정해져 있다면 폰트 사이즈가 작아지거나 커질 때도 패딩은 변하지 않게 된다

  • 폰트 사이즈는 em 을 단위로 하기 때문에 브라우저에 의해 폰트 사이즈가 크거나 작아질 수 있는데 이 때 패딩이 고정되어 있으면 글자가 작아지는 경우 패딩이 너무 크거나, 반대로 플자가 큰 경우에 패딩이 너무 작아보이는 경우가 생길 수 있다

  • 따라서 패딩도 폰트 크기에 따라서 바뀌어야 하기 때문에 픽셀보다는 em단위로 변경시켜 준다

  • 패딩을 em 단위로 설정하면 반응형에서도 화면의 크기에 따라 폰트 사이즈가 변경이 될 때 패딩도 변경된다

h1 {
  font-size: 5em;
  background-color: burlywood;
  padding: 0.1em;
  display: inline-block;
}

@media screen and (max-width: 780px) {
  h1 {
    font-size: 3em;
  }
}

  • 아래는 component라는 부모 요소안에서 emrem을 사용하는 경우이다
<section class="component">
  <header class="title">Hello</header>
  <p class="contents">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit quia amet,
    eaque ex, saepe vel modi rem cupiditate ullam officia officiis perferendis
    error pariatur dolore? Architecto totam voluptatem facilis odit.
  </p>
</section>
.component {
  width: 50%;
  border: 1px solid burlywood;
  font-size: 2rem;
}
.title {
  background-color: burlywood;
  padding: 0.5em;
}

.contents {
  font-size: 1rem;
  padding: 0.5em;
}

@media screen and (max-width: 780px) {
  .component {
    font-size: 1.5rem;
  }
}
  • component처럼 박스 컨테이너 자체의 사이즈를 만들 때에는 em이나 rem 보다는 %를 사용하는게 좋은데 그 이유는 emrem은 가변적으로 크기가 변하지만 폰트 사이즈에 비례해서 크기가 변경되기 때문에 결국 고정적인 값을 가지기 때문이다

  • 따라서 컨텐츠를 유동적으로 만들기 위해서는 %를 사용하는 것이 좋다

  • 패딩 값으로 em을 썼는데 em은 현재 폰트 사이즈에 따라 상대적으로 크기가 결정된다

  • 따라서 .title 의 폰트 사이즈는 2rem이므로, 패딩은 16px이 되고 .contents 의 폰트 사이즈는 1rem이기 8px이 된다

  • .title에 더 큰 패딩이 적용되어 수직적로 정렬이 되지 않는 것을 확인할 수 있다

  • 따라서 요소마다 사이즈에 상관없이 고정적인 패딩을 유지해야 되는 경우 rem을 써준다

  • .title 클래스에서 rem을 사용하는이유는 .title 클래스를 사용하는 요소들의 글자들이 어느 컴포넌트안에서 쓰이던지 상관없이 동일한 사이즈를 유지하기 위해서이다

  • 그리고 아래처럼 미디어 쿼리에서도 rem을 사용할 수 있다

@media screen and (max-width: 768px) {
  .container {
    flex-direction: column;
  }
}

@media screen and (max-width: 48em) {
  .container {
    flex-direction: column;
  }
}
  • pxmax-width를 정해놓으면 브라우저에서 폰트 사이즈를 크게 변경시켜도 동일하게 768px에서 세로로 요소가 정렬되기 때문에 반응형이 적용되기 직전에는 요소에 비해 폰트 사이즈가 너무 커서 레이아웃이 이상해지는 경우가 생길 수 있다

  • 따라서 48em과 같이 설정해 주면 더 자연스럽게 반응형으로 레이아웃이 변하게 된다

  • 이 때, rem 단위를 사용하지 않는 것이 좋은데 그 이유는 rem은 브라우저의 default font size를 사용하기 때문에 브라우저에 따라 다른 반응형으로 작동할 수 있기 때문이다


  • 결론적으로, 박스 자체의 사이즈를 결정할 때는 %v* 또는 flex 를 이용해서 유동적으로 만드는 것이 좋다.

  • 요소의 폰트 사이즈를 결정할 때는 root를 기준으로 사이즈가 변경되어야 하는 경우에는 rem을, 부모 요소에 따라서 사이즈가 변경되어야 하는 경우에는 em을 사용한다


Reference









© 2020. by dkmqflx

Powered by dkmqflx