박스와 간격
웹 화면을 아무리 들여다봐도 동그라미나 비스듬한 선은 드물다. 둥근 버튼도, 동그랗게 자른 얼굴 사진도 브라우저에게는 네모난 상자 하나다. 화면은 상자 안에 상자를, 그 안에 또 상자를 넣어 만든다. 그래서 웹 디자이너가 그리는 "간격"은 결국 상자와 상자 사이, 상자의 벽과 내용 사이의 거리다. 이 장은 그 상자를 네 겹으로 벗겨 보고, 상자의 폭이 어디까지인지, 위아래 간격이 왜 가끔 사라지는지 확인한다. 그리고 13, 17, 22 픽셀처럼 제각각이던 간격을 몇 개의 단계로 묶어, 시안을 그린 사람과 코드를 쓰는 사람이 같은 숫자로 말하게 한다.
- 화면의 요소를 상자로 보고, 상자 안의 상자(중첩)로 페이지를 읽는다.
- 박스 모델의 네 겹(내용, 안쪽 여백, 테두리, 바깥 여백)을 구별하고 상자가 실제로 차지하는 폭을 계산한다.
box-sizing의 두 방식이 "폭"을 어떻게 다르게 정의하는지 알고, 시안의 폭과 코드의 폭을 맞춘다.- 위아래 바깥 여백이 하나로 겹치는 마진 상쇄가 언제 일어나고 언제 일어나지 않는지 안다.
- 4·8 간격 단계를 만들고, "안쪽 간격 < 바깥 간격" 규칙으로 정보를 묶는다.
모든 것은 상자다
브라우저는 HTML 문서를 받으면 글 한 덩어리, 그림 하나, 버튼 하나마다 직사각형 영역을 하나씩 만든다. 이 영역을 상자(Box)라고 부른다. 상자의 크기와 위치를 정하는 일을 레이아웃(Layout)이라고 한다. CompositionBook에서 지면 위의 요소를 "놓는" 일을 레이아웃이라고 했는데(지면과 화면 구성), 웹에서는 그 일을 브라우저가 규칙에 따라 계산한다. 디자이너가 할 일은 그 규칙에 맞는 숫자를 주는 것이다.
상자는 혼자 있지 않다. 페이지 전체가 하나의 큰 상자이고, 그 안에 머리 띠와 본문과 바닥 띠가, 머리 띠 안에 로고와 메뉴 단추가 들어 있다. 상자 안에 상자가 든 이런 구조를 중첩(Nesting)이라고 한다. 아래는 책방 E의 모임 안내 페이지를 휴대폰 폭(360 CSS 픽셀, 2장)으로 그린 가상의 화면이다. "상자 보기"를 켜면 브라우저가 보는 대로 모든 상자의 테두리가 드러난다. 화면을 누르거나 끌면 손끝 아래의 가장 안쪽 상자가 골라진다.
화면을 상자로 보기
"상자만" 화면에서 본 것이 브라우저의 눈이다. 색과 글자를 지워도 페이지의 짜임은 그대로 남는다. 상자는 크게 두 가지로 놓인다. 제목, 문단, 그림처럼 위에서 아래로 한 줄씩 쌓이는 블록 상자(Block box)와, 문장 속 굵은 낱말이나 링크처럼 글줄 안에서 옆으로 흐르는 인라인 상자(Inline box)다. 블록 상자는 따로 정하지 않으면 부모의 폭을 가득 채우고, 높이는 안에 든 내용만큼 자란다. 위 화면의 요소들이 모두 폭 328로 같은 것도 그 때문이다. 폭은 바깥에서 정해지고, 높이는 안에서 정해진다. 이 비대칭이 웹 레이아웃의 첫 번째 성질이다. 종이 지면에서는 디자이너가 높이까지 정하지만, 웹에서는 글이 늘면 상자가 아래로 늘어난다.
박스 모델: 네 겹의 상자
상자 하나를 확대하면 네 겹이 있다. 가운데에 글이나 그림이 들어가는 내용 영역(Content)이 있고, 그것을 안쪽 여백(Padding, 패딩)이 감싼다. 안쪽 여백은 상자의 바탕색이 칠해지는 숨 쉴 자리다. 그 바깥에 테두리(Border, 보더)가 있고, 맨 바깥에 이웃한 상자를 밀어내는 투명한 바깥 여백(Margin, 마진)이 있다. 이 네 겹으로 상자의 크기와 간격을 정하는 규칙을 박스 모델(Box model)이라고 한다. 출처는 W3C의 CSS 명세다(CSS 2.1의 8장, 지금은 CSS Box Model Module Level 3로 이어진다).
CSS로는 네 겹을 각각 따로 적는다. 아래는 모임 안내 카드 하나를 적은 예다. 값을 하나만 쓰면 위·오른쪽·아래·왼쪽 네 변에 같은 값이 들어가고, 네 개를 쓰면 시계 방향(위, 오른쪽, 아래, 왼쪽)으로 들어간다.
.event-card {
width: 240px; /* 내용 영역의 폭(기본 방식에서) */
padding: 16px; /* 안쪽 여백: 네 변 모두 16 */
border: 2px solid #22342a;
margin: 0 0 24px; /* 바깥 여백: 위 0, 양옆 0, 아래 24 */
}
그렇다면 이 카드는 화면에서 폭을 얼마나 차지할까. 아래 시뮬레이터에서 상자 아래쪽 가장자리의 손잡이 셋을 위아래로 끌면 안쪽 여백(초록), 테두리(노랑), 바깥 여백(주황)의 두께가 바뀐다. 두께는 네 변에 똑같이 들어간다. 슬라이더는 CSS의 width 값이다. 위쪽의 세 치수선이 내용 폭, 눈에 보이는 폭, 차지하는 폭을 보여 준다.
네 겹을 끌어 보는 박스 모델
기본 방식에서 width는 상자의 겉 폭이 아니라 내용 영역의 폭이다. 안쪽 여백과 테두리는 그 바깥에 더해진다. 식으로 쓰면 다음과 같다.
width(기본 방식에서 내용 폭), \(p\): 안쪽 여백, \(b\): 테두리 두께, \(m\): 바깥 여백. 네 변의 값이 같다고 둔 식이다. 왼쪽과 오른쪽 값이 다르면 \(2p\) 대신 \(p_{\text{왼}} + p_{\text{오}}\)처럼 더한다.바깥 여백은 바탕색이 칠해지지 않으니 눈에 보이지 않는다. 그래서 시안을 보고 "카드 사이가 24"라고 읽은 것이 코드에서는 위 카드의 바깥 여백 24일 수도, 두 카드의 바깥 여백 12씩일 수도, 부모 상자의 간격 속성 24일 수도 있다. 눈에 같은 간격이 코드로는 여러 방법으로 만들어진다는 것, 그리고 방법마다 다르게 행동한다는 것이 이 장 뒷부분의 주제다.
outline(키보드로 고른 요소의 초점 표시에 자주 쓰는 바깥선)과 box-shadow(그림자)는 테두리 바깥에 그려질 뿐 자리를 차지하지 않는다. 그래서 그림자를 크게 줘도 옆 상자가 밀려나지 않고, 대신 옆 상자 위로 겹쳐 그려질 수 있다. 초점 표시를 테두리 두께로 만들면 초점이 들어올 때마다 상자가 몇 픽셀씩 커져 주변이 흔들리는데, outline은 그런 일이 없다. 7장(컴포넌트와 상태)에서 초점 표시를 다시 다룬다. 또 하나, 안쪽 여백과 바깥 여백을 퍼센트로 쓰면 위아래 값도 부모의 폭을 기준으로 계산된다. 높이가 아니다. 이 성질을 이용해 폭에 비례하는 높이를 가진 상자를 만들던 시절이 있었고, 지금은 aspect-ratio 속성이 그 일을 대신한다.
폭은 어디까지인가: box-sizing
앞 시뮬레이터에서 본 두 방식은 CSS의 box-sizing 속성으로 고른다. 기본값 content-box는 width를 내용 폭으로, border-box는 width를 테두리까지의 폭으로 읽는다. 앞의 것은 CSS 초기 명세의 정의이고, 뒤의 것은 디자이너가 "폭"이라고 말할 때 떠올리는 것에 가깝다. 시안에서 "카드 폭 240"이라고 적으면 대개 눈에 보이는 카드의 바깥 테두리까지를 뜻하기 때문이다. 이 차이가 어떤 사고를 내는지 보자. 폭 344의 상자 안에 카드 두 장을 width: 50%로 나란히 놓았다. 카드에 안쪽 여백과 테두리를 준다.
50% 두 장이 한 줄에 들어갈까
퍼센트 폭과 고정 여백을 섞는 순간 content-box는 계산을 어렵게 만든다. 50%와 32픽셀을 더한 값은 부모 폭이 바뀔 때마다 달라지기 때문이다. 그래서 오늘날 많은 사이트가 스타일시트 맨 앞에 모든 요소를 border-box로 바꾸는 규칙을 둔다. 이 규칙은 널리 퍼진 관례이고, 시안의 숫자와 코드의 숫자를 같은 뜻으로 만든다.
/* 모든 상자의 width·height를 테두리까지의 크기로 읽는다 */
*, *::before, *::after {
box-sizing: border-box;
}
사라지는 간격: 마진 상쇄
지후가 서윤의 시안을 코드로 옮기다 처음 부딪히는 것이 이것이다. 제목 아래에 바깥 여백 24를, 그 아래 문단 위에 바깥 여백 16을 주었다. 둘 사이 간격은 40이어야 할 것 같은데, 화면에서 재면 24다. 16은 어디로 갔을까.
일반적인 문서 흐름에서 위아래로 맞닿은 두 블록 상자의 바깥 여백은 더해지지 않고 큰 쪽 하나로 겹친다. 이것을 마진 상쇄(Margin collapsing)라고 한다. CSS 2.1 명세(8.3.1절)의 규칙이고, 원래는 글 문서를 위한 배려였다. 문단마다 위아래에 1줄씩 여백을 주더라도, 문단과 문단 사이가 2줄로 벌어지지 않고 1줄로 유지된다. 책의 단락 간격처럼 동작하게 만든 것이다. 아래에서 두 바깥 여백을 바꾸고, 두 상자가 놓인 방식을 바꿔 본다.
더해질까, 겹칠까
마진 상쇄는 형제 사이에서만 일어나지 않는다. 부모 상자에 안쪽 여백도 테두리도 없으면, 첫 자식의 위 바깥 여백이 부모 밖으로 빠져나가 부모의 바깥 여백과 겹친다. 카드 안 첫 제목에 위 여백 24를 주었는데 카드 안쪽이 아니라 카드 위쪽이 벌어지는 일이 그렇게 생긴다.
display: flow-root로도 같은 둑을 만들 수 있다.마진 상쇄는 버그가 아니라 명세에 적힌 동작이다. 하지만 시안을 그리는 사람에게는 직관에 어긋나고, 상자 하나를 옮기면 이웃 간격이 함께 바뀌어 예측하기 어렵다. 그래서 요즘의 레이아웃은 바깥 여백보다 부모 상자의 gap 속성을 즐겨 쓴다. 플렉스박스와 그리드 상자에서 gap: 24px을 주면 자식들 사이에만 24가 들어가고, 맨 앞과 맨 뒤에는 들어가지 않으며, 겹치지도 않는다. 플렉스박스의 gap은 2021년 무렵부터 주요 브라우저가 모두 지원한다.
gap으로 정한다. 또는 "앞에 형제가 있는 요소에만 위 여백을 준다"는 선택자(.stack > * + *)를 쓴다. 마지막 방법은 헤이든 피커링(Heydon Pickering)이 2014년 A List Apart에 쓴 글 「Axiomatic CSS and Lobotomized Owls」로 널리 알려졌다. 어느 쪽이든 핵심은 같다. 두 상자 사이의 간격을 정하는 사람은 한 명이어야 한다.
간격 체계: 4와 8
서윤의 첫 시안에는 간격이 13, 17, 22픽셀처럼 제각각이었다. 서윤에게는 이유가 있었다. 눈으로 보며 조금씩 밀고 당겨 "딱 좋아 보이는" 자리를 찾은 결과다. 하지만 지후에게는 그 숫자들이 재현할 수 없는 소음이었다. 13과 15의 차이가 의도인지 손떨림인지 알 길이 없고, 화면이 하나 늘 때마다 새로운 숫자가 생긴다. 해결책은 미리 정한 몇 개의 값만 쓰는 것이다. 이런 값의 목록을 간격 단계(Spacing scale)라고 한다.
단계를 만드는 방법은 여러 가지다. 아래에서 네 가지 방법을 비교한다. 막대 하나가 한 단계이고, 오른쪽 숫자는 바로 아래 단계와의 비다. 슬라이더는 "옆 단계와 구별되는 최소 비"라는 이 장의 문턱이다. 비가 문턱보다 작은 쌍은 붉게 칠한다.
간격 단계 만들기
결과에서 원리 하나를 읽을 수 있다. 사람은 길이의 차이를 절대량보다 비율로 느끼는 경향이 있다. 4와 8의 차이는 분명하지만, 44와 48의 차이는 같은 4픽셀인데도 거의 보이지 않는다. 지각 심리학에서 베버의 법칙(Weber's law)이라고 부르는 오래된 근사와 같은 방향이다. 그래서 좋은 간격 단계는 작은 쪽은 촘촘하고 큰 쪽은 성기다. 이 책이 정한 단계는 다음과 같다.
| 단계 | 값(px) | 아래 단계와의 비 | 주로 쓰는 곳(서윤의 첫 안) |
|---|---|---|---|
| 1 | 4 | — | 아이콘과 글자 사이, 날짜 칩과 제목처럼 붙어 있어야 하는 것 |
| 2 | 8 | 2 | 제목과 그 아래 한 줄 설명, 입력 칸과 그 라벨 |
| 3 | 12 | 1.5 | 목록 항목 사이, 작은 단추 안쪽 여백 |
| 4 | 16 | 1.33 | 카드 안쪽 여백, 화면 양옆 여백, 카드 안 무리 사이 |
| 5 | 24 | 1.5 | 카드와 카드 사이 |
| 6 | 32 | 1.33 | 넓은 화면의 바깥 여백, 큰 카드 안쪽 여백 |
| 7 | 48 | 1.5 | 구획(행사, 신간)과 구획 사이 |
| 8 | 64 | 1.33 | 넓은 화면의 큰 구획 사이, 첫 화면 위아래 |
왜 하필 4의 배수일까. 여러 이유가 겹친다. 첫째, 나누기 쉽다. 4의 배수는 반으로, 다시 반으로 나눠도 정수가 남는 경우가 많아 가운데 맞추기나 반쪽 여백을 계산할 때 소수점이 덜 생긴다. 둘째, 2장에서 본 기기 픽셀 비율이다. CSS 1픽셀은 기기 픽셀 비율(DPR)이 1.5인 화면에서 1.5기기 픽셀이 된다. 13픽셀 간격은 19.5기기 픽셀이라 경계가 픽셀 사이에 걸려 살짝 흐려질 수 있지만, 짝수 값은 DPR 1.5, 2, 3에서 모두 정수가 된다. 셋째, 관례다. 구글의 머티리얼 디자인 지침을 비롯한 여러 디자인 체계가 8 단위 격자(작은 요소에는 4 단위)를 쓰고, 그 관례를 아는 개발자와 디자이너가 많다. 숫자 자체에 마법이 있는 것은 아니다. 5의 배수나 6의 배수로 만든 단계도 같은 일을 할 수 있다. 중요한 것은 목록이 짧고, 모두가 같은 목록을 쓰는 것이다.
단계를 정했으면 시안을 그 단계에 맞춘다. 그런데 기계적으로 가장 가까운 값으로 반올림하면 어떻게 될까. 아래는 서윤의 행사 목록 시안이다. 분홍 띠는 개발자에게 넘기는 시안에 그리는 간격 표시(흔히 "레드라인"이라고 부른다)다.
시안의 간격을 단계에 맞추기
간격 단계는 숫자를 줄이는 도구이지 판단을 대신하는 도구가 아니다. 시안의 13을 12로 바꿀지 16으로 바꿀지는 반올림이 아니라 그 간격이 하는 일로 정한다. 같은 일을 하는 간격은 같은 값, 다른 일을 하는 간격은 확실히 다른 값. 그러면 값의 종류가 줄면서 관계는 오히려 분명해진다.
간격으로 묶고 떼기
CompositionBook 4장에서 가까이 있는 것은 한 무리로 보인다는 근접의 원리를 봤고, 12장에서 그것을 "무리 안 간격은 좁게, 무리 사이 간격은 확실히 넓게"라는 지면의 규칙으로 옮겼다. 웹의 상자는 이 규칙을 한 겹 더 깊게 만든다. 상자 안에 상자가 있으니, 간격에도 층이 있다. 글자와 글자 사이, 줄과 줄 사이, 무리와 무리 사이, 카드의 테두리와 내용 사이, 카드와 카드 사이, 구획과 구획 사이. 이 층들이 안쪽에서 바깥쪽으로 갈수록 넓어지면 화면은 저절로 읽힌다. 이 장에서는 이것을 "안쪽 간격 < 바깥 간격" 규칙이라고 부른다.
카드 하나로 확인해 보자. 신간 카드 두 장이 나란히 있고(카드 사이 24로 고정), 카드 안에는 표지, [제목·저자], [가격·재고], 단추가 있다. 대괄호로 묶은 것이 한 무리다. 세 슬라이더로 무리 안 간격, 무리 사이 간격, 카드 안쪽 여백을 바꾼다. 점선 상자는 간격만 보고 눈이 묶을 법한 무리를 CompositionBook 12장과 같은 단순한 규칙으로 찾은 것이다.
안쪽 간격 < 바깥 간격
셋째 실험의 거짓 무리는 반올림 실수에서 흔히 생긴다. 시안에서는 분명 저자 아래가 넓었는데, 값을 옮기다 위아래가 바뀌면 화면이 엉뚱한 이야기를 한다. 넷째 실험의 결과는 조금 미묘하다. 카드 안쪽 여백은 카드 안의 어떤 무리 사이 간격보다 좁으면 안 된다. 그러면 내용이 카드 안의 이웃보다 카드의 벽에 더 가까워져 갇힌 느낌이 든다. 또 카드 안쪽 여백이 카드 사이보다 넓으면, 카드의 경계보다 카드 안의 빈자리가 더 크게 보여 카드들이 한 판으로 붙어 보인다. 바탕색이나 테두리가 있으면 덜하지만 방향은 같다.
이 규칙은 카드에만 쓰는 것이 아니다. 입력 칸과 그 라벨은 4~8로 붙이고, 라벨·입력 칸 묶음과 다음 묶음 사이는 16~24로 뗀다(9장 폼). 단추 안의 아이콘과 글자는 4~8로 붙이고, 단추와 단추 사이는 그보다 넓게 뗀다. 화면 어디서든 "이 둘은 한 편인가?"를 묻고, 한 편이면 가깝게, 아니면 확실히 멀게.
간격은 누구의 것인가
시안 속 간격 하나를 코드로 옮길 때, 그 간격을 어느 상자의 어느 속성으로 줄지 정해야 한다. 같은 24를 위 카드의 아래 바깥 여백으로 줄 수도, 아래 카드의 위 바깥 여백으로 줄 수도, 두 카드를 담은 부모의 gap으로 줄 수도 있다. 화면은 같아 보여도, 카드를 다른 페이지로 옮기거나 순서를 바꾸면 결과가 달라진다. 위 카드에 아래 여백을 박아 두면 그 카드는 어디에 놓이든 아래에 24를 끌고 다닌다. 목록의 마지막에 놓여도, 혼자 놓여도.
그래서 많은 팀이 이런 약속을 한다. 부품(컴포넌트)은 바깥 여백을 갖지 않는다. 부품 사이의 간격은 부품을 놓는 부모가 정한다. 카드는 자기 안쪽 여백만 알고, 카드끼리 얼마나 떨어질지는 목록이 gap으로 정한다. 그러면 같은 카드를 행사 목록에서는 24 간격으로, 첫 화면 배너 옆에서는 16 간격으로 다시 쓸 수 있다.
| 시안에서 본 간격 | 누가 정하나 | CSS | 마진 상쇄 |
|---|---|---|---|
| 카드 테두리와 내용 사이 | 카드 자신 | padding | 없음 |
| 카드 안 무리와 무리 사이 | 카드 안의 배치 상자 | gap(또는 아래 여백 한쪽만) | gap이면 없음 |
| 카드와 카드 사이 | 목록(부모) | gap | 없음 |
| 구획과 구획 사이 | 페이지(부모) | gap 또는 구획의 padding-block | 바깥 여백으로 주면 일어날 수 있다 |
| 화면 가장자리와 내용 사이 | 페이지 바탕 상자 | padding-inline | 없음 |
시안도 이 약속을 따르면 넘기기 쉽다. 간격마다 숫자만 적지 말고 그 간격의 역할을 적는다. "카드 사이 24", "구획 사이 48"처럼. 개발자는 역할을 보고 어느 상자에 줄지 정하고, 다음에 새 화면을 그릴 때 디자이너는 같은 역할에 같은 값을 다시 꺼내 쓴다. 간격이 체계가 되는 것은 숫자가 깔끔해질 때가 아니라 역할에 이름이 붙을 때다.
rem(뿌리 글자 크기의 배수, 기본 16px이면 1rem = 16px) 단위로 적으면 사용자가 글자 크기를 키울 때 간격도 함께 커진다. 4·8 단계는 rem으로 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4가 된다. 어느 간격을 글자와 함께 키우고 어느 간격을 고정할지는 글자 단계와 함께 정하는 것이 좋아서, 6장에서 토큰을 만들 때 다시 다룬다. 이 장의 값은 기본 글자 크기 16px 기준의 픽셀로 적었다.
서윤의 웹 개편 노트
열아홉 가지 간격을 여덟 단계로
2028년 1월 둘째 주. 서윤이 2장에서 정한 대로 첫 화면을 "다음 모임" 하나만 크게 두고 다시 그렸고, 행사 일정 시안도 휴대폰 폭으로 함께 넘겼다. 이틀 뒤 지후의 답장이 왔다. 시안 두 장에서 간격을 재 보니 서로 다른 값이 열아홉 가지(가상 자료)였다. 13, 15, 17, 22, 27… "13이랑 15가 다른 의도인가요? 아니면 같은 건데 손이 미끄러진 건가요?" 서윤은 대답하지 못했다. 눈으로 보며 하나씩 맞춘 값이라 어느 것이 의도인지 서윤 자신도 기억하지 못했다.
지후가 먼저 코드로 옮긴 행사 카드에는 문제가 더 있었다. width: 50%로 두 장을 나란히 놓았더니 둘째 카드가 다음 줄로 떨어졌다. 안쪽 여백 16과 테두리 1이 50% 바깥에 더해졌기 때문이다. 카드 제목의 위 바깥 여백은 카드 밖으로 새어 나가 카드 위쪽을 벌렸다. 두 사람은 이 장의 시뮬레이터로 원인을 하나씩 확인했고, 지후는 스타일시트 맨 앞에 모든 상자를 border-box로 바꾸는 규칙을 넣었다. 시안의 폭은 테두리까지를 잰 값으로 읽기로 했다.
간격은 서윤이 단계부터 정했다. 처음에는 4씩 더하는 열여섯 단계를 만들었지만, 40과 44, 44와 48을 나란히 놓고 보니 구별되지 않았다. 작은 쪽은 4씩, 큰 쪽은 비 1.33~1.5로 벌어지는 여덟 단계로 줄였다. 그다음 시안의 간격을 가장 가까운 단계로 반올림해 봤는데, 카드 사이와 카드 안쪽 여백이 둘 다 16이 되고 행사 제목과 첫 카드 사이가 구획 사이와 같은 24가 되어 버렸다. 숫자는 깔끔해졌는데 화면은 더 어수선해졌다. 서윤은 반올림을 버리고 간격마다 역할을 먼저 적은 뒤 값을 골랐다. CompositionBook 4장에서 첫 화면에 정했던 "무리 안 12, 무리 사이 40"도 다시 봤다. 40은 단계에 없다. "무리 사이는 무리 안의 3배 이상"이라는 당시의 기준(12 × 3 = 36)을 지키는 가장 가까운 단계는 48이라, 첫 화면 무리 사이를 48로 올렸다.
| 간격의 역할 | 첫 시안(가상) | 서윤의 선택 |
|---|---|---|
| 날짜 칩 → 제목, 제목 → 장소(무리 안) | 7, 9 | 4, 8 |
| 카드 안 무리 사이(장소 → 설명 → 단추) | 11, 22 | 16 |
| 카드 안쪽 여백 | 15 | 16 |
| 카드 사이 | 17 | 24 |
| 구획 제목 → 첫 카드 | 22 | 16 |
| 구획 사이(행사 → 신간) | 27 | 48 |
| 화면 양옆 여백(휴대폰) | 13 | 16 |
지후는 표를 받자마자 카드에서 바깥 여백을 모두 지우고, 목록과 페이지에 gap을 넣었다. "이제 카드를 어디에 옮겨도 간격이 따라오지 않아요." 서윤은 시안의 레드라인 옆에 숫자 대신 역할 이름을 적기 시작했다.
4·8·12·16·24·32·48·64
카드 안쪽 · 사이16 / 24
구획 사이48
상자 폭border-box
box-sizing: border-box, 시안의 폭은 테두리까지. 부품은 바깥 여백을 갖지 않고 간격은 부모의 gap으로 준다. 단계 밖의 값은 이유를 적은 예외로만.핵심 정리
- 브라우저는 모든 요소를 직사각형 상자로 만들고, 페이지는 상자 안에 상자가 든 중첩 구조다. 블록 상자의 폭은 바깥(부모)에서, 높이는 안(내용)에서 정해진다.
- 박스 모델은 내용, 안쪽 여백(padding), 테두리(border), 바깥 여백(margin)의 네 겹이다. 바탕색은 테두리 안쪽에 칠해지고 바깥 여백은 투명하다. outline과 그림자는 자리를 차지하지 않는다.
- 기본
content-box에서 width는 내용 폭이라 안쪽 여백과 테두리가 바깥에 더해진다.border-box는 width를 테두리까지의 폭으로 읽어 시안의 "폭"과 같은 뜻이 된다. - 일반 블록 흐름에서 위아래로 맞닿은 바깥 여백은 큰 쪽 하나로 겹친다(마진 상쇄). 부모와 첫 자식 사이에서도 일어나고, 플렉스·그리드 안에서는 일어나지 않는다. 간격은 한 사람(대개 부모의
gap)이 준다. - 간격 단계는 짧은 목록이다. 작은 쪽은 촘촘하게, 큰 쪽은 비율로 벌어지게(4·8·12·16·24·32·48·64). 시안을 맞출 때는 반올림이 아니라 간격의 역할로 값을 고른다.
- "안쪽 간격 < 바깥 간격": 무리 안 < 무리 사이 ≤ 카드 안쪽 여백 < 카드 사이 < 구획 사이. 간격이 뒤집히면 거짓 무리가 생긴다.
확인 퀴즈
1. box-sizing을 바꾸지 않은 상자에 width: 300px; padding: 20px; border: 2px solid; margin: 20px;를 주었다. 이 상자의 눈에 보이는 폭(테두리까지)은?
2. 일반 블록 흐름에서 위 문단에 margin-bottom: 32px, 바로 아래 문단에 margin-top: 24px을 주었다. 두 문단 사이의 간격은?
3. 신간 카드의 간격을 정했다. "안쪽 간격 < 바깥 간격" 규칙에 맞는 것은? (무리 안 / 카드 안 무리 사이 / 카드 안쪽 여백 / 카드 사이 순)
4. 간격 단계를 4의 배수로 만드는 까닭으로 이 장의 설명과 맞지 않는 것은?
출처
- W3C, Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification, W3C Recommendation, 2011. 8장 Box model, 8.3.1 Collapsing margins.
- W3C, CSS Box Model Module Level 3, CSS Box Sizing Module Level 3. 박스 모델의 네 영역과
box-sizing의 정의. - W3C, CSS Box Alignment Module Level 3. 플렉스·그리드 상자의
gap. - Heydon Pickering, "Axiomatic CSS and Lobotomized Owls", A List Apart, 2014.
* + *선택자로 간격을 주는 방법(요약). - Google, Material Design 지침의 8dp 격자(작은 요소 4dp) 관례. 이 책의 간격 단계는 그것을 복제한 것이 아니라 같은 관례 위에서 정한 예시다.
- 근접의 원리와 무리 간격 규칙: CompositionBook 4장, 12장.
- 이 장의 시안 값, 간격 개수, 구별 문턱, 무리 찾기 규칙은 교육용으로 만든 가상 자료와 단순 모형이다.