그외 aria-속성들에 대해 알아보자.
콤보박스, 탭, 버튼과 같이 특정 element(controlling element)가 다른 element(controlled element)를 변경할 수 있다면 controlling element에 aria-controls를 정의한다.
aria-controls가 정의하는 값은 이 element가 컨트롤하고 있는 element의 id이다.
둘다 element 간의 관계를 보여주기 위해 사용한다. 차이점은, aria-controls는 controlled-controlling 관계에 초점이 맞춰져있고 aria-owns는 DOM에서는 아니지만 문맥적으로 부모-자식 관계일 때 이를 표현하기 위해 사용한다.
실제 DOM에서는 부모-자식 관계가 아닌 element 사이에서 부모-자식 관계를 표현하기 위해 사용한다. (하지만 이 역시 가능하다면 DOM에서 부모 자식으로 표현하는 게 베스트이다.)
부모로 생각되는 element에 aria-owns='자식으로 생각되는 element id'를 정의한다.
만약 DOM 상에서 자식 element가 존재한다면 focus 순서는 자식 element → aria-owns로 지정된 element 순이다.
aria-expanded는 controlled element가 expanded 상태인지를 표현한다. aria-controls와 함께 사용하는 경우가 많다.
<button aria-expanded="false" aria-controls="widget1">Show widget</button>해당 element가 interactive popup element를 트리거할 수 있음을 알려준다. 여기서 interactive popup element는 menu, listbox, tree, grid, dialog가 해당하고 tooltip은 interactive하지 않아서 제외된다.
계속 언급하지만 popup 기능이 있는건 아니라서 popup이 되는 기능은 직접 정의해야 한다.
interactive element는 accessible name이 있어야 한다. 예를 들어 button의 accessible name은 버튼 태그 안의 텍스트이다. <label for…>와 함께 사용되는 element에서는 label에 들어가는 텍스트가 accessible name 역할을 한다.
<!-- 아래 버튼의 accessible name은 ok -->
<button> ok </button>
<!-- 아래 input의 accessible name은 Kraken -->
<input type="radio" id="kraken" name="monster" value="K" />
<label for="kraken">Kraken</label>
몇몇 경우에 이 accessible name을 지정할 수 없는 경우가 있는데 이 때 aria-label을 사용할 수 있다. 예를 들어 button 안에 text 대신 svg가 들어있다면 aria-label을 사용해서 accessible name을 지정할 수 있다.
<button aria-label="Close" onclick="myDialog.close()">
<svg
aria-hidden="true"
focusable="false"
.../>
</button>
aria-label과 마찬가지로 대상의 accessible name을 지정하는 역할이다. aria-labelledby에 다른 element의 id를 지정하면 aria-labelledby로 지정된 element가 해당 element의 accessible name을 지정하는 대상이 된다.
<span
role="checkbox"
aria-checked="false"
tabindex="0"
aria-labelledby="tac"></span>
<span id="tac">I agree to the Terms and Conditions.</span>
<main>,<nav><footer>, <article>, <header><img>에서는 alt, <input>은 <label>과 함께 사용하자aria-selected, aria-checked, aria-current, aria-pressed 모두 element의 ‘현재 상태’에 대해 설명하고, role에 따라 다른 attributes를 적용한다.
role이 gridcelll, options, row, tab인 경우 현재 ‘선택된’ 상태를 표현할 때 사용한다. 두 개 이상의 element가 동시에 선택 가능할 땐 aria-multiselectable='true'을 같이 적용해준다.
role이 radio button, checkbox일 때 현재 checked된 상태를 나타내기 위해 사용한다. 마찬가지로 input태그의 type='checkbox', type='radio'를 사용한다면 필요없다.
<span
role="checkbox"
id="checkBoxInput"
aria-checked="false"
tabindex="0"
aria-labelledby="chk15-label"></span>
<label id="chk15-label">Subscribe to the newsletter</label>
여러 element 중에서 현재 활성화된 무언가를 정의하기 위해 사용한다. aria-current= page, step, location, date, time, true, false가 가능하다. 디폴트는 false이고 빈값으로 정의하거나 빈 문자열일 경우에도 false로 설정된다. 반면에 non-null 문자열은 aria-current='true'로 취급된다.
페이지 링크가 여러 개 있을 때 유저가 현재 있는 페이지의 링크 element에 aria-current='page'를 정의한다.
<nav aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="../../../../">Accessibility</a>
</li>
<li>
<a href="../../../">ARIA</a>
</li>
<li>
<a href="../../">ARIA States and Properties</a>
</li>
<li>
<a href="./" aria-current="page">ARIA: `aria-current` attribute</a>
</li>
</ol>
</nav>
서베이 혹은 여러 단계로 구성된 프로세스에서 현재 단계에 해당하는 element에 aria-current='step'을 표시한다.
토클 버튼에서 현재 눌린 상태임을 나타낸다. role='button'에서 aria-pressed를 정의하면 토클 버튼이 된다.
이 역시 aria-pressed를 사용하기 보단, <button>을 사용하여 직접 label을 변경한다거나 style을 변경해주는 게 좋다.
aria-hidden, role='presentation' 모두 접근성 트리에서 무언가를 숨긴다는 공통점이 있다. aria-hidden은 element 자체를 숨기고 presentation은 element의 semantic을 숨긴다.
non-interactive한 컨텐츠 자체를 접근성 트리에서 숨기는데 사용하는 속성이다. (hidden처럼 실제로 숨기는 건 아니다.)
순수 데코 목적의 컨텐츠(ex.아이콘이나 이미지). 가장 많이 사용하는 예시이다.
<button type="button" aria-label="Previous section" class="previous-button">
<VarcoIcon name="doubleChevronLeft" class="icon" aria-hidden="true" />
</button>
만약 <img>를 사용한다면 alt를 사용해서 해결 가능하다.
<button><img src="doubleChevronLeft.svg" alt=""></button>
중복된 컨텐츠 ex) 반복되는 텍스트
스크린을 벗어났거나 열고 닫히는 컨텐츠 ex) 메뉴
HTML 속성인 hidden이 존재할 때
element 혹은 element 조상이 display:none 혹은 visitbility: hidden 상태일 때
element 혹은 element 조상이 focusable할 때
role='presentation'과 함께
<!-- 잘못된 예시 -->
<div aria-hidden="true">
<button>press me</button>
</div>
<!-- 아래 예시에서 aria-hidden은 무의미하다. -->
<span id="msg" style="display:none" aria-hidden="true">hidden message</span>
반면에 아래와 같이 focusable하지 않은 element라면 interactive하더라도 사용 가능하다.
<!--사용 가능 -->
button {opacity:0}
<button tabindex="-1" aria-hidden="true">press me</button>
role='none'이 없어지고 대체되었다. aria-hidden은 아예 접근성 트리에서 element를 숨긴다면 presentiation은 element의 ARIA sematic을 제거한다.
해당 role은 사용을 지양하는게 좋다. 아래 둘은 같은 의미이므로 처음부터 후자로 작성하는게 맞다.
<!-- avoid -->
<h2 role="presentation">Democracy Dies in Darkness</h2>
<!-- instead -->
<div>Democracy Dies in Darkness</div>
그럼에도 불구하고 사용되는 케이스가 있는데, 과거에 레이아웃 잡을 때 <table> 혹은 <ul>, <ol>, <li>을 사용해서 space 간격을 잡아줬다. 이 때 css를 위해 사용된 태그들의 의미를 제거하는 용도로 사용했다.
아래 코드도 a 태그 외에 ul과 li는 의미상 크게 중요하지 않다. 이 경우에 ul에 presentation을 적용하여 li의 ARIA semantic까지 제거한다.
<ul role="presentation">
<li><a href="#">Link1</a></li>
<li><a href="#">Link2</a></li>
<!-- etc. -->
</ul>
aria-disabled='true'일 경우 HTML의 disabled와 동일하게 사용이 불가하다는 걸 나타내지만 기능까지 disabled 상태로 만들진 않으므로 개발자가 직접 정의해야 한다.
<div role="button" aria-disabled="true" tabindex="-1">Edit</div>https://w3c.github.io/using-aria/#third
https://developer.mozilla.org/en-US/docs/Web/Accessibility
https://www.scottohara.me/blog/2018/05/05/hidden-vs-none.html