웹 접근성

Day 7) SPA와 접근성: 페이지 제목과 포커스 관리하기

권끼리마끼리 2024. 12. 2. 13:51

🎄  A11y Advent Calendar (번역) 7일차입니다. 전체 목록을 보고싶으시면 여기로 이동해주세요 :)

 

우리가 흔히 간과하는 점은, 스크린 리더와 같은 보조 기술들이 초기 웹 환경을 기반으로 설계되었다는 사실입니다. 이러한 기술들은 페이지가 리로드될 때 페이지의 컨텍스트, 즉 <title> 요소로 정의된 페이지 제목을 사용자에게 전달합니다.

 

SPA(Single Page Application)을 구축할 때는 어떤 프레임워크를 사용하든, 라우터 링크를 따라 탐색할 경우 다음 두 가지 작업을 반드시 수행해야 합니다:

  1. 새로운 뷰/페이지의 제목을 사용자에게 전달.
  2. 포커스를 적절히 유지하거나 필요한 위치로 이동

이를 해결하기 위한 좋은 방법은 탐색 시 새 페이지의 제목이 표시되는 시각적으로 숨겨진 요소를 페이지 상단에 배치하고, 포커스를 해당 요소로 이동시켜 보조 기술이 내용을 읽도록 하는 것입니다.

 

이상적으로는, 건너뛰기 링크(skip link)가 이 숨겨진 노드 바로 뒤에 배치되어, 사용자가 자연스러운 흐름으로 콘텐츠 영역으로 빠르게 이동할 수 있습니다. 구현 흐름은 다음과 같습니다:

  1. 사용자가 콘텐츠 영역 내의 라우터 링크를 클릭합니다.
  2. 새로운 뷰가 로드됩니다.
  3. 새 뷰의 제목이 보이지 않는 노드에 렌더링됩니다.
  4. 포커스가 해당 노드로 이동해 제목을 보조 기술로 전달합니다.
  5. 사용자가 탭 키를 한 번 누르면 건너뛰기 링크로 이동하며, 이를 통해 콘텐츠 영역으로 빠르게 복귀할 수 있습니다.

아래는 위 내용을 구현한 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 7) Page Title in SPA