로고 라이트 모드

CSS 길이 단위 이해하기 (상대/절대/뷰포트 단위)

2025년 11월 2일 • 김소원 CSS 길이 단위 썸네일

CSS에서 사용하는 길이 단위의 종류와 특징을 이해하고, 절대 단위, 상대 단위, 뷰포트 단위 각각의 사용법과 장단점을 알아보며, 실무에서 효율적으로 활용하는 방법을 정리합니다.

***

해당 포스트는 원문: Making Sense of CSS Length Units에 대한 번역을 읽고 정리했습니다.


CSS 할때 px 단위 쓰면 안 된다고 합니다. 몰랐어

그 이유에 대해서 알아볼까요?

절대 단위

다른 요소(화면 크기, 해상도 등)와 관계 없이 일반적으로 ‘항상 동일한 크기’로 간주되는 단위를 말한다. cm, mm, q, in, pc, pt (순서대로 센티미터, 밀리미터, 쿼터밀리미터, 인치, 피카(1/6인치), 포인트(1/72인치))가 있는데, 이는 주로 인쇄용으로 권장되는 단위이다.

그 중에서도 px(픽셀)은 화면에서 표현할 수 있는 가장 작은 점을 의미하는데…

응? 하지만 고해상도의 레티나 디스플레이가 등장하면서, 오늘날의 픽셀은 실제 모니터의 물리적 픽셀이 아니라 CSS가 정의한 가상의 픽셀을 의미하게 된다. 더 이상 픽셀이 절대적인 단위가 아니라는 뜻이다. 즉, px은 더 이상 실제 물리 픽셀과 1:1 대응되지 않으며, 디바이스 픽셀 비율(DPR)에 따라 다르게 표현될 수 있는 단위이다.

해상도에 따른 도트 수 비교

그러면 왜 절대 단위보다 상대 단위를 사용하는 것이 더 현명한 선택일까?

초창기 컴퓨터 프린터는 인치당 1/72의 작은 점을 인쇄할 수 있었기 때문에, 저해상도 프린터에서 1pt가 1도트에 해당했다. 하지만 요즘 프린터는 인치당 150, 300, 600, 1200까지 인쇄할 수 있다. 이렇게 기기마다 1 포인트에 사용되는 도트의 개수가 다르다. 따라서 프린터의 해상도와 관계없이 페이지가 의도한 대로 인쇄되길 원하기 때문에 다른 측정 방법이나 상대 단위를 사용해야 하는 것이다.

Dot Per Inch

상대 단위

상대 단위에는 어떤 선택지가 있을까?

  • %

    퍼센트는 부모 요소를 기준으로 하므로 비교적 이해하기 쉽다. 하지만 무엇이 부모로 간주되는지 상황에 따라 다를 수 있으므로 주의가 필요한 단위이다. 보통 명확하지만 요소의 position이 absolute일 때 다루기 까다롭다.

  • rem

    루트(html) 요소의 글꼴 크기를 기준으로 한 비율 단위이다. 컴포넌트가 어디에 있든 항상 동일한 크기를 유지할 수 있다. 기본적으로 브라우저의 기본 글꼴 크기가 16px 이므로, 1rem16px이라고 생각하면 되는데, 다음과 같이 설정하면 1rem10px이 되어 계산이 간단해진다.

    html {
        font-size: 62.5%;
    }
    body {
        font-size: 1.6rem;
    }
  • em

    부모의 글꼴 크기를 기준으로 한 비율 단위이다. (특히 ‘m’ 문자의 너비를 참조) 예를 들어, 2em은 현재 글꼴 크기의 두 배가 된다. CSS 컴포넌트를 만들 때 크기가 부모 컨테이너의 영향을 받는다는 문제가 있다.

왜 픽셀을 쓰지 않을까?

앞서 픽셀은 이제 더 이상 물리적인 단위가 아니며, 디바이스 픽셀 비율(DPR)에 따라 표현 크기가 달라질 수 있다고 설명했는데 왜 결국 픽셀 대신 rem과 같은 단위를 사용해야 한다고 하는 걸까?

브라우저의 글꼴은 16px이 기본이지만, 사용자는 얼마든지 접근성 설정에서 글꼴 크기를 커스텀할 수 있다. 하지만 레이아웃이 px 기준이면 사용자의 설정을 무시하여, 레이아웃이 깨지거나 글자가 너무 작아질 수 있다.

뷰포트 단위

[s,l,d] v [h,w,i,b,min,max]는 웹 페이지의 표시 영역(뷰포트)을 기준으로 하는 24가지 단위이다.

  • *vh 는 뷰포트의 높이, *vw 는 너비를 의미한다.
  • *vmin*vmax 는 각각 뷰포트 치수 중 작은 값과 큰 값을 기준으로 한다.
  • *vi (인라인)와 *vb (블록)는 텍스트 방향에 따라 너비 또는 높이를 나타낸다. 영어처럼 가로쓰기 언어에서는 vivh, vbvw 와 같지만, 일본어처럼 세로쓰기 언어에서는 반대가 될 수 있다.

뷰포트 단위 예시

  • sv* (small)은 브라우저 컨트롤이 표시되는 디바이스 뷰포트의 크기이다.
  • lv* (large)은 브라우저 컨트롤이 숨겨져 있을 때의 뷰포트 크기이다.
  • dv* (dynamic)은 현재 뷰포트(작든 크든)를 나타낸다. 이는 뷰포트 전체 높이에 꼭 맞는 레이아웃을 만들려고 할 때 중요하지만, 컨트롤이 사라지는 즉시(예를 들어 사용자가 스크롤을 시작) 변경된다. s|l|d 를 지정하지 않으면 v*lv* (large)와 같다.

특이한 단위

좀 더 특수한 용도의 단위들도 있다. 이는 모든 브라우저에서 지원되는 것은 아니다.

  • ch: ‘0’ 문자의 너비
  • ex: ‘x’ 문자의 높이
  • cap: 대문자 높이(텍스트 옆에 아이콘을 맞출 때 유용)
  • ic: 한중일 문자의 ‘물(水)’ 너비
  • lh: 부모 요소의 줄 높이
  • rlh: 루트 요소의 줄 높이

핵심 정리

다음 세 가지 정도만 기억해도 충분하다.

  • 인쇄용 디자인에는 정확한 크기(mm 등)를 사용한다.
  • 웹 페이지에서는 rem 을 쓰면 크기 조정이 쉽고, 1rem=10px 로 설정하는 것도 고려해볼 만 하다.
  • 웹 애플리케이션에서는 뷰포트 단위를 활용해 레이아웃을 잡는 것이 좋다.

음 지난 프로젝트에서 모바일 메뉴 바에서 사파리의 브라우저 컨트롤(도구 막대) 때문에 로그인 버튼이 바로 보이지 않는 문제가 있어 모바일에서만 로그인 버튼을 살짝 올리도록 디자인을 애매하게 수정했던 기억이 났다.

뷰포트 단위 개념에 대해 알게 된 지금 디자인을 수정하지 않고도 모두를 만족시킬 수 있는 레이아웃 수정이 가능한지 살펴봐야 겠다는 생각이 든다.

***