버튼 컴포넌트
접근성

React 앱 접근성 개선 #03

A11Y

A11Y

GOAL

A11Y

GOAL

A11Y

버튼 컴포넌트 : 클릭, 포커싱 가능하며 기능 동작 수행

A11Y

모양은 분명 버튼인데...
스크린 리더 사용자에겐 어떻게 들릴까?

모양만 버튼이고, 실제 버튼이 아닌 링크가 사용 된 예시

A11Y

<a href="#none" class="btn btn_v2 btn_left"> 이전보기 </a>
<a href="#none" class="btn btn_v2 btn_right"> 다음보기 </a>
<a href="#none" class="btn btn_v2 btn_play"> 롤링플레이버튼 </a>
<button type="button" class="btn btn_v2 btn_left"> 이전 보기 </button>
<button type="button" class="btn btn_v2 btn_right"> 다음 보기 </button>
<button type="button" class="btn btn_v2 btn_play"> 롤링 플레이 </button>

문제는 모양만 버튼일 뿐, 실제 버튼이 아니라는 점!

—   스크린 리더에서 '링크'로 콘텐츠를 읽은 이유는 <a> 요소로 마크업이 구성되었기 때문

—   링크를 버튼 모양으로 꾸미는 대신, 버튼 요소를 사용해 의미적, 접근적으로 개선

A11Y

캐러셀 인디케이터(Indicator)는?

인디케이터

A11Y

맙소사! 키보드 접근도 안되고..
스크린 리더는 왜 '히어로 이미지'라고만 말하는 거지?

마우스로만 클릭 가능하고, 스크린 리더는 '히어로' 이미지 라고만 읽어주는 예시

A11Y

<div class="HeroWidget">
  <div>
    <img src="..." alt="히어로">
  </div>
  <div>
    <img src="..." alt="히어로">
  </div>
  ...
</div>

문제는 모양만 인디케이터일 뿐,
이미지를 사용하고 동일한
대체 텍스트를 작성한 것! 

—   이미지 요소는 키보드로 포커스 적용이 안되는 비 포커스 요소로 마우스 없이는 기능을 작동 시킬 수 없음

히어로

히어로

히어로

히어로

히어로

A11Y

<div class="HeroWidget">
  <div>
    <button type="button">
      <img src="..." alt>
      <span class="a11y-hidden">더워도 걱정 없는 아이스 립 파우치</span>
    </button>
  </div>
  ...
</div>

웹 표준에 <indicator> 요소는 없으므로,
<button> 요소로 커스텀 구성하는 것이 적절!

—   <button> 요소를 사용해 키보드 접근성 부여, 텍스트는 히든 콘텐츠 처리

A11Y

A11Y

import React, { Component } from 'react'
import A11yHidden from './components/A11yHidden'

const Control = (props) => {
  const c_name = props.prev ? 'btn-prev' : props.next ? 'btn-next' : ''
  return (
    <button 
      type="button" 
      className={c_name}
      onClick={props.onClick}
    >
      <A11yHidden>{ props.children }</A11yHidden>
    </button>
  )
}

export default Control

Control 컴포넌트 (<button> 요소 활용)

A11Y

import React, { Component } from 'react'
import A11yHidden from './components/A11yHidden'
import placeholder from '../assets/placeholder-indicator.jpg'

class Indicator extends Component {
  state = { isActive: false }
  render() {
    const { isActive } = this.state
    const { image, label } = this.props
    return (
      <div className={`indicator ${isActive ? 'is-active' : ''}`}>
        <button type="button" className="btn-indicator">
          <img src={ image || placeholder } alt />
          <A11yHidden>{label}</A11yHidden>
        </button>
      </div>
    )
  }
}

export default Indicator

Indicator 컴포넌트  (<button> 요소 활용)

A11Y

import React, { Component } from 'react'
import Indicator from './Indicator'

const Indicators = (props) => (
  props.indicators.map(indicator => 
    <Indicator 
      key={indicator.id}
      image={indicator.image} 
      label={indicator.label} />
  )
)

export default Indicators

Indicators 컴포넌트

A11Y

버튼 컴포넌트 접근성

React 앱 접근성 개선 #03

버튼에 해당되는 UI 컴포넌트는 <button> 요소를 사용합니다.

<button> 요소는 키보드 포커스 가능한 요소이며, 키 이벤트를 사용할 수 있습니다.

<div>, <span>, <img>와 같은 요소를 사용해 버튼 처럼 꾸미는 것은 좋지 않습니다.

링크, 버튼의 각 역할을 바로 알고 구분해 사용해야 합니다. (참고 영상)

Made with Slides.com