지금까지 나는 시맨틱 요소만 잘 써도 접근성의 많은 부분이 해결된다고 강조했다. 그런데 시맨틱만으로는 표현하기 어려운 순간이 있다. 텍스트 없는 아이콘 버튼의 이름, 접었다 편 상태, 동적으로 바뀌는 알림 같은 것들이다. 이럴 때 보조기기에 추가 정보를 전하는 도구가 아리아다. 이번 편은 그 아리아의 기초를 다룬다.


나는 아리아를 처음 배울 때 만능 도구인 줄 알고 여기저기 붙였다. 그런데 화면 낭독기로 들어보니, 잘못 붙인 아리아가 오히려 혼란을 키우고 있었다. 아리아는 강력하지만 그만큼 위험한 도구였다. 이 편에서 나는 아리아가 무엇을 하고 무엇을 못 하는지, 그리고 언제 써야 하고 언제 쓰지 말아야 하는지를 정리한다.

1. 아리아가 하는 일

아리아는 요소의 역할, 상태, 속성을 보조기기에 알려주는 도구다. 이 요소는 버튼이다, 지금 펼쳐져 있다, 지금 선택되어 있다 같은 정보를 접근성 트리에 더한다. 화면 낭독기는 이 정보를 읽어 사용자에게 전한다. 나는 아리아를 요소에 의미의 이름표를 덧붙이는 도구로 이해한다. 눈에는 안 보이지만 보조기기에는 또렷이 전해지는 이름표다.


아리아가 바꾸는 것은 오직 보조기기가 인식하는 정보뿐이다. 화면의 겉모습은 조금도 바뀌지 않는다. 아리아를 붙여도 눈으로 보는 사람에게는 아무 변화가 없고, 오직 낭독기 사용자에게만 그 정보가 전해진다. 나는 이 점을 분명히 이해하고 나서, 아리아를 시각적 효과가 아니라 보조기기 전용 정보 전달 수단으로 다루게 됐다.


여기서 가장 중요한 사실이 하나 있다. 아리아는 동작을 만들어 주지 않는다는 것이다. 아리아는 이 요소가 버튼이라고 알릴 뿐, 실제로 눌리게 만들지는 않는다. 키보드 조작이나 기능은 여전히 직접 코드로 짜야 한다. 나는 이 사실을 오해했다가 헛수고를 한 적이 있어, 아리아는 알림이지 기능이 아니라는 점을 늘 되새긴다.


그래서 아리아를 붙였다면 그에 걸맞은 동작도 함께 만들어야 한다. 요소에 버튼 역할 role을 붙였다면, 엔터와 스페이스로 눌리게 하고 포커스를 받게 하는 처리를 직접 더해야 한다. 역할만 붙이고 동작을 빠뜨리면 겉만 버튼인 함정이 된다. 나는 아리아와 동작을 항상 짝으로 챙기며, 하나만 있고 다른 하나가 없는 상태를 경계한다.


아리아는 접근성 트리라는 보이지 않는 구조를 다룬다. 브라우저는 화면과 별도로, 보조기기를 위한 요소들의 의미 구조를 만든다. 아리아는 바로 이 구조를 손보는 도구다. 나는 이 구조를 상상하며 아리아를 다룬다. 눈에 보이는 화면 뒤에, 낭독기가 읽는 또 하나의 화면이 있다고 생각하면 아리아의 역할이 또렷해진다.


정리하면 아리아는 역할과 상태와 속성을 보조기기에 알리는 도구로, 겉모습은 바꾸지 않고 접근성 트리만 손보며, 동작은 만들어 주지 않으니 기능은 따로 짜야 한다. 나는 아리아를 알림 전용 도구로 이해한다. 그렇다면 이 강력한 도구를 언제 써야 할까. 그 답은 뜻밖에도 되도록 쓰지 말라는 것이다.

2. 안 쓰는 것이 최선이다

아리아의 첫 번째 규칙은 되도록 아리아를 쓰지 말라는 것이다. 언뜻 이상하게 들리지만, 이 규칙은 아리아 자료 어디에나 나오는 핵심 원칙이다. 네이티브 요소로 표현할 수 있는 것을 굳이 아리아로 대체하지 말라는 뜻이다. 나는 이 규칙을 배우고 나서 아리아를 붙이기 전에 먼저 이걸 요소로 할 수 없을까를 묻게 됐다.


이 규칙이 있는 이유는 잘못 쓴 아리아가 안 쓴 것보다 나쁘기 때문이다. 네이티브 버튼을 쓰면 역할, 포커스, 키보드가 모두 따라오지만, 상자에 버튼 역할만 붙이고 나머지를 빠뜨리면 반쪽짜리 버튼이 된다. 낭독기는 버튼이라 알리는데 실제로는 눌리지 않는 혼란이 생긴다. 나는 이런 반쪽짜리가 사용자를 더 헷갈리게 한다는 걸 겪었다.


그래서 순서는 항상 요소가 먼저, 아리아가 나중이다. 버튼이 필요하면 버튼 요소를, 링크가 필요하면 링크 요소를, 목록이 필요하면 목록 요소를 먼저 떠올린다. 이 네이티브 요소들이 아리아 없이도 역할과 조작을 공짜로 준다. 나는 이 순서를 지키면서 아리아를 쓸 일 자체가 크게 줄었고, 그만큼 접근성 함정도 줄었다.


아리아를 남용하면 유지보수도 어려워진다. 역할과 상태를 손으로 붙이면, 상태가 바뀔 때마다 그 값을 손으로 갱신해야 한다. 하나라도 빠뜨리면 낭독기에는 옛 상태로 남는다. 네이티브 요소는 이런 갱신을 브라우저가 알아서 하니 실수할 여지가 없다. 나는 손이 덜 가고 실수가 적은 네이티브 요소를 늘 우선한다.


그렇다면 아리아는 언제 쓸까. 네이티브 요소로 도저히 표현할 수 없을 때만 쓴다. 텍스트 없는 아이콘 버튼에 이름을 주거나, 접힘과 펼침 상태를 알리거나, 여러 개의 같은 영역을 구분하는 것처럼 요소만으로는 전할 수 없는 정보를 더할 때다. 나는 아리아를 요소로 안 되는 틈을 메우는 보조 도구로 이해하고, 딱 그런 자리에만 쓴다.


정리하면 아리아의 첫 규칙은 되도록 쓰지 않는 것이고, 잘못 쓴 아리아는 안 쓴 것보다 나쁘며, 순서는 언제나 요소가 먼저다. 나는 아리아를 최후의 수단으로 아껴 쓴다. 이제 정말 아리아가 필요한 자리들을 하나씩 보자. 첫째는 텍스트가 없는 요소에 이름을 붙이는 경우다.

3. 이름을 직접 붙이는 속성

보이는 텍스트가 없는 요소에 이름을 붙이는 속성이 aria-label이다. 이 속성에 문자열을 담으면, 그 문자열이 요소의 접근 가능한 이름이 된다. 화면 낭독기는 이 이름을 읽어 사용자에게 요소가 무엇인지 알린다. 나는 이 속성을 텍스트 없는 요소에 목소리를 주는 도구로 이해한다. 눈에는 안 보이지만 귀에는 들리는 이름이다.


가장 흔한 쓰임은 아이콘만 있는 버튼이다. 돋보기 아이콘 하나만 있는 검색 버튼은 눈으로는 짐작이 되지만, 낭독기 사용자에게는 이름이 없으면 그냥 버튼일 뿐이다. 여기에 이 속성으로 검색이라는 이름을 주면 비로소 낭독기가 검색 버튼이라고 알린다. 나는 아이콘 버튼을 만들 때마다 이 이름을 챙기는 것을 습관으로 삼았다.


이 속성을 쓸 때 아이콘 자체는 보조기기에서 숨긴다. 버튼에 이미 이름을 주었으니, 안에 든 아이콘까지 낭독기가 읽으면 중복이 된다. 그래서 장식으로 든 아이콘은 보조기기에서 감춰 이름만 읽히게 한다. 나는 아이콘 버튼을 만들 때 버튼에는 이름을 주고 아이콘은 숨기는 두 처리를 짝으로 하여 깔끔한 낭독을 만든다.


이 속성은 요소 안의 텍스트를 덮어쓴다는 점도 알아야 한다. 버튼에 보이는 글자가 있는데 이 속성으로 다른 이름을 주면, 낭독기는 보이는 글자가 아니라 이 속성의 이름을 읽는다. 이러면 보이는 것과 읽히는 것이 어긋난다. 나는 보이는 텍스트가 있는 요소에는 이 속성을 함부로 쓰지 않고, 정말 텍스트가 없을 때만 쓴다.


이 속성을 오남용하면 오히려 접근성을 해친다. 멀쩡한 텍스트가 있는데도 습관적으로 이 속성을 붙여 엉뚱한 이름을 씌우는 경우가 있다. 나는 이 속성을 쓰기 전에 이 요소에 정말 보이는 이름이 없는지 먼저 확인한다. 텍스트가 있으면 그대로 두고, 없을 때만 이 속성으로 이름을 채운다. 남용은 함정으로 가는 지름길이다.


정리하면 이름을 직접 붙이는 이 속성은 텍스트 없는 아이콘 버튼 같은 요소에 목소리를 주되, 아이콘은 보조기기에서 숨기고, 요소 안 텍스트를 덮어쓴다는 점을 유의하며, 텍스트가 없을 때만 쓴다. 나는 이 속성을 텍스트가 없는 자리에만 아껴 쓴다. 그런데 이름을 문자열로 적는 대신 페이지의 기존 텍스트로 만들 수도 있다.

4. 기존 텍스트로 이름 만들기

이름을 문자열로 직접 적지 않고, 페이지에 이미 있는 요소를 참조해 만드는 속성이 aria-labelledby다. 이 속성에 다른 요소의 식별자를 담으면, 그 요소의 텍스트가 이 요소의 이름이 된다. 나는 이 속성을 이미 화면에 보이는 제목을 이름으로 재활용하는 도구로 이해한다. 같은 내용을 두 번 적지 않아도 되는 것이다.


예를 들어 어떤 영역에 이미 제목이 있다면, 그 영역에 이 속성으로 제목을 참조시킨다. 그러면 낭독기가 그 영역을 이 제목의 영역이라고 알린다. 이름을 따로 지어낼 필요 없이 눈에 보이는 제목을 그대로 이름으로 쓰는 것이다. 나는 여러 영역이 있는 페이지에서 이 방식으로 각 영역에 눈에 보이는 이름을 자연스럽게 붙인다.


이 속성은 앞서 본 문자열 이름 속성보다 우선한다. 두 속성이 한 요소에 함께 있으면, 낭독기는 참조로 만든 이름을 택한다. 그래서 이름을 만드는 여러 방법 중 이 참조 방식이 가장 강력하다. 나는 이 우선순위를 알아두어, 이름이 예상과 다르게 읽힐 때 어느 속성이 이기고 있는지 짚어내는 단서로 삼는다.


참조는 여러 요소를 한꺼번에 엮을 수도 있다. 이 속성에 여러 식별자를 나열하면, 그 텍스트들이 순서대로 이어져 하나의 이름이 된다. 흩어진 조각을 모아 완전한 이름을 만드는 것이다. 나는 이름의 부분들이 화면 여기저기에 흩어져 있을 때, 이 방식으로 조각을 모아 뜻이 통하는 하나의 이름으로 조립하곤 한다.


참조로 이름을 만들 때는 화면에 보이는 텍스트가 이름에 담기게 하는 것이 좋다. 낭독기로 읽히는 이름이 눈에 보이는 텍스트를 포함하면, 음성으로 조작하는 사용자가 보이는 글자를 그대로 말해 요소를 부를 수 있다. 나는 보이는 것과 읽히는 것을 일치시키는 이 원칙을 지켜, 시각과 청각 사용자 모두가 같은 이름으로 요소를 다루게 한다.


정리하면 기존 텍스트로 이름을 만드는 이 속성은 페이지의 제목 같은 요소를 재활용해 이름을 짓고, 문자열 이름보다 우선하며, 여러 조각을 이어 붙일 수도 있다. 나는 눈에 보이는 텍스트를 이름으로 살릴 때 이 방식을 쓴다. 이름이 정해졌다면, 이제 이름이 아닌 부가 설명을 붙이는 마지막 속성으로 넘어가자.

5. 부가 설명을 연결하는 속성

이름이 아니라 부가 설명을 연결하는 속성이 aria-describedby다. 이 속성에 설명이 담긴 요소의 식별자를 담으면, 낭독기가 요소의 이름을 읽은 뒤 이어서 그 설명을 읽어 준다. 이름은 이것이 무엇인가를, 설명은 어떻게 쓰는가나 무엇을 주의해야 하는가를 알린다. 나는 이 둘의 역할을 나누어 이해하고 각각 알맞게 쓴다.


대표적인 쓰임이 입력 칸의 도움말이다. 비밀번호 칸에 여덟 자 이상이어야 한다는 안내를 이 속성으로 연결하면, 낭독기가 비밀번호라는 이름을 읽은 뒤 그 규칙까지 읽어 준다. 눈으로 보는 사람이 칸 아래 안내를 보듯, 낭독기 사용자도 같은 안내를 듣는 것이다. 나는 형식 규칙이 있는 입력마다 이 속성으로 안내를 연결한다.


오류 메시지를 연결할 때도 이 속성을 쓴다. 입력에 오류가 나면, 그 오류 메시지를 이 속성으로 입력에 연결한다. 그러면 낭독기가 그 입력에 포커스했을 때 무엇이 잘못됐는지 바로 읽어 준다. 나는 오류를 색으로만 표시하지 않고 이 속성으로 텍스트 설명까지 연결해, 낭독기 사용자도 오류의 원인과 해결법을 알 수 있게 한다.


이름과 설명을 구분하는 것이 핵심이다. 이름에는 요소가 무엇인지를 짧게 담고, 설명에는 부가 정보를 담는다. 둘을 뒤섞으면 이름이 길고 장황해져 낭독이 지친다. 나는 짧고 또렷한 이름과 필요한 만큼의 설명을 나누어, 낭독기 사용자가 먼저 무엇인지 알고 이어서 자세한 안내를 듣게 한다. 이 구분이 깔끔한 낭독을 만든다.


설명은 필요한 만큼만 담는 것이 좋다. 모든 입력에 긴 설명을 붙이면 낭독이 늘어지고 사용자가 지친다. 정말 안내가 필요한 곳에만 설명을 연결하고, 자명한 곳에는 두지 않는다. 나는 이 속성을 쓸 때 이 설명이 없으면 사용자가 헤맬까를 묻고, 그렇다면 붙이고 아니면 생략한다. 절제가 좋은 접근성의 일부다.


정리하면 부가 설명을 연결하는 이 속성은 도움말이나 오류 메시지를 요소에 이어 붙여 낭독기가 이름 뒤에 읽게 하며, 이름과 설명의 역할을 나누고 필요한 만큼만 담는다. 나는 이름과 설명을 구분해 다룬다. 여기까지가 이름과 설명을 다루는 아리아의 기초다. 다음 편에서는 요소의 역할과 상태를 알리는 아리아를 더 깊이 파고든다.