접근성 시리즈의 마지막 편이자, 웹 퍼블리싱 시리즈 전체의 마지막 편이다. 지금까지 시맨틱부터 자동 검사까지 접근성의 여러 갈래를 다뤘다. 이번 편은 그 모든 것을 아우르며, 내가 직접 저질렀거나 자주 목격한 흔한 실수들을 한자리에 모은다. 실수를 아는 것이 가장 빠른 배움이라 믿기에, 이 정리로 시리즈를 마무리한다.


돌아보면 나의 접근성 공부는 실수의 연속이었다. 좋은 뜻으로 붙인 것이 오히려 해가 되고, 멋져 보이려 한 것이 벽이 됐다. 그러나 그 실수들 하나하나가 나를 가르쳤다. 나는 이 편이 나와 같은 실수를 반복하지 않도록 돕는 지도가 되기를 바란다. 흔한 함정을 미리 알면, 접근성으로 가는 길이 한결 수월해진다.

1. 시맨틱을 버리는 실수

가장 근본적인 실수가 의미 있는 요소를 버리고 상자로 모든 것을 만드는 것이다. 버튼이 필요한데 상자 요소 div에 클릭만 붙이고, 링크가 필요한데 상자에 이동만 붙인다. 겉모습은 같지만 접근성은 통째로 사라진다. 나는 이 실수가 다른 모든 접근성 문제의 뿌리라는 걸 배웠다. 시맨틱을 버리면 그 위의 모든 것이 흔들린다.


상자로 만든 버튼은 키보드로 포커스가 가지 않고, 엔터로 눌리지도 않으며, 낭독기가 버튼이라 알리지도 못한다. 진짜 버튼 요소 button이 공짜로 주는 것을 전부 잃는 것이다. 나는 버튼이 필요한 자리에는 반드시 진짜 버튼 요소를 쓴다. 잃어버린 기능을 손으로 되살리느라 애쓰느니, 처음부터 제대로 된 요소를 쓰는 것이 훨씬 낫다.


이 실수는 대개 스타일을 자유롭게 하려는 마음에서 온다. 네이티브 요소는 꾸미기 어렵다는 오해다. 그러나 네이티브 요소도 얼마든지 원하는 모양으로 꾸밀 수 있다. 나는 모양 때문에 시맨틱을 버릴 필요가 없다는 걸 알고 나서, 진짜 요소를 쓰면서도 원하는 디자인을 얻는 법을 익혔다. 의미와 모양은 대립하지 않는다.


제목을 크기로 고르는 것도 시맨틱을 버리는 실수다. 글자를 작게 보이려고 낮은 단계 제목을 쓰거나, 크게 보이려고 높은 단계를 쓰면 문서의 목차가 망가진다. 나는 제목을 크기가 아니라 의미로 고르고, 크기는 스타일로 조절한다. 제목 단계는 낭독기 사용자의 목차이니, 보이는 크기 때문에 그 목차를 헝클면 안 된다.


이 실수를 피하는 길은 단순하다. 무언가를 만들기 전에 이 자리에 가장 어울리는 의미의 요소가 무엇인지 먼저 묻는 것이다. 나는 이 질문 하나를 습관으로 삼고 나서, 시맨틱을 버리는 실수를 거의 하지 않게 됐다. 요소를 의미로 고르는 이 작은 습관이 접근성의 가장 큰 토대를 지켜 준다.


정리하면 시맨틱을 버리고 상자로 모든 것을 만드는 것은 접근성 문제의 뿌리이며, 모양 때문에 의미를 버릴 필요가 없고, 제목은 크기가 아니라 의미로 고른다. 나는 요소를 의미로 고른다. 시맨틱을 지켰다면, 다음으로 흔한 실수는 요소에 이름을 빠뜨리는 것이다.

2. 이름을 빠뜨리는 실수

두 번째로 흔한 실수가 요소에 이름을 주지 않는 것이다. 텍스트 없는 아이콘 버튼, 대체 텍스트 없는 이미지, 라벨 없는 입력 칸이 대표적이다. 눈으로 보는 사람에게는 멀쩡해 보이지만, 낭독기 사용자에게는 정체불명의 요소가 된다. 나는 이름 없는 요소를 낭독기로 들으며 그 답답함을 실감하고, 이름 챙기기를 습관으로 삼았다.


아이콘만 있는 버튼이 특히 이 실수에 잘 빠진다. 돋보기 아이콘 하나만 있는 검색 버튼은 눈으로는 짐작되지만, 낭독기에는 이름이 없으면 그냥 버튼일 뿐이다. 나는 아이콘 버튼마다 무슨 버튼인지 이름을 챙긴다. 아이콘은 눈을 위한 것이고, 이름은 귀를 위한 것이라, 둘 다 있어야 모든 사용자가 버튼을 알아본다.


이미지의 대체 텍스트 속성 alt를 빠뜨리는 것도 흔하다. 속성을 아예 빼면 낭독기가 파일 이름을 읽어버린다. 정보 이미지에는 그 뜻을 담고, 장식 이미지에는 값을 비워 건너뛰게 해야 한다. 나는 이미지를 넣을 때마다 이 이미지가 정보인지 장식인지 가려, 그에 맞게 대체 텍스트를 챙기거나 비운다. 속성 자체를 빠뜨리는 일만은 없게 한다.


안내 문구로 라벨을 대신하는 것도 이름을 빠뜨리는 실수의 일종이다. 입력 칸에 흐린 안내 문구만 두고 라벨을 생략하면, 입력을 시작하는 순간 그 이름이 사라진다. 나는 안내 문구를 라벨 대신 쓰지 않고, 라벨은 라벨대로 두고 안내 문구는 보조로만 쓴다. 칸의 이름은 입력 중에도 사라지지 않고 늘 남아 있어야 한다.


이름을 빠뜨리는 실수는 낭독기로 들어보면 금세 드러난다. 이름 없는 버튼이 그냥 버튼이라고, 라벨 없는 칸이 그냥 편집이라고 들리기 때문이다. 나는 낭독기로 페이지를 훑으며 이름 없는 요소가 있는지 확인한다. 눈으로만 보면 절대 못 찾는 이 실수를, 귀로 들으면 하나하나 잡아낼 수 있다. 그래서 낭독기 청취가 중요하다.


정리하면 아이콘 버튼, 이미지, 입력 칸에 이름을 빠뜨리는 실수가 흔하고, 안내 문구는 라벨의 대용이 될 수 없으며, 이 실수는 낭독기로 들어야 드러난다. 나는 모든 요소에 이름을 챙긴다. 이름을 챙겼다면, 다음으로 자주 무너지는 곳은 포커스와 키보드다.

3. 포커스와 키보드 실수

포커스 표시를 지우는 것이 포커스 관련 가장 흔한 실수다. 디자인이 지저분해 보인다는 이유로 테두리 표시를 outline: none으로 꺼버리면, 키보드 사용자는 포커스가 어디 있는지 알 수 없게 된다. 나는 포커스 표시를 지우는 대신, 조건부 표시로 키보드 사용자에게만 또렷한 표시를 보여주는 법을 쓴다. 지우는 것은 답이 아니다.


키보드 함정을 만드는 것도 치명적인 실수다. 포커스가 어떤 영역에 들어간 뒤 빠져나오지 못하면, 키보드 사용자는 그 안에 갇힌다. 나는 커스텀 위젯을 만들 때 들어가는 길과 나오는 길을 짝으로 챙기고, 모달처럼 의도적으로 가두는 경우에도 반드시 탈출구를 둔다. 탭만으로 페이지를 순회하며 갇히는 곳이 없는지 확인한다.


포커스 순서를 억지로 조정하는 것도 실수다. 포커스 순서 속성 tabindex에 양수 값을 주어 순서를 강제로 매기면, 순서가 꼬이고 유지보수가 지옥이 된다. 나는 양수 값을 절대 쓰지 않고, 순서가 필요하면 코드 순서 자체를 바로잡는다. 자연 순서 편입에는 영 값을, 프로그램 포커스에는 음수 값만 쓰는 것으로 충분하다.


마우스로만 되는 기능을 남기는 것도 흔한 실수다. 드래그로만 옮길 수 있거나 마우스를 올려야만 나타나는 기능은 키보드 사용자에게 닿지 않는다. 나는 마우스에 기댄 동작마다 키보드 대안을 함께 마련한다. 마우스를 올려야 뜨는 메뉴는 포커스했을 때도 뜨게 하고, 드래그 기능에는 키보드로 하는 방법을 더한다.


이 모든 포커스와 키보드 실수는 직접 키보드로 써봐야 드러난다. 마우스로 확인하면 아무 문제가 없어 보이기 때문이다. 나는 새 페이지마다 마우스를 치우고 키보드만으로 처음부터 끝까지 써본다. 이 간단한 순회 하나가 포커스와 키보드의 흔한 실수 대부분을 잡아낸다. 키보드로 써보지 않으면 이 실수들은 숨어 있다.


정리하면 포커스 표시 지우기, 키보드 함정, 양수 순서 값, 마우스 전용 기능이 포커스와 키보드의 흔한 실수이며, 모두 키보드로 직접 써봐야 드러난다. 나는 키보드 순회로 이를 점검한다. 다음으로, 접근성을 도우려다 오히려 해치는 아리아의 실수를 살펴보자.

4. 아리아를 잘못 쓰는 실수

아리아는 잘 쓰면 강력하지만 잘못 쓰면 안 쓴 것보다 나쁘다. 가장 흔한 실수가 네이티브 요소로 되는 것을 굳이 아리아로 대체하는 것이다. 진짜 버튼을 쓰면 될 것을 상자에 버튼 역할만 붙이고 키보드 처리를 빠뜨리는 식이다. 나는 아리아를 붙이기 전에 이걸 요소로 할 수 없을까를 먼저 묻는다. 요소가 먼저, 아리아는 나중이다.


상태를 동기화하지 않는 것도 흔한 실수다. 접었다 펴는 컨트롤의 상태를 화면으로만 바꾸고 아리아 상태 값은 옛날 그대로 두면, 눈에는 새 상태가 보이는데 낭독기에는 옛 상태로 남는다. 나는 시각을 바꿀 때 아리아 상태도 반드시 함께 바꾼다. 화면과 상태가 어긋나면 낭독기 사용자에게 거짓을 말하는 셈이 된다.


보조기기 감춤 속성 aria-hidden을 잘못 쓰는 것도 위험하다. 이 속성으로 포커스를 받는 요소를 감싸면, 낭독기에는 안 읽히는데 키보드로는 포커스가 가는 유령이 생긴다. 나는 이 속성을 켤 때 그 안에 포커스 대상이 없는지 반드시 확인한다. 순수한 장식이나 중복 요소에만 쓰고, 조작할 수 있는 요소가 든 영역에는 쓰지 않는다.


동적 알림에서도 아리아 실수가 잦다. 알림 영역을 내용과 함께 새로 만들어 낭독을 놓치거나, 단호한 알림을 남용해 사용자의 흐름을 계속 끊는 것이다. 나는 알림 영역을 페이지가 뜰 때 미리 비워 두고 내용만 바꾸며, 대부분의 알림은 정중한 방식으로 두고 단호한 방식은 정말 급한 경우에만 아껴 쓴다. 알림도 절제가 필요하다.


이 실수들의 공통점은 좋은 뜻으로 아리아를 붙였다가 오히려 해가 된다는 것이다. 아리아는 조심스럽게 다뤄야 하는 강력한 도구다. 나는 아리아를 최후의 수단으로 아껴 쓰고, 쓸 때는 그것이 기대하는 동작과 상태 동기화까지 함께 챙긴다. 반쪽만 쓴 아리아는 사용자를 더 헷갈리게 하니, 쓰려면 온전히 써야 한다.


정리하면 네이티브로 될 것을 아리아로 대체하기, 상태 미동기화, 감춤 속성 오용, 알림 실수가 아리아의 흔한 함정이며, 잘못 쓴 아리아는 안 쓴 것보다 나쁘다. 나는 아리아를 아껴 쓰고 온전히 쓴다. 마지막으로, 이 모든 실수를 아우르는 가장 근본적인 실수를 짚으며 시리즈를 맺는다.

5. 접근성을 미루는 실수

가장 근본적인 실수는 접근성을 나중으로 미루는 것이다. 다 만든 뒤에 접근성을 끼워 넣으려 하면, 구조를 뜯어고쳐야 할 때가 많아 고칠 것이 산더미가 된다. 나는 접근성을 마지막에 덧붙이려다 애먹은 뒤로, 처음부터 함께 설계하는 것이 훨씬 쉽다는 걸 배웠다. 접근성은 마감이 아니라 시작에 챙길 일이다.


접근성을 특별한 별도 작업으로 여기는 것도 미루는 실수의 한 형태다. 접근성을 나중에 할 특별한 단계로 보면 자꾸 뒤로 밀린다. 나는 접근성을 별도 작업이 아니라 잘 만든 페이지의 자연스러운 특성으로 본다. 의미에 맞는 요소를 쓰고, 이름을 챙기고, 키보드로 써보는 일상적인 습관 속에 접근성이 녹아 있는 것이다.


완벽을 기다리며 아무것도 안 하는 것도 실수다. 접근성을 한 번에 완벽하게 하려다 부담에 눌려 시작조차 못 하는 경우가 있다. 나는 완벽보다 시작이 중요하다고 믿는다. 대체 텍스트 하나, 제대로 연결한 라벨 하나가 실제로 누군가의 경험을 바꾼다. 지금 할 수 있는 하나를 챙기는 것이 완벽을 기다리는 것보다 언제나 낫다.


도구의 통과를 완성으로 착각하는 것도 흔한 실수다. 자동 검사가 통과라고 해도 실제로는 쓰기 어려울 수 있다. 나는 도구의 결과를 시작점으로 삼고, 키보드와 낭독기로 직접 확인하는 것을 완성으로 삼는다. 자동과 수동을 함께 해야 접근성이 온전해진다는 것을, 이 시리즈 내내 되풀이해 강조한 이유가 여기 있다.


이렇게 웹 퍼블리싱 시리즈를 마친다. 시맨틱한 마크업으로 시작해, 스타일과 반응형을 거쳐, 접근성으로 마무리했다. 이 모든 것을 관통하는 하나의 태도는 사용자를 먼저 생각하는 것이다. 나는 화면 너머에 다양한 사람이 있다는 것을 잊지 않으려 한다. 눈으로 보는 사람, 소리로 듣는 사람, 키보드로 오가는 사람 모두가 나의 사용자다.


정리하면 접근성을 나중으로 미루거나 별도 작업으로 여기거나 완벽을 기다리거나 도구의 통과에 안심하는 것이 가장 근본적인 실수이며, 접근성은 처음부터 함께 짜고 꾸준히 지켜 가는 일이다. 웹은 누구에게나 열려 있어야 한다는 그 처음의 약속을, 나는 이 시리즈를 마치며 다시 마음에 새긴다. 모두를 위한 웹, 그것이 우리가 만들 웹이다.