웹 실험실
열두 장 동안 책방 E의 새 웹사이트를 한 겹씩 정했다. 기준 폭 대신 최소 폭 320, 4의 배수 간격 여덟 단계, 12단 그리드와 최대 폭 1,200, em으로 적은 중단점 둘, 원시와 의미 두 층의 토큰, 버튼의 다섯 상태와 44 px 터치 타깃, 펼친 탭 바, 네 칸짜리 신청 폼, 움직임 두 단계, 접근성 점검표, 첫 화면 500 KB 예산. 그런데 이 값들은 각 장에서 따로 정했다. 글자를 두 배로 키우면 중단점이 밀리고, 칩이 커지면 한 줄에 들어가는 날짜가 줄고, 기기 픽셀 비율이 높으면 같은 사진도 더 큰 파일을 받는다. 이 장은 가상의 페이지 하나를 작업대에 올려 놓고 그 값들을 한꺼번에 움직이는 실험실이다. 실험실은 정답 설정을 알려 주지 않는다. 지금 설정에서 단이 몇 개인지, 글줄이 몇 자인지, 가장 작은 타깃이 몇 픽셀인지, 대비와 무게와 첫 화면이 뜨는 시간이 얼마인지를 숫자로 보여 주고, 휴대폰과 넓은 화면을 나란히 놓아 눈으로 고르게 한다.
- 창 폭, 브라우저 확대, 글자 크기 설정이 단 수, 중단점, 글줄 길이를 어떻게 함께 바꾸는지 한 화면에서 확인한다.
- 간격 단계와 그리드, 색 토큰과 다크 모드, 포커스 표시를 같은 페이지 위에서 점검하고 기준(WCAG 2.2)과 견준다.
- 터치 타깃을 2.5.8의 24 px 하한과 서윤이 고른 44 px로 재고, 글자를 키울 때 부품이 어떻게 버티는지 본다.
- 사진·글꼴·스크립트 선택이 첫 화면 무게와 LCP(12장의 교육용 모형)에 미치는 영향을 기기 픽셀 비율까지 넣어 어림한다.
- 장마다 정한 값이 서로 부딪치는 곳을 찾아, 무엇을 기준으로 하나를 고를지 근거를 적는다.
실험실 사용법
실험실의 재료는 책방 E 새 사이트의 세 페이지다. 첫 화면(다음 모임 하나, 그 아래 행사 일정·이달의 책·신간), 행사 일정(날짜 칩 줄과 행사 카드), 모임 신청 폼(네 칸). 모두 이 책이 직접 그린 가상의 페이지다. 이 페이지는 진짜 웹 페이지가 아니라 캔버스 위에 그린 목업이다. 실험실 안에 장마다 정한 규칙을 단순한 계산으로 옮겨 두고(폭이 35 em을 넘으면 행 모양, 칩은 최소 44 px…), 설정이 바뀔 때마다 상자의 자리와 크기를 다시 계산해서 그린다. 그래서 진짜 브라우저와 몇 픽셀씩 다를 수 있지만, 무엇이 어디서 깨지는지는 같은 순서로 보인다.
설정은 여덟 갈래다. 화면 쪽에서는 기기 폭, 브라우저 확대(100·200·400%), 글자 크기 설정(100~200%). 배치 쪽에서는 짜임(고정 960 / 기기 중단점 768·1024 / em 중단점 35·56), 간격(첫 시안의 제각각 값 / 여덟 단계). 상호작용 쪽에서는 색 토큰, 포커스 표시, 부품 크기. 쓰임 쪽에서는 사진·글꼴·스크립트와 통신 조건이다. 각 갈래에는 장마다 처음 시도했던 값(첫 시안)과 서윤이 고른 값이 함께 들어 있다.
먼저 실험실이 얼마나 다른 두 페이지를 그릴 수 있는지 보자. 아래는 같은 첫 화면을 폭 360 휴대폰에 띄운 두 모습이다. 왼쪽은 장마다 처음 시도했던 값을 한데 모은 판이다. 고정 960 짜임, 제각각인 간격, 연회색 #999999 보조 글자, 포커스 표시 없음, 120×36으로 못 박은 버튼, 원본 사진. 실제로 이런 판이 한 번에 있었던 것은 아니고, 각 장의 첫 시도를 모은 견본이다. 오른쪽은 각 장에서 서윤이 고른 값이다. 가운데 막대를 끌어 비교한다.
두 판은 한두 가지가 아니라 여덟 가지가 함께 다르다. 그래서 "무엇 때문에 좋아졌는가"를 말하기 어렵다. 이 장의 앞부분은 그 여덟 갈래를 하나씩 떼어 낸 패널이다(각 패널은 앞 장의 시뮬레이터를 실험실 형식으로 다시 쓴 것이다). 마지막 절의 종합 실험실이 다시 모두를 한데 모은다.
폭 패널: 창 폭과 글자 크기가 짜임을 바꾼다
첫 패널은 2장과 5장을 한데 모은 것이다. 페이지의 짜임을 정하는 폭은 기기의 화면 폭이 아니라 CSS 뷰포트 폭(CSS viewport width)이다. 브라우저를 200%로 확대하면 같은 노트북 화면 1,280 px이 CSS로는 640 px이 된다. 그래서 확대는 화면을 좁게 만든다. 반면 휴대폰의 글자 크기 설정은 뷰포트 폭을 그대로 두고 rem의 크기만 키운다. em으로 적은 중단점은 rem을 따라 밀린다. 글자를 150%로 키우면 35 em 중단점은 560이 아니라 840 px에 선다.
아래 목업의 오른쪽 끝을 끌거나 기기 폭 막대로 폭을 바꾼다. 맨 아래 눈금자에는 지금 글자 크기에서의 두 중단점이 표시된다. 짜임을 "기기 중단점 768·1024"(5장에서 지후가 처음 넣은 값)로 바꾸면 중단점은 글자 크기와 상관없이 제자리에 있다.
폭 패널: 같은 첫 화면, 폭과 글자 크기
clamp() 식, 신간 카드는 4장의 minmax(240px, 1fr).)기기 중단점 짜임은 세 견본 폭(360·768·1280)에서는 멀쩡하지만 그 사이 폭에서 깨진다. em 중단점 짜임은 폭이 아니라 "글줄이 몇 자가 되는가"를 따라 짜임을 바꾸므로, 글자를 키운 사람의 화면에서도 같은 기준이 지켜진다. 대가도 있다. 글자를 200%로 키운 노트북에서는 넓은 화면인데도 아래에 탭 바가 붙는다. 서윤과 지후는 이것을 "글자를 키운 사람에게는 휴대폰 짜임이 더 읽기 좋다"는 뜻으로 받아들였다. 5장에서 도경이 했던 말과 같다.
간격·그리드 패널: 숫자가 아니라 역할로
3장의 간격 단계(4·8·12·16·24·32·48·64)와 "안쪽 간격 < 바깥 간격" 규칙, 4장의 12단·거터 24를 행사 일정 페이지 위에 겹쳐 본다. 분홍 막대는 간격, 붉은 띠는 단이다. 간격을 "첫 시안"으로 바꾸면 3장에서 지후가 재 본 제각각의 값(9, 11, 15, 17, 22, 27)이 들어간다.
그리드 단 수는 이 장에서 처음 정하는 값이 하나 있다. 4장은 넓은 화면의 12단만 정했고 좁은 화면의 단은 남겨 두었다. 실험실은 5장의 두 중단점에 맞춰 좁은 쪽부터 4단(거터 16) → 8단(거터 24) → 12단(거터 24)을 안내선으로 그린다. 4·8·12는 모두 신간 카드 수(1·2·3·4권)를 나누어떨어지게 하는 수다.
간격·그리드 패널: 행사 일정 페이지
"첫 시안"과 "여덟 단계"의 차이는 숫자가 깔끔해졌다는 것이 아니다. 3장에서 서윤이 겪었듯, 첫 시안의 값을 가장 가까운 단계로 반올림하기만 하면 화면은 오히려 어수선해진다. 실험실의 규칙 검사는 값이 단계에 있는지가 아니라, 무리 안 < 카드 안 < 카드 사이 < 구획 사이의 순서가 지켜지는지와 구획 제목이 자기 목록에 붙는지를 본다. 규칙을 깨는 곳은 언제나 있을 수 있다. 4장의 "이달의 책" 띠는 일부러 그리드를 깨고 화면 끝까지 간다. 깨는 곳은 하나로, 이유와 함께 적는다.
토큰·대비 패널: 의미 토큰 하나를 바꾸면
6장의 의미 토큰(bg, surface, text, text-muted, action, on-action, band, on-band)으로 첫 화면을 칠하고, 그 페이지에 실제로 쓰인 글자–바탕 짝을 모두 ART.contrast(WCAG 2 대비율)로 잰다. 큰 글자(24 px 이상, 또는 약 18.7 px 이상 굵게)는 3:1, 나머지 글자는 4.5:1, 입력 칸 테두리 같은 비텍스트 요소는 3:1이 바닥이다(WCAG 2.2의 1.4.3, 1.4.11).
색 토큰은 넷이다. "옛 색"은 6장에서 서윤이 찾아낸 연회색 #999999가 섞인 상태, "밝은 토큰"과 "어두운 토큰"은 6장의 표, "반전 다크"는 지후가 처음 해 본 OKLCH 명도 뒤집기다. 아래 "주색 명도" 막대는 의미 토큰 action 하나의 OKLCH 명도만 움직인다. 버튼의 바탕, 링크, 눈썹 글이 모두 이 토큰을 부르므로 한 곳을 바꾸면 그 색을 쓰는 모든 짝의 대비가 함께 바뀐다.
토큰·대비 패널: 첫 화면의 글자–바탕 짝
| 짝(쓰인 곳) | 글자 | 바탕 | 대비(기준) |
|---|
#999999가 2.85, 바닥글의 차분한 초록이 2.62다. ② "반전 다크"로 바꾼다. 주색 버튼과 흐린 글자가 3.19·3.06으로 떨어진다(6장에서 지후가 본 숫자). ③ "밝은 토큰"에서 주색 명도를 +0.08쯤 올린다. 버튼 위 흰 글자가 4.5 아래로 내려가는 순간을 본다. 어두운 토큰에서 같은 막대를 내리면 반대 방향으로 무너진다. (모형의 가정: 대비는 이 서가의 엔진 ART.contrast, 명도 조정은 OKLCH에서 L만 바꾸고 색역 밖이면 채도를 줄인다.)토큰 체계가 하는 일은 "같은 초록이 여섯 가지 hex로 흩어지지 않게" 하는 것만이 아니다. 실험실처럼 의미 토큰 하나를 바꾸었을 때 영향을 받는 짝이 모두 한 표에 모인다는 것이 더 크다. 6장의 다크 모드 값(바탕 #151917, 주색 #5eaa85, 주색 위 글자 #151917)은 반전이 아니라 따로 지정한 값이라, 표의 모든 짝이 4.5를 넘는다. 가장 낮은 짝은 카드 표면 #2a2f2d 위의 주색 날짜 줄 4.90이다. 6장이 바탕 위에서 잰 6.39보다 낮은 것은 카드가 바탕보다 한 단계 밝기 때문이다. 토큰 표는 짝마다 "어느 바탕 위에서"까지 적어야 한다.
포커스 패널: 장과 코드가 다르게 적은 링
장마다 정한 값과 지후가 따로 짠 시험판 코드가 다르게 적은 곳이 나왔다. 포커스 표시다. 7장은 버튼 상태 표에 3 px 링 #22342a, 2 px 띄움, 어두운 영역 안에서는 크림 #ffe2d7을 적었고, 11장의 점검표도 같은 링을 불렀다. 그런데 시험판 코드에는 개발 템플릿에서 온 3 px 책방 초록 #2f7d5b, 2 px 띄움이 남아 있었다. 둘 다 흰 바탕에서는 기준을 넘는다. 차이는 바탕이 바뀔 때 드러난다.
아래 패널은 신청 폼과 짙은 바닥글을 Tab 순서대로 한 칸씩 옮겨 가며, 링과 그 링이 닿는 바탕의 대비를 잰다. 포커스 링은 비텍스트 요소이므로 바탕과 3:1 이상이어야 알아볼 수 있다(1.4.11). WCAG 2.2의 2.4.13 포커스 모양(AAA)도 포커스 표시가 그 둘레와 3:1 이상 대비를 갖기를 요구한다.
포커스 패널: Tab으로 한 칸씩
실험실에서 정한 것은 이렇다. 포커스 색은 7장의 짙은 링 #22342a로 한다. 흰 바탕 13.19, 페이지 바탕 #f6fcf8 12.68, 크림 띠 10.74다. 어두운 영역(바닥글, 그리고 다크 모드의 모든 바탕) 안에서는 크림 #ffe2d7 링을 쓴다. 바닥글 위 10.74, 다크 모드 바탕 위 14.46이다. 시험판의 초록 링은 흰 바탕 4.99, 크림 띠 4.07로 밝은 곳에서는 통과하지만, 짙은 바닥글 위에서 2.64로 무너진다. 주색 버튼 둘레에서도 링과 버튼이 같은 색이라, 그 사이의 2 px 틈이 아니면 한 덩어리로 보이기 쉽다. 11장의 점검표(키보드만으로 신청, 포커스 순서 = 읽는 순서, :focus-visible, 고정 띠만큼 scroll-padding)는 그대로 두고 시험판 코드의 색 한 줄만 7·11장 값으로 맞춘다.
var(--focus-ring)을 불렀다면 값은 처음부터 갈라질 수 없었다. 토큰 체계(6장)가 색과 글자에만 쓰는 도구가 아니라는 뜻이다. 보조 글자도 같은 일이 있었다. 6장과 11장은 text-muted를 #567666으로 적었는데, 시험판의 폼 코드에는 안내 글자가 #5d6b63으로 남아 있었다. 실험실에서는 토큰 하나(text-muted #567666, 흰 칸 5.03 · 바탕 4.83)로 합쳤다. 이 책의 엔진으로 다시 재면 #5d6b63은 흰 바탕 위 5.60이다. 둘 다 4.5를 넘으니 어느 쪽을 골라도 기준은 지키지만, 같은 일을 하는 글자가 두 색일 이유는 없다.
타깃 패널: 44는 글자를 키워도 44인가
7장은 터치 타깃의 사이트 최소를 44×44 CSS px로 정했다(WCAG 2.2 2.5.8의 24×24는 하한). 8장은 탭 바 네 칸이 폭 320·글자 200%에서도 칸 폭 80 px, 높이 56 px 이상이 되게 했다. 이 패널은 행사 일정 페이지를 휴대폰 폭에 놓고 모든 타깃에 상자를 그린다. 초록 실선은 44 이상, 주황 점선은 24~44, 빨강은 24 미만이다. 24 미만인 타깃에는 2.5.8의 간격 예외를 확인하는 지름 24의 원을 그린다.
목업의 타깃을 누르면, 7장의 손가락 흩어짐 모형(걸으면서 한 손, 표준편차 2.0 mm)으로 그 타깃을 노린 마흔 번의 터치를 찍는다. 노린 것에 닿으면 짙은 초록, 이웃 타깃에 닿으면 빨강, 빈 곳이면 회색이다.
타깃 패널: 휴대폰의 행사 일정
44라는 수는 "최소 높이"로 적어야 지켜진다. 첫 시안의 버튼처럼 height: 36px로 못 박으면 글자를 키운 사람에게 글자가 잘리고, 반대로 칩을 28px로 못 박으면 글자는 넘치고 타깃은 그대로 작다. 서윤의 부품은 min-height: 44px에 안쪽 여백과 rem 글자를 더해 크기가 내용을 따른다. 대가는 자리다. 글자 200%의 휴대폰에서 칩은 한 화면에 세 개 남짓만 보인다. 서윤은 칩을 줄이지 않고 가로로 넘기는 방식을 지켰다. 2.5.8은 크기를 간격으로 메우는 길도 열어 두었지만(24 원이 겹치지 않으면 통과), 간격은 잘못 누르기를 "반응 없음"으로 바꿀 뿐 노린 칩에 닿는 비율을 올리지는 않는다.
용량 패널: 픽셀 비율 3의 휴대폰은 어느 사진을 받는가
12장은 첫 화면(휴대폰)의 무게 예산을 500 KB로 정했다. HTML·CSS 50, 자바스크립트 50, 웹폰트 200, 첫 사진 150, 기타 50. 사진은 480·800·1600 세 폭의 WebP를 srcset으로 두고, "360 px 휴대폰은 800화소(약 75 KB)를 받는다"고 적었다. 그런데 브라우저가 고르는 파일은 화면의 CSS 폭이 아니라 그 폭에 기기 픽셀 비율(DPR)을 곱한 화소 수를 기준으로 한다. 서윤의 휴대폰은 DPR 3이다(2장).
아래 패널은 첫 화면 사진이 차지하는 CSS 폭과 DPR로 srcset이 고를 파일을 정하고, 12장의 내려받기 모형(대역폭과 왕복 지연, 동시에 받는 파일이 대역폭을 나눠 쓰는 단순 모형)으로 LCP를 어림한다. 1200 폭은 이 장에서 새로 넣어 보는 후보다. 무게는 12장과 같은 어림(면적이 4분의 1이면 무게는 약 3분의 1)으로 약 142 KB, 480 폭은 약 33 KB로 쳤다.
용량 패널: 첫 화면 무게와 LCP
이 패널이 찾아낸 것은 두 장 사이의 빈틈이다. 12장의 예산표는 맞고, 5장의 srcset도 맞다. 다만 12장은 기기 픽셀 비율 2의 휴대폰으로 계산했고, 서윤의 휴대폰 같은 DPR 3은 아무도 따져 보지 않았다. 고칠 길은 셋이다. 사진 폭 후보를 하나 더 두거나(1200), sizes를 실제보다 작게 적어 브라우저를 속이거나, 첫 사진의 예산을 늘리고 다른 갈래를 줄이는 것. 두 번째는 화면이 흐려지는 것을 받아들이는 길이고, 세 번째는 웹폰트 200 KB(TypeBook 11장의 예산)를 건드려야 한다. 서윤은 첫째를 골랐다. 파일이 하나 늘 뿐 화면도 예산도 지킨다.
규칙이 부딪치는 곳
각 패널은 한 갈래씩 떼어 보았다. 그런데 실험실의 진짜 쓸모는 갈래 사이에서 나온다. 한 장에서 정한 규칙이 다른 장의 규칙과 같은 화면에서 만날 때다. 서윤과 지후가 실험실을 돌리며 찾은 부딪침을 그림 3에 모았다. 어느 것도 한쪽이 "틀린" 것이 아니다. 각 장은 자기 문제를 풀었고, 두 해법이 함께 놓이는 조건을 그 장에서는 볼 수 없었을 뿐이다.
ART.contrast와 12장의 모형)로 잰 값이다.부딪침을 푸는 순서는 서윤이 정했다. 첫째, 사람이 못 쓰게 되는 쪽을 먼저 막는다. 바닥글 위에서 사라지는 포커스 링은 키보드 사용자에게 길을 끊는다. 둘째, 기준을 넘는 두 값 사이에서는 체계가 단순한 쪽을 고른다. 보조 글자는 둘 다 4.5를 넘으므로 토큰 하나로 합쳤다. 셋째, 비용이 작은 쪽으로 고친다. 사진 폭을 하나 더 뽑는 것은 웹폰트 예산을 깎는 것보다 싸다. 넷째, 어느 쪽도 고치지 않는 것도 선택이다. 글자를 200%로 키운 노트북에 탭 바가 붙는 것은 받아들였다. 그 사람에게 글줄 22자의 1단 짜임이 더 읽기 좋기 때문이다.
종합 실험실
이제 모든 설정을 한 작업대에 모은다. 위쪽에 목업이 놓이고, 아래 조절기가 여덟 갈래를 모두 움직인다. "나란히 비교"를 켜면 같은 설정을 폭 360 휴대폰과 폭 1,280 넓은 화면에 나란히 그리고, 점검표도 두 칸으로 나뉜다. 두 단추로 "첫 시안 모음"과 "서윤의 선택"을 한 번에 불러올 수 있다. 둘 다 출발점일 뿐이니 하나씩 바꿔 가며 어느 갈래가 어느 줄을 빨갛게 만드는지 본다.
순서는 이렇게 권한다. ① 페이지와 폭을 정한다. ② 확대 200%와 글자 200%를 차례로 켜서 짜임이 무너지지 않는지 본다(1.4.4, 1.4.10). ③ 그리드를 겹쳐 카드 경계가 단 선 위에 서는지 본다. ④ 색 토큰을 밝은·어두운으로 바꿔 대비 줄을 확인한다. ⑤ Tab 순서를 끝까지 밀어 포커스 링이 모든 바탕에서 보이는지 본다. ⑥ 타깃을 겹쳐 가장 작은 것을 찾는다. ⑦ 사진·글꼴·통신을 바꿔 무게와 LCP를 본다. ⑧ 나란히 비교로 휴대폰과 넓은 화면을 함께 본다.
웹 실험실
페이지와 화면
배치
상호작용
쓰임
| 점검 | 지금 화면 | 기준 |
|---|
clamp() 식, 중단점은 rem 기준 em, 간격은 rem, 화면 가장자리 16 px, 한 줄 글자 수는 0.757 em 어림, LCP는 12장 모형에 첫 화면에서 가장 넓게 보이는 요소를 LCP 후보로 쳤다.)점검표에서 가장 먼저 볼 줄은 가로 넘침과 포커스 표시다. 둘은 실패하면 어떤 사람에게는 페이지 전체가 쓸 수 없게 된다. 대비와 타깃은 그다음이다. 무게와 LCP는 통신 조건에 따라 오가므로 "느린 모바일"에서 기준을 넘는지를 본다. 표의 어느 줄도 빨갛지 않다고 좋은 페이지가 되는 것은 아니다. 숫자가 말하지 못하는 것, 곧 첫 화면이 "다음 모임" 하나를 제대로 말하는지, 책방의 목소리처럼 보이는지는 두 폭을 나란히 놓고 눈으로 고른다.
서윤의 작업 노트
공개 전 마지막 점검, 세 페이지를 한 작업대에
2028년 2월 마지막 주 목요일 저녁, 책방 E 2층. 공개(3월 첫 주)까지 열흘이 남았다. 서윤은 노트북과 휴대폰을 나란히 놓고 첫 화면, 행사 일정, 모임 신청 폼을 실험실에 차례로 넣었다. 지후는 맞은편에서 시험판 코드를 열었고, 한도경은 글자를 가장 크게 한 휴대폰을 들고 왔다. 1월부터 장마다 따로 정한 값이 한 화면에서도 서로 어긋나지 않는지, 정하지 못하고 남겨 둔 것은 무엇인지 확인하는 자리였다.
먼저 장마다 처음 시도했던 값을 모은 "첫 시안 모음"을 띄워 출발점을 적었다. 폭 360에서 960 판이 600 px 넘쳤고, 글자 대비는 바닥글 2.62·날짜 줄 2.85, 포커스 표시는 없었고, 가장 작은 타깃은 머리 띠의 메뉴 링크 24 px(행사 일정의 날짜 칩은 28 px), 첫 화면 무게는 6.4 MB, 느린 모바일 LCP는 30초가 넘었다(모형). 그다음 "서윤의 선택"을 띄워 같은 줄을 다시 쟀다. 아래 표의 값은 이 장의 실험실로 잰 것이다(목업의 어림이라 진짜 브라우저와 몇 픽셀 다를 수 있다).
| 점검 | 휴대폰 360 · 글자 100% | 휴대폰 360 · 글자 200% | 넓은 화면 1280 | 기준 |
|---|---|---|---|---|
| 짜임 · 그리드 | 1단 · 4단 거터 16 | 1단 · 4단 거터 32 | 행 + 옆 칸 · 12단 · 단 78 | 최소 폭 320에서 넘침 없음 |
| 본문 · 한 줄 | 17 px · 약 25자 | 34 px · 약 12자 | 18 px · 약 37자 | 상한 28 em(약 37자) |
| 제목(h1) | 30 px | 60 px | 40 px | 5장 clamp() 식 |
| 가장 작은 타깃 | 44(로고) | 52 · 칩 75 | 44(로고) | 2.5.8 24 · 사이트 44 |
| 탭 바 · 메뉴 | 4칸 · 칸 90 · 높이 58 | 4칸 · 글자 두 줄 · 높이 104 | 머리 띠 5개 | 8장 |
| 글자 대비 최저 | 4.80 | 4.80 | 4.80 | 4.5 · 큰 글자 3 |
| 포커스 링 최저 | 10.74 | 10.74 | 10.74 | 3 이상 |
| 첫 화면 무게(DPR 3) | 492 KB | 492 KB | 492 KB(DPR 2) | 500 KB |
| LCP 느린 모바일(모형) | 약 2.3초 | 약 1.3초(글자가 LCP) | 약 2.3초 | 2.5초 |
| 첫 화면 단서 | 신청하기 · 일정 첫머리 보임 | 신청하기가 첫 화면 밖 | 모두 보임 | 2장 |
표에서 빨간 줄은 없었지만, 실험실을 돌리는 동안 부딪침이 다섯 곳에서 나왔다(그림 3). 가장 먼저 걸린 것은 포커스 링이었다. 7장의 버튼 표와 11장의 점검표에는 #22342a가 적혀 있었는데, 시험판 코드에는 개발 템플릿의 #2f7d5b가 남아 있었다. 지후가 "코드에는 아직 템플릿 값이 들어가 있어요" 하고 Tab을 바닥글까지 누르자 "오시는 길"의 초록 링이 짙은 바닥글에 묻혔다. 실험실로 재니 2.64였다. 서윤은 7장의 값으로 맞췄다. 밝은 바탕에서는 짙은 링(최저 10.74, 크림 띠 위), 어두운 영역과 다크 모드에서는 크림 링(최저 10.74, 바닥글 위)이다. 코드와 두 장의 표에는 hex 대신 var(--focus-ring)을 적었다. 보조 글자도 6·11장의 #567666과 폼 코드의 #5d6b63이 갈라져 있어 토큰 하나로 합쳤다.
두 번째는 사진이었다. 서윤의 휴대폰(DPR 3)으로 시험판을 열자 개발자 도구에 1600 폭 사진이 찍혔다. 12장의 "800화소"는 DPR 2 휴대폰의 계산이었다. 실험실로 재니 첫 화면이 570 KB, 느린 모바일 LCP가 3.0초였다. 지후가 1200 폭을 하나 더 뽑아 srcset을 네 폭으로 만들자 492 KB, 2.3초가 되었다. 세 번째는 도경의 휴대폰이었다. 글자 200%, 폭 360에서 날짜 칩은 75 px로 커져 한 화면에 세 개 남짓만 보였다. 도경은 칩을 손가락으로 밀어 보더니 "옆으로 밀리는 걸 알겠네. 끝이 잘려 있으니까" 했다. 서윤은 칩을 줄이지 않았다. 표에 남은 마지막 주황 줄은 "첫 화면 단서"였다. 폭 360에서 사진을 16:9로 두자 행사 일정 제목이 첫 화면 끝(탭 바 위)보다 13 px 아래로 밀려 2장의 약속("행사 일정의 첫머리가 첫 화면 끝에 걸쳐 보이게")을 지키지 못했다. 서윤은 휴대폰에서만 사진을 5:2로 잘라 보이게 했다(같은 파일, aspect-ratio와 object-fit: cover). 제목이 첫 화면 안으로 올라왔고, 사진은 여전히 첫 화면에서 가장 넓은 요소라 LCP 후보로 남았다. 글자를 200%로 키운 도경의 화면에서는 "신청하기"도 첫 화면 밖으로 밀렸는데, 이것은 받아들였다. 큰 글자로 한 번 스크롤하는 것이 작은 글자로 한눈에 보는 것보다 낫다. 마지막으로 도경이 노트북 브라우저를 200%로 키우자 넓은 화면인데도 아래 탭 바가 붙었다. 지후는 고칠지 물었고, 서윤은 그대로 두자고 했다. 그 화면의 본문은 한 줄 22자 안팎으로, 넓은 짜임을 억지로 지키는 것보다 읽기 편했다.
도경은 마지막으로 서윤의 노트에 메모를 끼워 두었다. "표가 다 초록이어도 내 휴대폰으로 한 번은 더 해 봐라. 그리고 고르지 않은 것도 같이 적어 둬. 봄에 다시 고칠 때 그게 제일 쓸모 있을 거다." 지후의 메모는 짧았다. "값은 한 곳에. 나머지는 이름으로."
#22342a(3 px, 2 px 띄움, 흰 바탕 13.19)로 확정하고, 어두운 영역과 다크 모드에서는 #ffe2d7(바닥글 10.74, 다크 바탕 14.46). 값은 --focus-ring 토큰 한 곳에만 둔다. ③ 보조 글자는 text-muted #567666 하나로 합친다. ④ 좁은 화면 그리드 안내선: 35 em 아래 4단·거터 16, 35~56 em 8단·거터 24, 그 위 12단. ⑤ 첫 사진 srcset에 1200 폭(약 142 KB)을 더해 네 폭(480·800·1200·1600)으로, DPR 3 휴대폰에서도 첫 화면 492 KB·LCP 약 2.3초(모형). ⑥ 글자 200% 넓은 화면의 1단·탭 바 짜임은 고치지 않는다. ⑦ 휴대폰(35 em 아래)에서 첫 사진은 5:2로 잘라 보여 "신청하기"와 행사 일정 첫머리가 첫 화면(360×640, 탭 바 제외) 안에 든다. 탭 바는 HTML에서 머리 띠 바로 뒤에 두어 Tab 순서가 로고 → 탭 바 → 본문 → 바닥글이 되게 한다.sizes를 작게 적어 DPR 3에서도 800을 받게 하기(가볍지만 흐림), 첫 사진 예산을 늘리고 웹폰트를 한 굵기로 줄이기, 칩을 36 px·간격 12로 바꿔 한 줄에 일주일을 넣기(모형의 잘못 누르기는 1.4%로 비슷하지만 사이트 최소 44에서 벗어나고 빈 곳을 누르는 일이 는다), 글자 200% 넓은 화면에서도 머리 띠 메뉴를 유지하기. 두 설정의 점검표를 함께 노트에 남겼다.핵심 정리
- 장마다 따로 정한 값은 한 페이지 위에서 함께 점검한다. 폭, 확대, 글자 크기 설정 하나만 바꿔도 짜임, 글줄, 타깃, 무게가 같이 움직인다.
- 브라우저 확대는 CSS 뷰포트를 좁히고, 글자 크기 설정은 rem을 키운다. em 중단점은 둘 모두를 따라가서 글줄 기준(28 em, 약 37자)을 지킨다.
- 간격과 그리드는 값이 단계에 있는지보다 무리 안 < 카드 안 < 카드 사이 < 구획 사이의 순서와, 제목이 자기 목록에 붙는지로 본다.
- 대비는 페이지에 실제로 쓰인 글자–바탕 짝을 모두 잰다. 의미 토큰 하나를 바꾸면 그 토큰을 부르는 짝이 함께 바뀐다. 다크 모드는 반전이 아니라 따로 지정한다.
- 포커스 링은 그 링이 닿는 모든 바탕에서 3:1 이상이어야 한다. 이 책의 결정은 밝은 곳
#22342a, 어두운 곳#ffe2d7이고, 값은 토큰 한 곳에 둔다. - 터치 타깃은 고정 크기가 아니라 최소 크기(
min-height: 44px)로 적어야 글자를 키워도 지켜진다. 2.5.8의 24는 하한이다. srcset은 CSS 폭 × 기기 픽셀 비율로 파일을 고른다. 무게 예산은 가장 높은 DPR의 휴대폰에서 다시 재 본다.
확인 퀴즈
1. 노트북 화면(폭 1,280 px)에서 브라우저를 400%로 확대했다. 이 페이지의 짜임을 정하는 CSS 뷰포트 폭은 얼마이고, 어떤 기준과 이어지는가?
2. 7장과 11장은 포커스 링을 #22342a로 적었는데, 시험판 코드에는 #2f7d5b가 들어가 있었다. 실험실에서 #22342a(어두운 곳은 크림 #ffe2d7)를 고른 근거로 가장 알맞은 것은?
3. 첫 사진이 화면에서 CSS 폭 328 px을 차지하고, srcset에 480·800·1600 세 폭이 있다. 기기 픽셀 비율 3의 휴대폰은 어느 파일을 받는가?
sizes로 정한 CSS 폭에 기기 픽셀 비율을 곱한 화소 수를 채우는 가장 작은 후보를 고른다(캐시나 데이터 절약 설정에 따라 달라질 수 있다). 984화소를 채우려면 1600이 필요하다. 그래서 이 장은 1200 폭을 더해 DPR 3에서도 무게 예산 안에 들게 했다.4. "신청하기" 버튼을 width: 120px; height: 36px로 못 박았다. 글자 크기 설정을 200%로 키운 휴대폰에서 일어날 일과 고칠 방법으로 가장 알맞은 것은?
참고 문헌
W3C, Web Content Accessibility Guidelines (WCAG) 2.2, 2023(성공 기준 1.4.3 대비 최소, 1.4.4 글자 크기 조절, 1.4.10 리플로, 1.4.11 비텍스트 대비, 2.4.7 포커스 보임, 2.4.13 포커스 모양, 2.5.8 타깃 크기 최소)과 Understanding WCAG 2.2 · 한국지능정보사회진흥원, 한국형 웹 콘텐츠 접근성 지침(KWCAG) 2.2 · web.dev, Core Web Vitals 기준값(LCP 2.5초, INP 200 ms, CLS 0.1) · WHATWG HTML Living Standard, img의 srcset·sizes 선택. 대비율은 이 서가의 계산 엔진(ART.contrast)으로, 무게와 LCP는 12장의 교육용 모형으로, 터치 흩어짐은 7장의 교육용 모형으로 계산했다. 이 장의 페이지, 행사, 책 제목은 모두 가상이다.