반응형을 처음 짤 때 나는 유명한 휴대폰과 태블릿의 해상도를 검색해서 그 숫자마다 브레이크포인트를 걸었다. 특정 기종 폭에 딱 맞추면 완벽할 줄 알았는데, 새 기기가 나올 때마다 목록을 늘려야 했고 어느새 조건문이 감당 못 할 만큼 불어났다. 기기를 좇는 방식이 왜 지옥으로 불리는지 그때 몸소 겪었고, 결국 방식을 통째로 갈아엎어야 했다.


이번 편은 그 실수에서 벗어나 브레이크포인트를 어디에 둘지 정하는 방법에 관한 것이다. 특정 기기가 아니라 콘텐츠가 깨지는 지점을 기준으로 삼는 현대적 접근, 관례적인 출발점, 그리고 접근성까지 챙기는 단위 선택을 내 경험과 함께 정리한다. 전환점을 잘 잡는 감각이 반응형의 품질을 좌우한다고 나는 믿는다.

1. 기기가 아니라 콘텐츠를 기준으로

가장 먼저 버려야 할 생각은 특정 기기 폭에 브레이크포인트를 맞춘다는 발상이다. 기기의 종류와 해상도는 해마다 파편처럼 늘어나서, 그 숫자를 좇는 순간 유지보수가 끝없는 술래잡기가 된다. 나는 이 술래잡기에 지쳐 방향을 완전히 바꿨다. 잡아야 할 대상이 도망만 다니는 게임은 애초에 이길 수 없는 싸움이었다.


현대적 접근은 콘텐츠가 깨지는 지점에서 전환점을 잡는 것이다. 화면을 서서히 좁혀보다가 어느 폭에서 배치가 어색해지거나 글자가 답답해지는 순간이 오는데, 바로 그 지점이 브레이크포인트가 되어야 한다. 특정 기기가 아니라 내 콘텐츠 자체가 전환점을 알려주는 셈이다. 콘텐츠에게 물으면 콘텐츠가 답한다는 걸 나는 뒤늦게 깨달았다.


이 방식의 가장 큰 장점은 미래 대응력이다. 콘텐츠가 편안하게 담기는 폭을 기준으로 삼으면, 아직 나오지도 않은 기기가 그 사이 어느 폭을 갖더라도 자연스럽게 대응된다. 나는 이 방식으로 바꾼 뒤로 새 기기가 나와도 코드를 손댈 일이 거의 없어졌다. 특정 숫자를 좇지 않으니 새 숫자가 나와도 흔들리지 않았다.


깨지는 지점을 찾는 방법은 단순하다. 브라우저 창의 폭을 천천히 줄이거나 늘리면서 배치가 무너지는 순간을 눈으로 관찰하는 것이다. 나는 개발자 도구를 열고 창을 손으로 잡아 늘였다 줄였다 하며, 어느 폭에서 카드가 찌그러지고 어느 폭에서 여백이 사라지는지 확인한다. 이 관찰만으로 대부분의 전환점이 저절로 드러난다.


이렇게 찾은 지점은 콘텐츠마다 다르다. 어떤 카드 묶음은 육백 픽셀쯤에서 두 줄로 접는 게 좋고, 어떤 표는 사백 픽셀 근처에서 스크롤로 바꿔야 한다. 브레이크포인트는 정답이 정해진 숫자가 아니라 그 콘텐츠에 맞춰 발견하는 값이라는 걸 나는 강조하고 싶다. 남의 콘텐츠에 맞는 숫자가 내 콘텐츠에도 맞으리란 보장은 없다.


물론 처음부터 완벽하게 찾을 수는 없다. 나는 대략의 지점을 잡아두고, 실제 콘텐츠를 채운 뒤 다시 훑으면서 조정한다. 텍스트 길이나 이미지 비율이 바뀌면 깨지는 지점도 미세하게 달라지기 때문에, 브레이크포인트는 한 번 정하고 끝이 아니라 계속 다듬는 값이다. 살아 있는 콘텐츠에는 살아 있는 전환점이 필요한 셈이다.

2. 관례적 구간은 출발점일 뿐

그렇다고 아무런 기준 없이 시작하기는 막막하다. 그래서 나는 관례적으로 쓰이는 구간을 출발점으로 삼는다. 대체로 모바일은 육백사십 픽셀 아래, 태블릿은 칠백육십팔 픽셀 근처, 데스크톱은 천이십사 픽셀 이상, 넓은 화면은 천이백팔십 픽셀 이상으로 나누는 관례가 있다. 이 값들은 많은 화면이 몰려 있는 대략의 구간을 반영한다.


이 숫자들은 절대적인 법칙이 아니라 다수의 화면이 몰려 있는 대략의 구간일 뿐이다. 나는 이 값을 시작점으로 두고, 앞서 말한 대로 콘텐츠가 깨지는 지점에 맞춰 조금씩 밀거나 당긴다. 관례를 참고하되 거기에 얽매이지 않는 것이 요령이다. 출발점은 어디까지나 출발점이지 도착점이 아니다.


흔히 저지르는 실수는 이 관례 구간을 그대로 신주 모시듯 쓰는 것이다. 콘텐츠는 보지도 않고 유명한 프레임워크가 쓰는 숫자를 베껴 넣으면, 정작 내 페이지에서는 엉뚱한 폭에서 배치가 어긋난다. 나도 초반에는 남의 숫자를 그대로 복사하다가 그런 어긋남을 여러 번 겪었다. 남의 옷을 그대로 입으니 몸에 맞을 리가 없었다.


브레이크포인트의 개수도 고민거리다. 너무 많으면 관리가 복잡해지고 각 구간을 세밀하게 챙기기 어렵다. 나는 보통 두세 개의 주요 전환점으로 큰 틀을 잡고, 정말 필요한 곳에만 보조 전환점을 더한다. 전환점이 적을수록 각 구간에 더 집중할 수 있고, 나중에 손볼 곳도 줄어든다.


전환점을 정할 때는 각 구간에서 콘텐츠가 어떻게 보일지를 미리 그려본다. 모바일 구간에서는 한 줄로 쌓고, 태블릿에서는 두 칸, 데스크톱에서는 세 칸으로 펼치는 식이다. 이렇게 구간별 목표를 먼저 정해두면 어느 폭에서 배치를 바꿔야 할지가 자연스럽게 따라온다. 목표가 있어야 전환의 이유가 생긴다.


결국 관례 구간은 지도 위의 안내 표지일 뿐이고, 실제 길은 내 콘텐츠가 정한다. 나는 이 둘을 함께 쓴다. 표지를 보며 대략의 방향을 잡되, 발밑의 지형을 확인하며 걸음을 조정하는 것이다. 이 균형이 잡히면 브레이크포인트 설계가 한결 수월해진다. 지도와 지형을 함께 볼 줄 아는 것이 실력이다.

3. 접근성을 살리는 단위 선택

브레이크포인트를 어떤 단위로 적느냐도 생각보다 중요하다. 많은 사람이 픽셀 단위로 전환점을 적지만, 나는 사용자 폰트 확대까지 고려하면 상대 단위가 낫다는 걸 알게 되었다. 상대 단위로 전환점을 잡으면 사용자가 브라우저 기본 글자를 키울 때 전환점도 함께 반응한다. 화면 폭만이 아니라 글자 크기까지 전환의 조건에 들어오는 것이다.


예를 들어 육백사십 픽셀은 기본 글자 기준으로 사십 배쯤 되는 상대 단위로 바꿔 적을 수 있다. 이렇게 하면 사용자가 글자를 크게 키웠을 때 전환점도 함께 커져서, 큰 글자가 좁은 구간에 억지로 끼는 문제가 줄어든다. 저시력 사용자를 배려하는 작은 장치인 셈이다. 겉으로는 같은 숫자처럼 보여도 그 안의 배려가 다르다.


픽셀 단위 전환점의 문제는 사용자 설정을 무시한다는 데 있다. 화면 폭이 같으면 사용자가 글자를 아무리 키워도 같은 배치가 나오는데, 이러면 큰 글자가 좁은 칸에 눌려 답답해진다. 상대 단위는 이 문제를 자연스럽게 풀어준다. 사용자의 선택을 존중하는 방향으로 배치가 함께 움직이기 때문이다.


나는 처음에 상대 단위 계산이 번거로워 보여 미뤘지만, 실제로는 몇 개의 값만 외워두면 충분했다. 기본 글자를 십육 픽셀로 잡으면 사십 배가 육백사십, 사십팔 배가 칠백육십팔, 육십사 배가 천이십사가 된다. 이 몇 개만 알아두면 관례 구간을 그대로 상대 단위로 옮길 수 있다. 생각보다 진입 장벽이 낮았던 셈이다.


물론 모든 프로젝트가 상대 단위 전환점을 써야 하는 것은 아니다. 접근성 요구가 특별히 높지 않은 내부 도구라면 픽셀로도 충분할 수 있다. 다만 나는 공개된 콘텐츠 사이트라면 되도록 상대 단위를 쓰려 하는데, 어떤 사용자가 어떤 설정으로 올지 모르기 때문이다. 불특정 다수를 향한 페이지일수록 여지를 넓게 두어야 한다.


단위 선택은 사소해 보여도 누군가에게는 읽을 수 있느냐 없느냐를 가른다. 나는 이런 작은 선택들이 모여 접근성의 수준을 만든다고 믿는다. 전환점 하나를 상대 단위로 적는 것만으로도 더 많은 사람에게 편안한 페이지가 된다면, 그 정도 수고는 기꺼이 감수할 가치가 있다. 배려는 대개 이런 작은 자리에 숨어 있다.

4. 미디어 쿼리와 컨테이너 쿼리의 분업

브레이크포인트를 이야기할 때 최근 빼놓을 수 없는 것이 컨테이너 쿼리의 등장이다. 예전에는 모든 전환을 화면 폭 기준의 미디어 쿼리로만 처리했는데, 이제는 부품 단위의 전환을 부모 칸의 폭 기준으로 따로 다룰 수 있게 되었다. 이 변화가 브레이크포인트 설계의 그림을 바꿨다. 전환의 기준이 하나에서 둘로 늘어난 셈이다.


미디어 쿼리는 화면 전체의 폭을 본다. 그래서 페이지의 큰 골격, 즉 사이드바를 접을지 메뉴를 세로로 바꿀지 같은 판단에 적합하다. 나는 페이지 레이아웃의 큰 뼈대를 정할 때는 여전히 미디어 쿼리를 쓴다. 화면 전체에 걸친 결정에는 화면 전체를 보는 도구가 어울린다.


반면 컨테이너 쿼리는 부품이 담긴 칸의 폭을 본다. 같은 카드 부품이라도 넓은 본문에 놓이면 가로로 펼치고, 좁은 사이드바에 놓이면 세로로 쌓게 만들 수 있다. 화면 폭이 아니라 그 부품이 실제로 차지한 공간에 반응하니, 진짜 재사용 가능한 부품이 된다. 같은 부품을 어디에 두어도 스스로 알아서 맞추는 것이다.


이 둘을 어떻게 나눌지에 대해 나는 간단한 규칙을 세웠다. 페이지 골격의 전환점은 미디어 쿼리로, 재사용 부품 내부의 전환점은 컨테이너 쿼리로 두는 것이다. 둘은 경쟁 관계가 아니라 역할을 나눠 맡는 동료다. 어느 하나가 다른 하나를 대체하는 것이 아니라 서로의 빈자리를 채운다.


이 분업 덕분에 브레이크포인트가 한결 정돈되었다. 예전에는 부품이 어디에 놓이든 화면 폭만 보고 배치를 정하다 보니, 넓은 화면의 좁은 사이드바에서 카드가 어색해지는 일이 잦았다. 컨테이너 쿼리로 부품 전환을 옮긴 뒤로는 그런 어긋남이 사라졌다. 부품이 자기가 놓인 자리를 스스로 인식하게 된 덕분이다.


다만 컨테이너 쿼리는 부모에 컨테이너 선언을 해두어야 동작하고, 아직 세밀한 부분에서는 주의가 필요하다. 나는 필요한 곳에 조건부로 도입하고, 지원하지 않는 환경을 위한 대비도 함께 둔다. 새 도구를 쓰되 안전장치를 함께 챙기는 것이 오래 버티는 코드를 만든다. 앞서가되 무리하지 않는 균형이 중요하다.

5. 전환점을 검증하고 다듬기

브레이크포인트를 정했다고 끝이 아니다. 나는 반드시 각 전환점 사이의 모든 폭을 훑어보며 검증한다. 브라우저 창을 천천히 늘렸다 줄였다 하면서, 정해둔 전환점 말고 다른 폭에서 배치가 깨지지 않는지 살피는 것이다. 전환점만 확인하고 그 사이를 방치하면 반드시 어딘가에서 사고가 난다.


이 과정에서 예상 못 한 어긋남을 자주 발견한다. 두 전환점 사이 어중간한 폭에서 카드가 유독 좁아지거나 제목이 두 줄로 넘치는 경우가 있는데, 고정 기기 프리셋만 봤다면 놓쳤을 문제들이다. 그래서 나는 특정 기기 폭이 아니라 연속된 폭 전체를 확인한다. 화면 폭은 몇 개의 점이 아니라 이어진 선이기 때문이다.


어긋남을 찾으면 전환점을 옮기거나 보조 전환점을 하나 더한다. 이때도 무작정 전환점을 늘리기보다, 유연한 격자로 흡수할 수 있는 변화인지 먼저 따진다. 유연함으로 해결될 문제를 조건문으로 막으면 코드만 복잡해진다는 걸 나는 여러 번 겪었다. 조건문은 정말 필요할 때 아껴 써야 한다.


가로와 세로 방향 전환도 확인한다. 휴대폰을 가로로 눕히면 폭이 크게 달라지는데, 이때 배치가 자연스러운지 살펴야 한다. 나는 세로에서만 확인하고 넘어갔다가, 가로로 눕힌 화면에서 여백이 무너지는 걸 뒤늦게 발견한 적이 있어 이제는 두 방향을 모두 본다. 사용자는 언제든 기기를 돌릴 수 있다.


접근성 확인도 이 단계에서 함께 한다. 글자를 이백 퍼센트로 키운 상태에서 전환점이 여전히 자연스럽게 작동하는지 보는 것이다. 상대 단위 전환점을 썼다면 이 상황에서도 배치가 큰 글자에 맞춰 넉넉해지므로 마음이 놓인다. 확대 상태를 확인해야 상대 단위의 진가가 눈에 들어온다.


정리하면 브레이크포인트는 특정 기기가 아니라 콘텐츠가 깨지는 지점에서 잡아야 하고, 관례 구간은 출발점일 뿐이며, 상대 단위를 쓰면 접근성이 좋아진다. 페이지 골격은 미디어 쿼리로, 부품 내부는 컨테이너 쿼리로 나누고, 전환점 사이의 모든 폭을 훑어 검증한다. 다음 편에서는 이 전환점을 어느 방향으로 쌓을지, 즉 모바일 퍼스트의 실전을 다룬다. 전환점을 어디에 둘지 정했으니 이제 어느 쪽으로 쌓을지가 남았다.