화면 맨 아래에 딱 붙는 결제 버튼을 만든 적이 있다. 데스크톱에서도, 안드로이드에서도 완벽했다. 그런데 최신 아이폰에서 그 버튼을 눌러 달라는 문의가 들어왔다. 확인해보니 버튼이 화면 맨 아래 홈 인디케이터라 부르는 그 가느다란 막대에 절반쯤 가려져 있었다. 손가락을 대면 버튼이 아니라 시스템 제스처가 먹었다. 화면은 사각형이 아니었고, 나는 그때까지 세상의 모든 화면을 반듯한 사각형이라 여기고 있었다.


한때 화면은 단순했다. 가로세로 비율 몇 가지, 반듯한 네 귀퉁이. 지금은 그렇지 않다. 위쪽이 파여 있고, 모서리는 둥글고, 아래엔 막대가 지나가고, 접히기까지 한다. 세로로 길쭉한 폰부터 가로로 넓은 모니터, 정사각형에 가까운 태블릿, 펼치면 두 배가 되는 접는 화면까지, 우리 글이 놓이는 판은 제각각이다. 이번 편은 이 제각각인 화면을 어떻게 견디는지에 대한 이야기다.

1. 화면비가 이토록 다양할 줄이야

내가 처음 웹을 배울 때는 가로가 세로보다 넓은 화면이 당연했다. 모니터는 옆으로 길쭉했고, 레이아웃도 그 가로 공간을 쓰는 데 익숙했다. 그런데 휴대폰이 주류가 되면서 이 전제가 뒤집혔다. 손안의 화면은 세로로 길쭉하다. 가로로 펼치던 습관을 세로로 쌓는 습관으로 바꿔야 했다.


여기서 끝이 아니었다. 같은 휴대폰이라도 어떤 건 홀쭉하게 길고 어떤 건 통통했다. 태블릿은 정사각형에 가까웠다. 가로로 아주 넓은 모니터를 쓰는 사람도 늘었다. 나는 특정 화면비 하나를 머릿속에 그려두고 디자인하는 버릇이 있었는데, 그 하나의 비율에 맞춘 화면은 다른 비율에서 여지없이 어색해졌다. 한 화면비에 딱 맞춘다는 건 나머지 모든 화면비를 버린다는 뜻이었다.


그래서 나는 특정 비율을 겨냥하는 대신, 어떤 비율에서도 무너지지 않는 유연함을 목표로 삼는다. 세로로 길든 가로로 넓든 콘텐츠가 자연스럽게 흐르도록 짜두면, 낯선 비율의 새 기기가 나와도 대체로 버틴다. 화면비를 예측하려는 싸움은 이길 수 없다. 어떤 비율이 와도 견디는 쪽으로 방향을 트는 게 낫다.


이미지나 영상처럼 비율이 정해진 요소를 다룰 때는 이야기가 조금 다르다. 이런 것들은 자기만의 가로세로 비율을 지켜야 찌그러지지 않는다. 나는 이런 요소에 비율을 직접 지정해, 화면이 넓어지든 좁아지든 그 비율을 유지한 채 크기만 변하게 한다. 예전에는 높이와 폭을 따로 계산해 억지로 맞췄는데, 지금은 비율 하나만 알려주면 나머지는 알아서 지켜진다. 이 하나로 영상이 위아래로 눌리거나 옆으로 늘어나는 사고가 사라졌다.


넓은 모니터를 쓰는 사람도 잊지 말아야 한다. 가로로 아주 긴 화면에 본문을 그냥 풀어두면 한 줄이 끝없이 길어져 읽기 힘들어진다. 나는 아무리 화면이 넓어도 콘텐츠가 어느 폭 이상으로는 안 퍼지게 상한을 두고, 남는 좌우 공간은 여백으로 비운다. 넓은 화면을 다 채우려는 욕심이 오히려 가독성을 해친다. 빈 공간은 낭비가 아니라 읽기를 돕는 여백이다.

2. 100vh라는 오랜 거짓말

화면을 꽉 채우는 첫 화면을 만들 때, 나는 오랫동안 뷰포트 높이 전체를 뜻하는 단위를 썼다. 화면 높이만큼 딱 채우라는 뜻이니 당연히 잘 될 줄 알았다. 그런데 모바일에서 이게 배신을 했다.


모바일 브라우저에는 위아래로 주소창과 도구 막대가 있는데, 이것들이 스크롤에 따라 접혔다 펼쳐졌다 한다. 문제는 화면 높이 전체를 뜻하는 그 단위가, 이 주소창이 접힌 상태의 큰 높이를 기준으로 잡힌다는 데 있었다. 주소창이 펼쳐져 있을 때는 그 단위로 잡은 요소가 화면보다 커져서, 아래쪽이 주소창에 가리거나 잘렸다. 첫 화면 맨 아래 버튼이 주소창 뒤로 숨는 걸 보고 나서야 이 함정을 알았다.


이걸 풀려고 새로운 높이 단위들이 나왔다. 하나는 주소창이 펼쳐진 가장 좁은 상태의 높이, 하나는 접힌 가장 넓은 상태의 높이, 그리고 하나는 주소창 상태에 따라 실시간으로 변하는 높이다. 나는 절대 가려지면 안 되는 요소, 이를테면 화면을 꽉 채우는 모달에는 가장 좁은 상태의 높이를 써서 어떤 상황에도 잘리지 않게 한다. 첫 화면 배경처럼 주소창을 따라 늘었다 줄었다 해도 괜찮은 곳에는 실시간으로 변하는 높이를 쓴다.


다만 실시간으로 변하는 높이에도 함정이 있다. 이 값은 스크롤할 때마다 미세하게 바뀌는데, 여기에 글자 크기 같은 걸 묶어두면 스크롤할 때 글자가 덩달아 들썩인다. 나는 이걸 모르고 첫 화면 제목 크기를 이 높이에 연동했다가, 화면을 넘길 때마다 제목이 떨리는 걸 겪었다. 그 뒤로 화면을 채우는 그릇의 높이에만 이 단위를 쓰고, 그 안의 글자 크기는 얌전한 고정 단위로 못 박는다. 떨리는 배경은 참아도 떨리는 글자는 못 참는다.


옛 브라우저를 위해 순서를 지키는 것도 잊지 않는다. 새 높이 단위를 못 읽는 환경이 있을 수 있으니, 나는 예전 단위를 먼저 적고 그 아래에 새 단위를 덧적는다. 새 단위를 읽는 브라우저는 아래 값으로 덮어쓰고, 못 읽는 브라우저는 위의 옛 값을 쓴다. 이렇게 두 줄을 겹쳐두면 어느 환경도 빈손으로 두지 않는다.

3. 파인 화면과 안전 영역

화면 위쪽이 파이기 시작한 건 큰 사건이었다. 카메라와 센서를 넣느라 화면 한가운데 위쪽을 도려낸 그 모양을, 흔히 노치라 부른다. 요즘은 알약 모양으로 파인 것도, 구멍만 뚫린 것도 있다. 아래쪽엔 홈 인디케이터라는 막대가 지나가고, 네 귀퉁이는 둥글게 깎였다.


이 파인 부분들이 콘텐츠를 가린다. 화면 맨 위에 붙인 제목이 노치에 물리고, 맨 아래 버튼이 홈 막대에 가리고, 모서리에 둔 요소가 둥근 귀퉁이에 잘린다. 나는 이걸 처음 겪고 당황했다. 분명 화면 끝에 맞춰 뒀는데 그 끝이 시스템에 먹혀 있었다.


다행히 이 파인 영역들을 피해 갈 수 있는 값이 있다. 화면 각 변에서 시스템이 차지하는 안전하지 않은 영역의 크기를, 위아래 좌우 각각 읽어올 수 있다. 나는 화면 끝에 붙는 요소에 이 값을 여백으로 줘서, 노치 아래로, 홈 막대 위로, 둥근 귀퉁이 안으로 콘텐츠를 밀어 넣는다. 그러면 파인 화면에서도 글자와 버튼이 안전한 자리에 놓인다.


여기엔 전제가 하나 있다. 이 값을 쓰려면 먼저 화면을 파인 부분까지 포함한 전체로 확장하겠다고 선언해야 한다. 이 선언을 안 하면 브라우저가 애초에 안전한 영역 안쪽에만 그리기 때문에, 안전 영역 값이 전부 영으로 나와 무용지물이 된다. 나는 이 선언을 빠뜨려서 값이 왜 영으로만 나오나 한참 헤맨 적이 있다. 화면을 끝까지 쓰겠다고 먼저 말해야, 그 끝의 위험한 부분을 피하는 값도 살아난다.


안전 영역 값을 그대로 여백으로 쓰면 요소가 파인 부분에 딱 붙어 아슬아슬해 보인다. 이 값은 시스템이 차지하는 딱 그만큼이라 숨 쉴 여백이 영이기 때문이다. 나는 이 값에 얼마간의 여유를 더해, 파인 부분을 피하면서도 콘텐츠가 벽에 붙지 않고 여유를 갖게 한다. 배경은 화면 끝까지 시원하게 채우되, 정작 읽고 눌러야 할 글자와 버튼만 안전한 안쪽으로 들이는 게 요령이다.


방향에 따라 노치 위치가 달라진다는 점도 챙겨야 한다. 세로로 들었을 때는 노치가 위에 있지만, 가로로 눕히면 그 파인 부분이 왼쪽이나 오른쪽으로 옮겨 간다. 위쪽 여백만 챙기고 좌우를 잊으면, 가로로 눕혔을 때 콘텐츠가 옆의 노치에 물린다. 나는 안전 영역을 네 방향 모두 챙겨, 어느 방향으로 쥐어도 콘텐츠가 파인 부분을 피하게 한다. 세로만 확인하고 넘어가면 딱 가로에서 사고가 난다.


화면 아래 고정한 막대에서는 이 배려가 특히 빛난다. 아래에 붙는 탭 막대나 버튼은 홈 인디케이터와 자리를 다투기 쉬운데, 아래쪽 안전 영역 값만큼 바닥 여백을 밀어 올리면 그 막대가 홈 인디케이터 위로 얌전히 올라앉는다. 처음 결제 버튼이 홈 막대에 가렸던 그 사고를, 나는 바로 이 아래쪽 여백 하나로 해결했다. 알고 나면 한 줄이지만, 모르면 원인조차 못 찾는 종류의 문제다.

4. 돌리고 접히는 화면

화면은 고정돼 있지 않다. 사용자는 휴대폰을 가로로 눕히기도 하고, 접는 기기는 펼쳐서 화면을 두 배로 키우기도 한다. 나는 세로 화면만 상상하고 만든 화면이 가로로 눕는 순간 우스꽝스러워지는 걸 여러 번 봤다.


세로에서 멀쩡하던 첫 화면이 가로로 누우면 높이가 확 줄어, 세로로 꽉 채웠던 내용이 화면 밖으로 넘친다. 반대로 가로에서 넓게 퍼지던 요소가 세로에서는 답답하게 눌린다. 나는 방향에 따라 극단적으로 달라지는 배치는 피하고, 어느 방향이든 무리 없이 흐르도록 짜두는 편을 택한다. 방향을 강제로 하나로 고정하고 싶은 유혹도 있지만, 사용자가 어떻게 쥐든 그 선택을 존중하는 게 맞다.


접는 화면은 또 다른 숙제를 던진다. 펼쳤을 때 화면 한가운데 접힘 선이 지나가서, 그 자리에 중요한 버튼이나 글이 놓이면 접힘에 걸린다. 아직 이런 화면은 소수라 나도 깊이 대응하지는 않지만, 화면 한가운데를 피해 중요한 요소를 두는 정도의 습관은 들여두려 한다. 세상의 화면은 점점 더 이상한 모양으로 변해가고, 반듯한 사각형이라는 가정은 계속 배신당할 것이다.


가로로 눕혔을 때 특히 신경 쓰는 게 키보드다. 좁은 화면을 가로로 눕히고 입력창을 누르면, 화면 아래 절반을 키보드가 덮어버려 정작 입력하는 칸이 키보드 뒤로 숨는 일이 있다. 나는 입력 화면을 만들 때 화면이 낮아지는 상황을 함께 떠올려, 중요한 입력칸과 확인 버튼이 키보드에 가리지 않도록 배치를 살핀다. 넓고 여유로운 화면만 상상하면, 좁고 낮아진 순간에 꼭 무언가가 가려진다.


회전을 감지해 배치를 바꿀 수도 있지만, 나는 이걸 남용하지 않는다. 가로냐 세로냐로 딱 잘라 다른 배치를 주기보다, 폭과 높이의 실제 값에 반응하게 짜는 편이 견고하다. 같은 세로여도 작은 폰과 큰 태블릿은 사정이 다르고, 같은 가로여도 폰을 눕힌 것과 넓은 모니터는 전혀 다르기 때문이다. 방향이라는 거친 잣대보다, 실제 크기라는 정밀한 잣대가 더 많은 경우를 품는다.

5. 극단을 견디는 태도

이 모든 이야기를 관통하는 건 하나다. 특정 기기를 겨냥하지 말고, 극단을 견디게 짜라는 것이다. 나는 오래도록 유명한 몇몇 기기의 화면 크기를 외워두고 거기에 맞췄다. 그 목록에 없는 기기가 나올 때마다 화면이 깨졌다.


지금은 기기 목록을 외우지 않는다. 대신 화면을 아주 좁은 폭부터 아주 넓은 폭까지, 세로로 납작한 높이부터 길쭉한 높이까지 죽 훑으며, 어느 지점에서 무너지는지를 본다. 특정 기기가 아니라 값의 범위 전체를 견디게 만드는 것이다. 이렇게 짜두면 내가 한 번도 손에 쥐어본 적 없는 기기에서도 대체로 멀쩡하다.


파인 화면과 안전 영역도 같은 태도로 다룬다. 특정 기기의 노치 크기를 재서 그 숫자를 박아 넣으면, 다음 기기의 다른 노치에서 어긋난다. 시스템이 알려주는 안전 영역 값에 맡기면, 노치가 어떻게 생겼든 그 값이 알아서 달라진다. 내가 숫자를 외우는 대신 기기가 자기 사정을 알려주게 두는 것이다.


결제 버튼이 홈 막대에 가렸던 그 문의를 나는 아직 기억한다. 그 하나가 나에게, 화면은 내가 상상하는 반듯한 사각형이 아니라는 걸 가르쳤다. 이제 나는 새 화면을 만들면 일부러 파인 화면과 눕힌 화면, 좁고 넓은 극단을 골라 확인한다. 반듯한 화면에서 잘 되는 건 기본이고, 이상한 화면에서도 버티는 게 진짜 완성이다. 화면이 반듯할 거라는 믿음을 버리고 늘 의심하는 습관 하나가, 낯선 기기 앞에서 무너지지 않는 화면을 만든다. 다음 편에서는 이 온갖 화면을 실제로 어떻게 점검하고 문제를 찾아내는지, 반응형 테스트와 디버깅을 다룬다.