React 앱 접근성 개선 #02
GOAL
Voice Over, OSX
버튼 컴포넌트의 레이블(히든 콘텐츠)을 올바로 제공하지 않은 예시
<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;
}
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>
)
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
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>
)
<!-- 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>
<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>
React 앱 접근성 개선 #02
화면에 보이지 않더라도, 읽혀야 되는 콘텐츠는 '올바른 감춤 처리' 되어야 합니다.
'올바른 감춤 처리'는 스크린 리더 사용자에게 탐색에 용이한 정보를 제공합니다.
React 사용자는 A11yHidden 컴포넌트 활용을 고려해 볼 수 있습니다.