스크린 리더 사용자를
고려한 히든 콘텐츠

React 앱 접근성 개선 #02

A11Y

A11Y

GOAL

A11Y

히든 콘텐츠 : 화면에 보이진 않지만, 스크린 리더에서 읽힘

Voice Over, OSX

A11Y

올바른 히든 콘텐츠를 제공하지 않으면?
스크린 리더 사용자의 혼란 야기!

버튼 컴포넌트의 레이블(히든 콘텐츠)을 올바로 제공하지 않은 예시

A11Y

<div style="display: none"> ... </div>

<div style="visibility: hidden"> ... </div>

<div hidden> ... </div>
.a11y-hidden {
  position: absolute;
  clip: rect(0 0 0 0);
  width: 1px;
  height: 1px;
  overflow: hidden;
  margin: -1px;
  border: 0;
  padding: 0;
  white-sapce: nowrap;
}

잘못된 vs 올바른 '히든 콘텐츠' 처리

✔︎

A11Y

import React from 'react'

const App = (props) => (
  <React.Fragment>
    
    <h1>kakako TV</h1>

    <h2 className="a11y-hidden">검색</h2>

    <h3 className="a11y-hidden">kakako TV 홈 메뉴</h3>

    <h3>인기 PD 동영상</h3>

    <h3 className="a11y-hidden">카테고리 별 인기 동영상 슬롯</h3>

    <h4>예능 최신 인기 동영상 바로가기</h4>

    <h4>드라마 최신 인기 동영상 바로가기</h4>

  </React.Fragment>
)

히든 콘텐츠 CSS 클래스

A11Y

히든 콘텐츠 CSS 클래스 실습

A11Y

import React, { Component } from 'react'

const styles = {
  position: 'absolute',
  clip: 'rect(0 0 0 0)',
  width: '1px',
  height: '1px',
  overflow: 'hidden',
  margin: '-1px',
  border: 0,
  padding: 0,
  whiteSapce: 'nowrap'
}

class A11yHidden extends Component {

  state = { isFocus: false }

  changeStateFocused = () => {
    this.setState({ isFocus: true })
  }

  changeStateBlured = () => {
    this.setState({ isFocus: false })
  }

  render() {
    let attrs = {}
    for (let [key, value] of Object.entries(this.props)) {
      if(key === 'tag' || key === 'focusable') { continue }
      attrs[key] = value
    }
    const { tag, focusable } = this.props
    const { isFocus } = this.state
    const Tag = tag || 'span'
    return (
      <Tag 
        style={!focusable ? styles : isFocus ? null : styles } 
        {...attrs}
        onFocus={focusable && this.changeStateFocused} 
        onBlur={focusable && this.changeStateBlured} />
    )
  }

}

export default A11yHidden

히든 콘텐츠 컴포넌트 (Class)

A11Y

히든 콘텐츠 컴포넌트 활용

import React from 'react'
import A11yHidden from './components/A11yHidden'

const App = (props) => (
  <React.Fragment>
    
    <h1>kakako TV</h1>

    <A11yHidden tag="h2">검색</A11yHidden>

    <A11yHidden tag="h3">kakako TV 홈 메뉴</A11yHidden>

    <h3>인기 PD 동영상</h3>

    <A11yHidden tag="h3">카테고리 별 인기 동영상 슬롯</A11yHidden>

    <h4>예능 최신 인기 동영상 바로가기</h4>

    <h4>드라마 최신 인기 동영상 바로가기</h4>

  </React.Fragment>
)

A11Y

히든 콘텐츠 컴포넌트 응용

<!-- span 요소로 처리 -->
<A11yHidden> ... </A11yHidden>

<!-- a 요소, href 속성 설정 -->
<A11yHidden tag="a" href="#target"> ... </A11yHidden>

<!-- button 요소, 포커스 상태가 되면 화면에 표시 / 블러 상태가 되면 다시 화면에서 감춤 -->
<A11yHidden tag="button" focusable> ... </A11yHidden>

<!-- button 요소, 포커스 상태에서 화면에 표시 될 버튼을 스타일링 -->
<A11yHidden tag="button" focusable className="button"> ... </A11yHidden>

A11Y

히든 콘텐츠 오류 ➪ 올바로 사용하기

<button>
  <i class="_1QY7TzdLHKX3-BKPDNNYKF"></i>
  <svg 
    width="20px" 
    height="22px" 
    viewBox="0 0 20 22" xmlns="http://www.w3.org/2000/svg"
  >
    <title>ic_share_B</title>
    ...
  </svg>
</button>
<button>
  <A11yHidden>프로젝트 공유하기</A11yHidden>
  <svg
    aria-hidden="true" 
    width="20px" 
    height="22px" 
    viewBox="0 0 20 22" xmlns="http://www.w3.org/2000/svg"
  >
    ...
  </svg>
</button>

A11Y

히든 콘텐츠 오류 ➪ 올바로 사용하기

✔︎

A11Y

히든 콘텐츠 컴포넌트 실습

A11Y

히든 콘텐츠

React 앱 접근성 개선 #02

화면에 보이지 않더라도, 읽혀야 되는 콘텐츠는 '올바른 감춤 처리' 되어야 합니다.

'올바른 감춤 처리'는 스크린 리더 사용자에게 탐색에 용이한 정보를 제공합니다.

React 사용자는 A11yHidden 컴포넌트 활용을 고려해 볼 수 있습니다.

Made with Slides.com