본문으로 건너뛰기

단위마다 기준

HTML·CSS 목차단위와 변수레슨 61 / 93

목차

CSS 단위는 저마다 크기를 재는 기준이 다릅니다. em은 가까운 글자 크기, %는 부모의 내용 칸, vw · vh는 화면을 기준으로 잽니다. 앞 레슨의 rem은 뿌리 요소의 글자 크기였습니다.

기준을 모르고 단위를 고르면, 목록 안 목록의 글자가 겹마다 커지거나 반으로 나눈 칸이 생각보다 좁게 나옵니다. 이 레슨은 단위마다 무엇을 따라 변하는지 보고, 그 크기가 무엇을 따라 변해야 하는지로 단위를 고르는 법을 봅니다.

그림 준비 중

1em은 가까운 글자 크기

em은 글자 크기를 기준으로 삼되, 뿌리 요소가 아니라 가까운 요소를 봅니다. font-size에 쓰면 부모의 글자 크기가, padding 같은 다른 속성에 쓰면 제 글자 크기가 기준입니다.

<div class="card">
  <p>잘 익은 김치를 씁니다.</p>
</div>
.card {
  font-size: 20px;
}

.card p {
  font-size: 0.8em;
  padding: 1em;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .card p의 font-size16px
  • .card p의 padding-top16px
  • 글자 크기 0.8em은 부모 .card의 20px에 0.8을 곱한 16px입니다.
  • 안쪽 여백 1em은 제 글자 크기 16px의 한 배입니다 — 부모의 20px이 아닙니다.

단추의 안쪽 여백을 em으로 주면 단추 글자가 커질 때 여백도 함께 넓어집니다. 그런데 글자 크기를 em으로 적은 요소가 겹치면, 겹마다 부모의 크기에 다시 곱해집니다 — 예제에서 봅니다.

2%는 부모의 내용 칸

width에 쓴 %는 부모 상자의 내용 칸 너비를 기준으로 잽니다(브라우저 규칙 6).

<div class="box">
  <div class="half">반</div>
</div>
.box {
  width: 300px;
}

.half {
  width: 50%;
  background: #d2d2d7;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .half의 너비150px

부모 내용 칸 300px의 50%라 150px입니다. 10단원 너비와 box-sizing에서 칸에 준 width: 100%도 '부모 내용 칸의 100%'라는 뜻입니다. 부모가 넓어지고 좁아지면 %로 적은 칸도 따라 늘고 줍니다.

3vw · vh는 화면

뷰포트(viewport)는 브라우저 창에서 페이지가 보이는 칸입니다. 1vw는 그 폭의 1%, 1vh는 높이의 1%입니다.

<div class="banner">
  레시피 노트
</div>
.banner {
  width: 50vw;
  background: #d2d2d7;
}
결과 화면폭 640px
잰 값개발자 도구에서 본 값
  • .banner의 너비320px

창 폭 640px의 50%라 320px입니다. 부모가 아니라 창이 기준이라, 어느 요소 안에 있든 같은 값입니다. 창 높이가 800px이면 50vh는 400px이고, 첫 화면을 꽉 채우는 칸은 min-height: 100vh처럼 씁니다(min-height는 가장 작은 높이 — 내용이 많으면 더 길어집니다).

최솟값 · 바라는 값 · 최댓값을 한꺼번에 주는 clamp()도 있습니다. 글자 크기를 clamp(1.25rem, 4vw, 2rem)⁠으로 주면 화면 폭의 4%를 쓰되 1.25rem보다 작아지지도, 2rem보다 커지지도 않습니다. 이 과목의 실습에서는 쓰지 않습니다.

4무엇을 따라 변해야 하는지로 고른다

단위는 그 크기가 무엇을 따라 변해야 하는지로 고릅니다. 무엇에도 흔들리지 않아야 하면 px입니다.

무엇단위까닭
글자 크기rem사용자의 글자 크기 설정을 따른다
줄 높이단위 없는 수(1.6)제 글자 크기의 몇 배라 글자와 함께 커진다
단추의 안쪽 여백em단추 글자와 함께 넓어진다
선 굵기 · 그림자 · 둥근 모서리px모양을 다듬는 값이라 그대로 둔다
칸 너비%부모 폭에 맞춰 늘고 준다
화면만큼vw · vh화면이 기준이다

예제

재료 목록 안 목록의 글자가 겹마다 커진다

재료를 묶음으로 나눈 목록입니다. 줄 글자를 본문보다 조금 크게 하려고 1.2em을 줬더니, 안쪽 줄일수록 글자가 커집니다.

<ul>
  <li>
    재료
    <ul>
      <li>
        채소
        <ul>
          <li>김치</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
li {
  font-size: 1.2em;
}
결과 화면
잰 값개발자 도구에서 본 값
  • li의 글자 배율1.2
  • li li의 글자 배율1.44
  • li li li의 글자 배율1.73

Computed 창에서 세 li를 차례로 고르면 font-size가 19.2px · 23.04px · 27.648px입니다(브라우저 글자 크기 설정이 처음 그대로일 때). 잰 값의 글자 배율로 보면 본문의 1.2배 · 1.44배 · 1.73배입니다. li 규칙 하나가 세 줄 모두에 닿았는데, 안쪽 li의 부모 ul이 바깥 li의 크기를 물려받아, 1.2배를 다시 1.2배 했습니다.

몇 겹이든 같은 크기여야 하니 뿌리 요소를 기준으로 하는 rem으로 고칩니다.

li {
  font-size: 1.2rem;
}
결과 화면
잰 값개발자 도구에서 본 값
  • li의 글자 배율1.2
  • li li의 글자 배율1.2
  • li li li의 글자 배율1.2

자주 틀리는 곳

틀린 생각: em은 rem처럼 어디에서나 같은 크기다.

<h2>
  <span class="tag">가</span>
</h2>
<p>
  <span class="tag">가</span>
</p>
h2 {
  font-size: 2rem;
}

.tag {
  font-size: 0.75em;
}
결과 화면
잰 값개발자 도구에서 본 값
  • h2 .tag의 글자 배율1.5
  • p .tag의 글자 배율0.75

같은 .tag 규칙인데 제목 안에서는 본문의 1.5배, 문단 안에서는 0.75배입니다. 제목 안이면 제목 글자 크기의 0.75배이기 때문입니다.

맞는 규칙: font-size의 em은 부모의 글자 크기를 기준으로 합니다. 어디에서나 같은 크기여야 하면 rem을 씁니다.

틀린 생각: height: 50%를 주면 부모 높이의 절반이 된다.

<div class="card">
  <div class="bar"></div>
</div>
.bar {
  height: 50%;
  background: #005bb5;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .bar의 높이0px

막대가 보이지 않습니다. 부모 .card의 높이가 정해져 있지 않으면(내용만큼) % 높이는 잴 바탕이 없어 auto, 곧 내용만큼으로 셈합니다. 빈 막대라 0px입니다.

맞는 규칙: % 높이는 부모의 높이가 정해져 있을 때만 그 몇 %가 됩니다.

틀린 생각: %는 부모가 차지하는 너비를 기준으로 한다.

<div class="box">
  <div class="half">반</div>
</div>
.box {
  width: 200px;
  padding: 40px;
  background: #f5f5f7;
}

.half {
  width: 50%;
  background: #d2d2d7;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box의 너비280px
  • .half의 너비100px

부모가 차지하는 너비는 280px인데 .half는 그 절반 140px이 아니라 100px입니다. 안쪽 여백은 셈에 들지 않습니다.

맞는 규칙: %는 부모의 내용 칸(여기서는 width의 200px)을 기준으로 합니다(브라우저 규칙 6).

확인 문제

1. 1절 예제에서 .card의 font-size를 25px로 바꾸면, 문단(p)의 위쪽 안쪽 여백은 몇 px일까요? 숫자만 쓰세요.

<div class="card">
  <p>잘 익은 김치를 씁니다.</p>
</div>
.card {
  font-size: 25px;
}

.card p {
  font-size: 0.8em;
  padding: 1em;
}
힌트

먼저 p의 글자 크기를 셈하고, padding의 em이 누구의 글자 크기를 보는지 1절에서 찾아보세요.

정답

20입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • .card p의 font-size20px
  • .card p의 padding-top20px
  • p의 글자 크기는 부모 25px의 0.8배인 20px이고, padding: 1em은 제 글자 크기 20px의 한 배입니다.
  • 흔한 오답은 25입니다. 여백의 em도 부모의 글자 크기를 본다고 본 것입니다. font-size 밖의 em은 제 글자 크기를 봅니다.

2. 카드 안 사진 자리의 너비를 카드 내용 칸의 절반으로 하려 합니다. 카드 너비가 바뀌어도 늘 절반이게 ____ 자리를 채우세요.

.card {
  width: 240px;
}

.photo {
  width: ____;
  height: 60px;
  background: #d2d2d7;
}
힌트

부모를 따라 늘고 주는 단위를 4절 표에서 찾아보세요.

정답

50%입니다.

<div class="card">
  <div class="photo"></div>
</div>
.card {
  width: 240px;
}

.photo {
  width: 50%;
  height: 60px;
  background: #d2d2d7;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .photo의 너비120px

240px의 50%라 120px이고, 카드 너비를 바꾸면 따라 바뀝니다. 120px로 적어도 지금은 같지만 카드가 바뀌면 따라가지 않습니다.

3. 플로우 카페 메뉴판입니다. '커피 4000' 줄의 글자는 본문 글자의 몇 배일까요?

<ul class="menu">
  <li>
    음료
    <ul>
      <li>커피 4000</li>
    </ul>
  </li>
</ul>
.menu li {
  font-size: 0.8em;
}
힌트

나무를 그려 '커피 4000' 줄에서 .menu까지 거슬러 오르며, 요소마다 글자 크기가 본문의 몇 배인지 적어 보세요.

힌트 둘

em은 부모의 글자 크기에 곱합니다. '커피 4000' 줄의 부모 ul은 '음료' 줄의 크기를 물려받았습니다.

정답

0.64배입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • .menu li li의 글자 배율0.64
  • '음료' 줄은 본문의 0.8배이고, '커피 4000' 줄은 그 부모 ul이 물려받은 '음료' 줄 크기의 0.8배라 0.8 × 0.8 = 0.64배입니다.
  • 흔한 오답은 0.8배입니다. em이 어디에서나 같은 크기라고 본 것입니다(em이 고정이라는 생각). em은 겹마다 부모의 크기에 곱해집니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 예제의 목록을 index.html과 style.css로 저장하고 link로 이어 엽니다(문서 뼈대의 body 안에 예제 HTML을 넣습니다). 목록을 한 겹 더 넣으면 넷째 줄 글자가 어떻게 될지 먼저 적고, 저장한 뒤 새로고침합니다. 그다음 1.2em을 1.2rem으로 바꿔 견줍니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

HTML·CSS 목차로