-
Notifications
You must be signed in to change notification settings - Fork 2
[FE] 땅콩 접근성 개선기
방 참여 → 게임 초대 → 게임 시작 → 옵션 선택 → 라운드 결과
스크린 리더 사용자가 게임이 시작되고 라운드가 진행될 때, 화면이 전환되더라도 현재 상황을 이해할 수 있는 것을 목적으로 하였다.
개선 최종 목표: 땅콩을 스크린리더로 무리 없이 사용할 수 있다.
1차 스프린트
: 핵심 기능이 포함된 페이지 개선
- 게임 화면, 투표 결과 화면
2차 스프린트
: 그 외 기능이 포함된 페이지 개선
- 닉네임 설정 화면, 대기 방 화면, 매칭 결과 화면
-
Semantic tag를 쓰자
-
ARIA 속성은 꼭 필요한 경우에만 사용한다
-
문서를 잘 읽자
-
스크린리더 전용 컴포넌트를 사용하자
- 닉네임이 최대 12 글자인데 최대 글자에 도달한 것을 리더기에서 인지할 수 없는 상황.
- 닉네임이 12 글자가 되어 더 이상 입력하지 못하는 경우 이를 사용자에게 알려주고 싶다.
- 닉네임에 focus가 되어도 리더기에서 제대로 인지하지 못함
- 현재 닉네임에 focus가 되었는지 여부를 리더기 사용자에게 알리고 싶음
- 닉네임이 최대 글자에 도달하면 “최대 길이에 도달했습니다“라는 안내 메세지가 나온다.
- “aria-label”과 “aria-live” 닉네임에 focus 될 때와 닉네임을 입력할 때 알 수 있도록 설정하였다.
- 방 설정 컴포넌트에 focus가 되었을 때 설정 내용들이 여러 태그에 흩어져 있어 내용이 한 번에 읽히지 않는 상황
- 리더기 사용자에게 카테고리/라운드 수/제한 시간을 한 번에 읽게 하고 싶다.
- 방 설정 모달
- 카테고리 선택 목록
- 어떤 선택 목록인지 알 수 없다.
- 목록이 열려있고 스와이프 했을 때 요소로 넘어가지 못한다.
- 목록 중 몇 번째인지 알 수 없다.
- 목록 중 어느 것이 선택되어 있는지 알 수 없다.
- 선택 후 포커스를 잃는다.
- 라운드, 제한 시간
- 어떤 설정 값이 선택되어 있는지 알 수 없다.
- 몇 개의 목록 중 몇 번째인지 알 수 없다.
- 카테고리 선택 목록
- 공통으로 만든 “A11Only” 컴포넌트를 사용하여 방 정보를 한 번에 읽을 수 있도록 수정하였다.
- 방 설정 모달
- 카테고리 선택 목록
-
어떤 선택 목록인지 알 수 있다.
📢 카테고리 선택 목록, 현재 선택: 연애, 팝업 버튼, 상자 팝업, 피커를 활성화 하려면 이중탭 하십시오.
-
목록이 열려있고 스와이프를 했을 때 다음 요소를 읽을 수 있다.
📢 카테고리 선택 목록 -> 연애 -> 만약에 -> MBTI -> 음식
-
목록의 시작과 끝을 알 수 있다.
📢 연애 목록 시작 -> ... -> 음식 목록 끝
-
해당 옵션이 선택되어 있는지 알 수 있다.
📢 선택됨 음식
-
옵션 선택 후 포커스가 다시 선택 목록이 된다.
-
- 라운드, 제한 시간
-
어떤 설정 값이 선택되어 있는지 알 수 있다.
📢 5 선택 버튼 선택됨
-
몇 개의 옵션 중 몇 번째인지 알 수 없다.
📢총 3개 중 1번째
-
- 카테고리 선택 목록
- 게임이 시작되었는데 게임이 시작되었는지 알 수 없었다.
- 게임 화면으로 넘어갔을 때 전체 라운드와 현재 라운드를 알려주면 좋겠다.
- 헤더의 텍스트를 끊어서 읽고 불필요한 정보까지 전달한다.
- 헤더에서 게임 정보를 알려주면 좋겠다.
- 옵션이 선택된 옵션인지 알 수 없었다.
- 옵션 중 하나만 선택 가능하고, 선택 가능한 옵션인지 알려주면 좋겠다.
- 현재 타이머가 몇초 남았는지 알 수 없었다.
- 기준을 세우고, 기준에 따라서 사용자에게 현재 타이머를 알려주면 좋겠다.
- 게임 화면으로 넘어갔을 때 전체 라운드, 현재 라운드, 질문, 제한 시간을 안내하여 게임을 수월하게 진행하도록 개선하였다.
- 처음 라운드 시작되었을 때, 절반 지났을 때, 5초 남았을 때로 총 3번으로 나눠서 제한시간을 알려주었다.
role=”alert”
를 사용하여 특정 지점에서 제한 시간을 안내하도록 설정하였다. - 옵션이 이미 선택된 경우
선택됨
이라고 안내 음성이 나오며,radio
와radiogroup
을 사용하여 두 개 중 몇 번째라는 안내 음성을 제공한다.
before / afer 좀 더 직관적으로 확인할 수 있게 영상을 같이 첨부해주세요
import { ElementType, AriaRole, PropsWithChildren } from 'react';
import { a11yOnlyLayout } from './A11yOnly.styled';
interface A11yOnlyProps<T extends ElementType = 'span'> {
as?: T;
role?: AriaRole;
}
const A11yOnly = <T extends ElementType = 'span'>({
as,
children,
...props
}: PropsWithChildren<A11yOnlyProps<T>>) => {
const Component = as || 'span';
return (
<Component css={a11yOnlyLayout} {...props}>
{children}
</Component>
);
};
export default A11yOnly;
두 가지 방향으로 코드를 작성해 보고, A11yOnly 컴포넌트를 적용한 코드가 가독성이 더 좋고 유지 보수를 하기에 용이하다고 생각했기 때문이다.
개선 전
_.mov
개선 후
_._.mov
개선 전
_.mov
개선 후
_.mov
개선 전
_.mov
개선 후
_.mov
Modal을 열고 닫을 때 focus가 제대로 된 위치를 찾지 못하고 있는 상황
- 문제점: Modal이 mount 되었을 때 focus가 Modal의 내부가 아닌 Modal의 바깥쪽에서 움직이고 있는 상황
- 해결: Modal이 mount 되었을 때 useRef 사용하여 Modal에 ref를 넣고 useEffect 내부에서 Modal ref의 focus 함수를 실행시켜 Focus가 Modal로 오게 만듦
modal-focus.mp4
- 문제점: Modal이 unmount 될 때 focus 기존에 있었던 위치로 돌아가지 않고 엉뚱한 곳으로 focus가 돌아가는 상황
- 해결: 현재 구현 방식은 Modal이 특정 버튼을 클릭하면 Modal 호출 함수가 실행되고 Modal이 뜨는 방식이다. 그래서 호출 함수에 인자로 “특정 버튼의 ref”를 넣어주어 Modal 에서 unmount 될 때 인자로 전달해준 ref로 focus가 되도록 구현해서 리더기 사용자가 Modal 닫히더라도 계속해서 서비스를 이용할 수 있게 만듦
modal-close.mp4
- 문제점: 버튼을 눌러 다음 페이지로 넘어갈 경우 다음 페이지에서의 fosuc가 맨 위로 올라오는 것이 아닌 이전 페이지의 버튼 위치에 계속 머물러 있어. 리더기 사용자 입장에서는 당황스러운 상황
- 해결: Header 태그에 ref를 넣고 useEffect 내부에서 매 페이지가 첫 로딩 될 때 마다 ref의 focus 함수를 실행시킨다.