단체 톡방에서 처음으로 소식을 들었는데요. 계엄 선포가 된 거면 정말 큰 일인데 아무런 안내가 없어서 이게 진짜 맞나? 싶더라고요. 비상계엄 선포 방송 때도 수어통역이 없어서 농인들은 계엄 소식을 알 수가 없었다고 하더라고요. 계엄 해제가 안됐더라면 일상이 완전히 무너질 만한 중요한 일이었는데 정보 전달이 안돼서 대비할 새 없이 속수무책으로 당할 수 있었다고 생각하니 더 아찔하게 느껴졌습니다.
관계없이 모든 사람이 접근할 수 있도록 하는 것은 필수적인 요소이다.”라고 말했습니다. 저도 웹이야 말로 접근성을 확장하기에 가장 좋은 매체라고 생각해요. 그래서 웹 프론트엔드 개발자로서 누구나 접근 가능한 방식으로 웹을 만들기 위해 책임감을 가져야한다고 생각하고 있어요.
마크업 할 때 html 요소에 WAI-AREA 속성을 넣어주면 스크린리더에서 잘 읽어주도록 처리할 수 있습니다. 텍스트를 가지고 있지 않은 아이콘 같은 요소는 스크린리더가 읽지 않기 때문에 실제로 유저가 존재를 알아야 하는 요소라면 라벨링도 해줘야 하고요. 키보드로만 요소를 이동할 수 있도록 대응해줘야 합니다. 또, 모바일은 PC와 다르게 키보드가 없기 때문에 모바일 스크린 리더를 위해 따로 처리해줘야 하는 것도 있고요. 실제로 스크린리더에서 잘 읽히는지 voiceover나 talkback과 같은 스크린리더로 테스팅도 해야 합니다. 간단하게만 정리해봐도 정말 공수가 많이 들 것 같고 이걸 언제 다 대응하나 절망적이게 느껴지는데요. 1번부터 시도해보려고 해도 뭐부터 해줘야하나 막막한데요. 저는 어디 베스트 프랙티스라도 있다면 클론 코딩하면서 익히고 싶다는 생각부터 들더라고요.
4가지 분류로 나눠보았는데요. Headless는 로직만 제공하고 스타일은 완전히 사용자가 정의하는 방식, Unstyled은 최소한의 스타일만 제공하고, 사용자가 자유롭게 커스터마이징 가능한 방식, Style Starter은 기본 스타일이나 테마를 제공하는 방식, Full UI Kit, Design System은 스타일 완성도가 높고 완전한 UI 스타일을 제공하는 방식입니다.
높은 프로젝트에 좋은 라이브러리입니다. 또, 최소한의 스타일만 제공하는 unstyled 방식의 라이브러리이기 때문에 커스터마이징 하기 편하지만 스타일을 정의하는 과정이 필요하기 때문에 사용 편의성은 약간 낮은 편입니다. Install 명령어를 보시면 특이한 점이 있는데 필요한 컴포넌트를 각각 설치하는 방식으로 사용합니다.
기준으로 실제 컴포넌트를 VoiceOver로 읽을 때 어떻게 읽는지 확인해봤는데요. 들을 때 어떠신 것 같나요? 내용이 잘 이해가 되시나요? Button의 Collapsed 상태도 잘 읽고 다이얼로그가 뜰 때 초점도 잘 이동합니다. 확인이 아닌 취소 버튼부터 초점이 이동하게 만든 것도 의도한 동작 같네요. 다이얼로그에서 탭하면 다이얼로그 안에서만 초점이 이동하고요. 다만 다이얼로그로 이동할 때 내용이 아닌 버튼부터 읽는 건 약간 어색하게 느껴지지만 어쨌든 내용도 잘 읽어줍니다. 다이얼로그를 닫으면 초점도 다시 잘 돌아오고요.
입혀 래핑한 라이브러리라 radix입니다. shadcn의 특징은 설치하는 방식 이외에도 코드 스니펫을 제공해 radix만 설치하고 shadcn의 컴포넌트 코드를 복사 붙여넣기 해서 사용할 수 있다는 점입니다. 기존에 정의된 스타일을 덮어쓸 필요 없이 그냥 복사한 코드를 바로 수정하면 된다는 점이 편리합니다. 설치할 필요가 없으니 tailwind를 사용하고 있다면 한번 찍먹해보셔도 좋을 것 같아요.
디자인 시스템 방식의 라이브러리이기 때문에 커스터마이징 자유도는 조금 떨어지는 대신 스타일을 따로 정의할 필요 없이 바로 가져다 쓸 수 있어서 편의성이 높습니다. 유의할 점은 MUI는 emotion에 대한 의존성을 가지고 있다는 점입니다. 특히 SSR에서는 styled-component 대신 emotion을 사용하라고 강하게 권장하고 있습니다.
다른 점은 aria-modal이 정의되어 있습니다. 이 속성은 현재의 dialog가 모달 상태, 즉 dialog 외부 콘텐츠에 접근할 수 없는 상태임을 스크린리더에게 알리는 역할입니다. Radix에서는 이 속성 대신 hideOthers 함수로 다이얼로그 외부의 요소는 무시하게끔 처리하고 있었죠.
이동하지 않아서 탭을 해야 이동하고 본문도 읽어주지 않고 탭을 하면 다이얼로그 안에서만 초점이 이동해야 하는데 밖으로 벗어나버립니다. alert dialog만 이러고 다른 컴포넌트는 잘 대응이 됐을 수도 있겠지만요. alert dialog면 중요한 정보를 전달하고 있는 컴포넌트일텐데 정말 접근성 대응이 잘 되어 있는지 의심이 되긴 합니다.
방식의 react aria, unstyled 방식의 react aria components, design system 방식의 react spectrum 라이브러리로 구분되어 있습니다. React-aria는 hook에서 반환한 prop을 개발자가 마크업한 요소에 넣어주는 방식으로 사용합니다.
점으로 모바일 스크린 리더까지 대응하고 있다는 점을 얘기했습니다. 많은 라이브러리들이 ARIA Rractices Guide를 기반으로 구현하고 있는데 여기에도 제대로 다루고 있지 않은 부분이라고요. 예를 들면 모바일에서는 키보드가 없어서 팝요소를 없애고 싶을 때 esc 키로 없앨 수 없습니다. React aria는 Esc 키를 대신할 숨겨진 버튼을 제공하는 방식으로 대응하고 있다고 합니다.
방법을 아주 짧게 설명해보려고 하는데요. 일단 이슈를 찾습니다. 우리는 이미 headless ui의 alert dialog 이슈를 하나 찾았죠? 그런 다음 레포를 포크하고 컨트리뷰팅 가이드를 확인합니다. 가이드에 맞춰서 디버깅을 하고 test code나 가이드에 제시되어 있는 방식대로 테스팅을 진행합니다. 문제없이 동작하면 PR을 올립니다.