li태그는 ul태그 내부에 작성한다.
요소의 기능에 따라, 가능하다면 시맨틱 요소를 사용한다.
header, nav, main, aside, footer, section, article, hgroup, p 등
요소의 이름만 보고 기능을 판단할 수 없는 div, span 태그부터 리팩토링 시작하기
hgroup을 글씨 크기 조절용으로 사용하지 않는다.
스타일 속성을 적용할 때 인라인 스타일링 또는 b, i 등의 요소를 사용하지 않고 css를 이용한다.
b 요소는 텍스트 자체를 강조하고, strong 요소는 콘텐츠 자체의 중요성을 강조한다i 요소는 텍스트를 이탤릭체로 설정하고, em 요소는 emphasized text를 표현할 때 사용한다.br 요소는 요소 사이에 간격을 주고 싶을 때 사용하지 않고, 줄 바꿈을 할 때에만 사용한다.
인라인 요소 안에 블록 요소를 넣지 않는다.
a, spandiv텍스트가 아닌 콘텐츠는 그 의미나 용도를 나타내는 대체 텍스트를 제공한다.
너무 자세하거나 광범위 하지 않은, 적절한 텍스트로 제공한다.
alt 속성값으로 빈 문자열을 입력하면 해당 요소 자체를 인식하지 않는다.
alt='' 속성을 적용한다.인접 요소의 내용에서 이미지의 정보를 제공하는 경우 alt 속성을 작성하지 않는다.
//alt 속성이 필요한 경우
<img src={catImage} alt="윙크하는 고양이"/>
//alt 속성이 필요하지 않은 경우
<img src={redPandaImage} />
<p>래서 펜더가 대나무를 앞발로 잡고 혀를 내밀고 있다.</p>
스크린 리더는 마크업 순서대로 내용을 읽는다.
콘텐츠는 논리적인 순서로 제공해야 한다.
제목 ➞ 내용
탭이 있다면 탭 제목 다음에 탭 내용이 오도록 마크업을 구성해야 한다.
(별도의 스타일링 필요)
//잘못된 예
<div>
<div>
<div>title1</div>
<div>title2</div>
</div>
<div>
<div>content1</div>
<div>content2</div>
</div>
</div>
//콘텐츠 선형 구조
<div>
<div>
<div>title1</div>
<div>content1</div>
</div>
<div>
<div>title2</div>
<div>content2</div>
</div>
</div>
시맨틱 요소만으로 요소의 의미 전달이 충분한 상황에서는 WAI-ARIA를 사용하지 않는다.
시맨틱한 HTML을 작성하는 것이 최우선이며, WAI-ARIA는 보조적인 역할로만 사용해야 한다.
역할 속성으로 해당 요소가 어떤 역할을 하는지 명시해준다.role <div className="button" role="button">요소는 div</div>
<button>요소는 button</button>
상태 속성을 사용하여 요소의 상태를 지정해준다.
요소에 대한 정보를 전혀 알 수 없는 경우 속성값을 주어 요소를 설명한다.
aria-label<button className="iconButton" aria-label="홈"><img src={home} /></button>
스크린 리더를 듣는 것만으로 표의 구조를 파악할 수 있도록 마크업을 작성해야 한다.
| 요소 | 역할 |
|---|---|
| table | 표를 생성 |
| caption | 표의 제목 |
| thead | (optional)열의 제목을 묶음 |
| tbody | (optional)표의 내용을 묶음 |
| th | 열의 제목 |
| tr | table row: 행을 생성 |
| td | table data: 열을 생성 |
table 요소 안에 caption 요소를 사용해서 표의 제목을 제공한다.
표의 셀은 th 제목 셀과 td 데이터 셀을 구분하여 작성한다.
표의 구조가 복잡할 경우, 최대한 간소화하거나 scope, id, headers 속성을 사용하여 작성한다.
//scope 속성 사용
<table>
<caption>바밤바 시리즈 정리</caption>
<thead>
<th scope="col">이름</th>
<th scope="col">당류</th>
<th scope="col">내용량</th>
<th scope="col">칼로리</th>
</thead>
<tbody>
<tr>
<td scope="row">바밤바</td>
<td>13g</td>
<td>70ml</td>
<td>100kcal</td>
</tr>
<tr>
<td scope="row">배뱀배</td>
<td>14g</td>
<td>70ml</td>
<td>75kcal</td>
</tr>
<tr>
<td scope="row">바밤바샌드</td>
<td>24g</td>
<td>180ml</td>
<td>240kcal</td>
</tr>
</tbody>
</table>
//id, headers 속성 사용
<table>
<caption>바밤바 시리즈 정리</caption>
<thead>
<th id="A">이름</th>
<th id="B">당류</th>
<th id="C">내용량</th>
<th id="D">칼로리</th>
</thead>
<tbody>
<tr>
<td id="a">바밤바</td>
<td headers="B a">13g</td>
<td headers="C a">70ml</td>
<td headers="D a">100kcal</td>
</tr>
<tr>
<td id="b">배뱀배</td>
<td headers="B b">14g</td>
<td headers="C b">70ml</td>
<td headers="D b">75kcal</td>
</tr>
<tr>
<td id="c">바밤바샌드</td>
<td headers="B c">24g</td>
<td headers="C c">180ml</td>
<td headers="D c">240kcal</td>
</tr>
</tbody>
</table>
사용자 입력에 대응하는 레이블을 제공한다.
입력해야 하는 내용에 대한 정보를 제공한다.
<input> 요소의 placeholder 속성은 레이블을 대체할 수 없다.
내용을 입력하는 순간 사라지기 때문에 일부 스크린 리더는 읽지 못하게 된다.
<input> 요소에 id 속성을 설정하고 <label> 요소의 for 속성으로 연결한다.
title 속성을 사용한다.
꼭 필요한 경우 WAI-ARIA의 aria-label 속성을 사용한다.
<div className="inputContainer">
<label for="name" title="customer's name">name: </label>
<input type="text" id="name" name="person"/>
</div>