반쪽짜리 모달과 제대로 만든 모달

알아 두세요

이 결과가 실제 장애인 사용자의 검증을 대신하지는 못합니다. 에이전트가 막혔다면 실제로도 문제가 있을 가능성이 높지만, 끝까지 갔다고 해서 문제가 없다는 뜻은 아닙니다. 실제 스크린리더가 읽어 주는 순서나 가상 커서 동작은 흉내 내지 않습니다. 한계와 실제 사용자 검증 방법

고치기 전

고치기 전 · 신청 취소 버튼을 눌러 대화상자를 연다

https://demo.codeslog.com/book/vibe-a11y/ch14/broken-modal.html

  • 키보드 에이전트: 3단계에서 막힘, 다 했다고 했지만 성공 조건과 맞지 않음 (페이지 쪽 문제일 가능성이 큼)
  • 스크린리더 에이전트: 5단계에서 막힘, 다 했다고 했지만 성공 조건과 맞지 않음 (페이지 쪽 문제일 가능성이 큼)

고치기 전 · 키보드 에이전트: 3단계에서 막힘

페이지 구조는 보지만 마우스는 쓰지 않습니다. 포커스 표시가 보이지 않으면 지금 어디에 있는지 모릅니다.

  1. 1단계 화면. 대화상자가 닫혀 있고 포커스가 없는 초기 상태를 인지했다. Tab 정지점은 6개이며 신청 취소 버튼은 네 번째 정지점으로 추정된다.

    1단계

    포커스: 없음

    파악한 것: 대화상자가 닫혀 있고 포커스가 없는 초기 상태를 인지했다. Tab 정지점은 6개이며 신청 취소 버튼은 네 번째 정지점으로 추정된다.

    하려는 일: Tab을 4회 눌러 신청 취소 버튼에 포커스를 이동시키려 한다.

    한 일: Tab

    결과: 4회

  2. 2단계 화면. 신청 취소 버튼에 포커스가 위치한 것을 인지했다.

    2단계

    포커스: 신청 취소 버튼

    파악한 것: 신청 취소 버튼에 포커스가 위치한 것을 인지했다.

    하려는 일: Enter 키를 눌러 대화상자를 열고자 한다.

    한 일: Enter 키

  3. 3단계 화면. 막힘: 신청 취소 버튼에서 Enter를 누른 후 '정말 취소하시겠어요?' 대화상자 콘텐츠가 트리에 나타난 것을 인지했다.

    3단계⚠ 막힘

    포커스: 신청 취소 버튼

    파악한 것: 신청 취소 버튼에서 Enter를 누른 후 '정말 취소하시겠어요?' 대화상자 콘텐츠가 트리에 나타난 것을 인지했다.

    하려는 일: 대화상자가 열렸음을 확인하고 과업을 완료 처리하고자 한다.

    한 일: 다 했다고 판단, 다 했다고 했지만 성공 조건과 맞지 않음

    결과: 완료 주장. 성공 조건과 맞지 않아 막힘으로 기록

원인 판단: 페이지 쪽 문제일 가능성이 큼

근거

  • 성공 조건인 role=dialog의 '정말 취소하시겠어요?' 요소가 open 상태로 확인되지 않아 과업은 충족되지 않았다.
  • Tab 4회로 '신청 취소' 버튼에 정확히 도달했고 Enter로 활성화까지 성공해, 조작 경로 탐색 자체에는 실패가 없었다.
  • Enter 이후에도 트레이스의 dialog 플래그가 false로 유지되고 포커스가 여전히 트리거 버튼에 남아 있어, 모달이 dialog 역할로 노출되지 않고 포커스 이동·상태 통지가 이루어지지 않는 구조 결함이 드러난다.
  • 페이지 이름 자체가 broken-modal이며, 키보드 사용자가 대화상자 진입 여부를 확인할 수단이 제공되지 않았다는 점에서 앱 측 결함으로 귀속된다.
  • 텍스트 콘텐츠가 트리에 나타난 것만으로 성공을 단정해 검증되지 않은 완료 주장로 종료했으므로, 해석 낙관이라는 부차적 요인도 존재한다.

실제 스크린리더에서는 다를 수 있는 점

  • 접근성 트리에 '정말 취소하시겠어요?' 텍스트가 나타난 것을 대화상자 열림으로 해석했으나, 실제 스크린리더에서는 role=dialog와 aria-modal이 없으면 모드 전환 자체가 안내되지 않아 사용자가 변화를 인지하지 못할 수 있다.
  • 포커스가 트리거 버튼에 머문 상태를 문제로 삼지 않았지만, 실제 사용자는 가상 커서를 직접 이동하지 않는 한 새 콘텐츠에 도달하지 못할 수 있다.
  • 트리 스냅샷의 노드 존재만 확인했으므로, 시각적으로는 오버레이가 떠 있으나 배경 콘텐츠가 aria-hidden 처리되지 않아 스크린리더가 배경과 모달을 구분하지 못하는 상황을 놓쳤을 수 있다.
  • 에이전트가 관찰한 Tab 정지점 6개는 대화상자 열림 전 값일 수 있어, 실제로는 포커스 트랩 부재로 Tab이 배경 요소로 빠져나가는지 검증되지 않았다.

고치기 전 · 스크린리더 에이전트: 5단계에서 막힘

화면은 보지 않습니다. 접근성 트리에서 제목, 랜드마크, 지금 포커스가 있는 곳과 그 주변 몇 줄만 읽습니다.

  1. 1단계 화면. 페이지 개요를 확인했고 본문(main) 랜드마크가 있음을 인지했다. 신청 취소 버튼은 아직 읽기 창에 보이지 않는다.

    1단계

    포커스: 없음

    파악한 것: 페이지 개요를 확인했고 본문(main) 랜드마크가 있음을 인지했다. 신청 취소 버튼은 아직 읽기 창에 보이지 않는다.

    하려는 일: 본문 랜드마크로 이동하여 신청 취소 버튼을 찾는다.

    한 일: 랜드마크로 건너뛰기

    결과: 읽기 창 이동(브라우저 동작 없음)

  2. 2단계 화면. 본문 랜드마크로 이동했으나 아직 신청 취소 버튼을 찾지 못했다. 읽기 창에는 안내 리스트만 보인다.

    2단계

    포커스: 없음

    파악한 것: 본문 랜드마크로 이동했으나 아직 신청 취소 버튼을 찾지 못했다. 읽기 창에는 안내 리스트만 보인다.

    하려는 일: 읽기 창을 다음으로 이동하여 신청 취소 버튼을 탐색한다.

    한 일: 다음 줄 읽기

    결과: 읽기 창 이동(브라우저 동작 없음)

  3. 3단계 화면. 안내 텍스트만 확인했고 실제 신청 취소 버튼 요소는 아직 읽기 창에 나타나지 않았다.

    3단계

    포커스: 없음

    파악한 것: 안내 텍스트만 확인했고 실제 신청 취소 버튼 요소는 아직 읽기 창에 나타나지 않았다.

    하려는 일: 읽기 창을 더 이동하여 신청 취소 버튼 요소를 찾는다.

    한 일: 다음 줄 읽기

    결과: 읽기 창 이동(브라우저 동작 없음)

  4. 4단계 화면. 읽기 창에서 '신청 취소' 버튼(n=30, ref=e24)을 발견했다.

    4단계

    포커스: 없음

    파악한 것: 읽기 창에서 '신청 취소' 버튼(n=30, ref=e24)을 발견했다.

    하려는 일: 신청 취소 버튼을 활성화하여 대화상자를 연다.

    한 일: 누르기

  5. 5단계 화면. 막힘: 신청 취소 버튼을 활성화한 후 개요에 '정말 취소하시겠어요?' 헤딩이 새로 나타난 것을 인지했다. 다만 dialogOpen 속성은 false로 표시되어 있다.

    5단계⚠ 막힘

    포커스: 신청 취소 버튼

    파악한 것: 신청 취소 버튼을 활성화한 후 개요에 '정말 취소하시겠어요?' 헤딩이 새로 나타난 것을 인지했다. 다만 dialogOpen 속성은 false로 표시되어 있다.

    하려는 일: 헤딩 목록에 대화상자 관련 제목이 나타난 것으로 보아 버튼 클릭으로 대화상자 내용이 열렸다고 판단하고 과업 완료를 선언한다.

    한 일: 다 했다고 판단, 다 했다고 했지만 성공 조건과 맞지 않음

    결과: 완료 주장. 성공 조건과 맞지 않아 막힘으로 기록

원인 판단: 페이지 쪽 문제일 가능성이 큼

근거

  • 성공 조건인 role=dialog 요소의 open 상태가 충족되지 않았고, 에이전트는 검증 없이 완료를 선언했다(검증되지 않은 완료 주장).
  • 4단계에서 '신청 취소' 버튼 활성화는 정상 수행되었으므로 컨트롤 도달·활성화 자체는 문제가 없었다.
  • 활성화 후 '정말 취소하시겠어요?' 헤딩만 개요에 추가되었을 뿐 dialogOpen은 false로 남았다. 즉 모달 콘텐츠가 dialog 역할/aria-modal로 노출되지 않아 접근성 트리상 대화상자로 인식될 수 없는 구조적 결함(broken-modal 페이지)이 원인이다.
  • 활성화 후에도 포커스가 버튼에 그대로 머물러 있어 대화상자로의 포커스 이동 및 상태 변화 통지가 이루어지지 않았다.
  • 에이전트가 dialogOpen=false를 인지하고도 헤딩 출현만으로 완료를 판단한 점은 판정 오류이나, 어떤 추가 조작으로도 dialog 역할이 생성되지 않는 구조였으므로 주된 귀인은 앱 결함으로 본다.

실제 스크린리더에서는 다를 수 있는 점

  • 개요 헤딩 목록에 '정말 취소하시겠어요?'가 나타난 것을 대화상자 열림으로 해석했으나, 실제 스크린리더 사용자는 포커스가 이동하지 않아 해당 콘텐츠의 출현 자체를 인지하지 못할 수 있다.
  • 접근성 트리 스냅샷에서는 모달 텍스트가 읽을 수 있는 노드로 존재하지만, 실제 스크린리더에서는 배경 콘텐츠와 구분되지 않아 모달 경계·닫기 수단을 파악하기 어려울 수 있다.
  • 활성화 액션이 ok:true로 반환된 것이 시각적 모달 표시를 의미할 뿐, 실제 AT 통지(라이브 리전/포커스 이동)가 발생했다는 근거는 트레이스에 없다.
  • 에이전트가 dialogOpen 속성이라는 도구 전용 신호에 접근할 수 있었던 반면, 실제 스크린리더 사용자에게는 그런 상태 단서조차 제공되지 않는다.

고친 뒤

고친 뒤 · 신청 취소 버튼을 눌러 대화상자를 연다

https://demo.codeslog.com/book/vibe-a11y/ch14/ok-modal.html

  • 키보드 에이전트: 4단계 만에 끝까지 감
  • 스크린리더 에이전트: 5단계 만에 끝까지 감

막힌 곳이 없었습니다. 접근성 트리의 제목·랜드마크·포커스와 키보드 조작만 살펴본 결과입니다.

고친 뒤 · 키보드 에이전트: 4단계 만에 끝까지 감

페이지 구조는 보지만 마우스는 쓰지 않습니다. 포커스 표시가 보이지 않으면 지금 어디에 있는지 모릅니다.

  1. 1단계 화면. 대화상자가 닫혀 있고 포커스가 아직 이동하지 않은 초기 상태를 인지했다. '신청 취소' 버튼이 페이지의 세 번째 탭 정지점으로 보인다.

    1단계

    포커스: 없음

    파악한 것: 대화상자가 닫혀 있고 포커스가 아직 이동하지 않은 초기 상태를 인지했다. '신청 취소' 버튼이 페이지의 세 번째 탭 정지점으로 보인다.

    하려는 일: Tab을 3회 눌러 '신청 취소' 버튼에 포커스를 이동시키려 한다.

    한 일: Tab

    결과: 3회

  2. 2단계 화면. 포커스가 '화면 모드' 콤보박스에 있음을 인지했다. '신청 취소' 버튼은 아직 도달하지 못했다.

    2단계

    포커스: 화면 모드 선택 상자

    파악한 것: 포커스가 '화면 모드' 콤보박스에 있음을 인지했다. '신청 취소' 버튼은 아직 도달하지 못했다.

    하려는 일: Tab을 눌러 '신청 취소' 버튼으로 포커스를 이동시키려 한다.

    한 일: Tab

  3. 3단계 화면. '신청 취소' 버튼에 포커스가 위치한 것을 확인했다.

    3단계

    포커스: 신청 취소 버튼

    파악한 것: '신청 취소' 버튼에 포커스가 위치한 것을 확인했다.

    하려는 일: Enter 키를 눌러 버튼을 활성화하고 대화상자를 연다.

    한 일: Enter 키

  4. 4단계 화면.

    4단계

    포커스: 닫기 버튼

판정 근거

근거

  • 성공 조건 전부 충족

실제 스크린리더에서는 다를 수 있는 점

  • 접근성 트리 기준 완료이며 실제 스크린리더 발화는 검증하지 않음

고친 뒤 · 스크린리더 에이전트: 5단계 만에 끝까지 감

화면은 보지 않습니다. 접근성 트리에서 제목, 랜드마크, 지금 포커스가 있는 곳과 그 주변 몇 줄만 읽습니다.

  1. 1단계 화면. 페이지 개요에서 main 랜드마크와 헤딩들을 확인했으나 아직 신청 취소 버튼을 찾지 못했다.

    1단계

    포커스: 없음

    파악한 것: 페이지 개요에서 main 랜드마크와 헤딩들을 확인했으나 아직 신청 취소 버튼을 찾지 못했다.

    하려는 일: main 랜드마크로 이동하여 신청 취소 버튼을 탐색한다.

    한 일: 랜드마크로 건너뛰기

    결과: 읽기 창 이동(브라우저 동작 없음)

  2. 2단계 화면. main 랜드마크로 이동했으나 신청 취소 버튼은 아직 읽기 창에 보이지 않는다.

    2단계

    포커스: 없음

    파악한 것: main 랜드마크로 이동했으나 신청 취소 버튼은 아직 읽기 창에 보이지 않는다.

    하려는 일: 읽기 창을 다음으로 이동하여 신청 취소 버튼을 탐색한다.

    한 일: 다음 줄 읽기

    결과: 읽기 창 이동(브라우저 동작 없음)

  3. 3단계 화면. 읽기 창에서 '신청 취소'라는 강조 텍스트를 발견했으나 이는 안내문 내의 텍스트이며 실제 버튼 요소가 아직 보이지 않는다.

    3단계

    포커스: 없음

    파악한 것: 읽기 창에서 '신청 취소'라는 강조 텍스트를 발견했으나 이는 안내문 내의 텍스트이며 실제 버튼 요소가 아직 보이지 않는다.

    하려는 일: 읽기 창을 계속 이동하여 실제 '신청 취소' 버튼 요소를 탐색한다.

    한 일: 다음 줄 읽기

    결과: 읽기 창 이동(브라우저 동작 없음)

  4. 4단계 화면. 읽기 창에서 '신청 취소' 버튼을 발견했다.

    4단계

    포커스: 없음

    파악한 것: 읽기 창에서 '신청 취소' 버튼을 발견했다.

    하려는 일: 해당 버튼을 activate하여 대화상자를 연다.

    한 일: 누르기

  5. 5단계 화면.

    5단계

    포커스: 닫기 버튼

판정 근거

근거

  • 성공 조건 전부 충족

실제 스크린리더에서는 다를 수 있는 점

  • 접근성 트리 기준 완료이며 실제 스크린리더 발화는 검증하지 않음