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.2li li의 글자 배율1.44li 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.2li li의 글자 배율1.2li 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.5p .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으로 바꿔 견줍니다.