🎄 A11y Advent Calendar (번역) 7일차입니다. 전체 목록을 보고싶으시면 여기로 이동해주세요 :)
우리가 흔히 간과하는 점은, 스크린 리더와 같은 보조 기술들이 초기 웹 환경을 기반으로 설계되었다는 사실입니다. 이러한 기술들은 페이지가 리로드될 때 페이지의 컨텍스트, 즉 <title> 요소로 정의된 페이지 제목을 사용자에게 전달합니다.
SPA(Single Page Application)을 구축할 때는 어떤 프레임워크를 사용하든, 라우터 링크를 따라 탐색할 경우 다음 두 가지 작업을 반드시 수행해야 합니다:
- 새로운 뷰/페이지의 제목을 사용자에게 전달.
- 포커스를 적절히 유지하거나 필요한 위치로 이동
이를 해결하기 위한 좋은 방법은 탐색 시 새 페이지의 제목이 표시되는 시각적으로 숨겨진 요소를 페이지 상단에 배치하고, 포커스를 해당 요소로 이동시켜 보조 기술이 내용을 읽도록 하는 것입니다.
이상적으로는, 건너뛰기 링크(skip link)가 이 숨겨진 노드 바로 뒤에 배치되어, 사용자가 자연스러운 흐름으로 콘텐츠 영역으로 빠르게 이동할 수 있습니다. 구현 흐름은 다음과 같습니다:
- 사용자가 콘텐츠 영역 내의 라우터 링크를 클릭합니다.
- 새로운 뷰가 로드됩니다.
- 새 뷰의 제목이 보이지 않는 노드에 렌더링됩니다.
- 포커스가 해당 노드로 이동해 제목을 보조 기술로 전달합니다.
- 사용자가 탭 키를 한 번 누르면 건너뛰기 링크로 이동하며, 이를 통해 콘텐츠 영역으로 빠르게 복귀할 수 있습니다.
아래는 위 내용을 구현한 HTML 코드입니다.
<body>
<p tabindex="-1" class="sr-only">…</p>
<a href="#main" class="sr-only sr-only--focusable">Skip to content</a>
<!-- Rest of the page -->
</body>
리액트로 구현할때는 아래와 같이 <TitleAnnouncer /> 라는 컴포넌트를 정의하여 넣어줍니다.
import React from 'react'
import { useLocation } from 'react-helmet'
import { Helmet } from 'react-helmet'
const TitleAnnouncer = props => {
const [title, setTitle] = React.useState('')
const titleRef = React.createRef()
const { pathname } = useLocation()
const onHelmetChange = ({ title }) => setTitle(title)
React.useEffect(() => {
if (titleRef.current) titleRef.current.focus()
}, [pathname])
return (
<>
<p tabIndex={-1} ref={titleRef} className='sr-only'>
{title}
</p>
<Helmet onChangeClientState={onHelmetChange} />
</>
)
}
로딩 상태나 쿼리 오류와 관계없이 항상 관련 <h1> 요소가 존재한다는 것을 보장할 수 있다면, 숨겨진 요소를 사용하는 대신 해당 <h1> 요소에 포커스를 맞추는 것이 더 간단한 해결책이 될 수 있습니다. 이 경우에도 tabindex="-1" 속성을 추가하여 포커스를 관리할 수 있습니다.
참고로 NextJS에는 자체적으로 페이지 제목을 알리는 announcer를 제공하므로, 별도의 구현이 필요하지 않습니다
SPA의 접근성에 대해 궁금해져서 검색해보다 유익한 글을 발견해 함께 공유드립니다
(요약: SPA로 개발하면 브라우저가 기본적으로 제공하던 접근성 관련 기능을 우리가 직접 구현해야 하는 부분이 많다.. 🤓
또한, 접근성을 고려하여 개발하면 테스트에도 많은 이점이 있다고 합니다!)
'웹 접근성' 카테고리의 다른 글
Day 9) 접근성을 고려한 Form 설계 (0) | 2024.12.04 |
---|---|
Day 8) 이미지의 대체 텍스트(alt text) (0) | 2024.12.03 |
Day 6) Skip to Content를 추가하여 접근성 높이기 (0) | 2024.11.28 |
Day 5) 적절한 제목 계층 구조로 접근성 높이기 (0) | 2024.11.24 |
Day 4) 접근성을 고려한 링크 작성법 (0) | 2024.11.20 |