웹 접근성을 고려한 탭 메뉴는 키보드 사용자, 스크린 리더 사용자 등 다양한 사용자들이 접근할 수 있도록 구성해야 합니다.
탭 메뉴 구성 요소
- 탭 컨테이너: 탭 메뉴를 감싸는 컨테이너.
- 탭 리스트: 각 탭 버튼을 포함하는 리스트.
- 탭 버튼: 클릭 또는 키보드로 선택할 수 있는 버튼.
- 탭 패널: 각 탭 버튼이 활성화될 때 보여줄 콘텐츠.
접근성을 고려한 HTML 구조
다음은 웹 접근성을 고려한 탭 메뉴의 기본 HTML 구조입니다.
<div class="tab-container" role="tablist" aria-label="샘플 탭">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">탭 1</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">탭 2</button>
<button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">탭 3</button>
</div>
<div id="panel-1" role="tabpanel" aria-labelledby="tab-1">
<p>탭 1의 내용</p>
</div>
<div id="panel-2" role="tabpanel" aria-labelledby="tab-2" hidden>
<p>탭 2의 내용</p>
</div>
<div id="panel-3" role="tabpanel" aria-labelledby="tab-3" hidden>
<p>탭 3의 내용</p>
</div>
HTML 구조
- role="tablist": 탭 버튼들을 감싸는 컨테이너로 역할을 지정합니다.
- role="tab": 각각의 탭 버튼에 역할을 지정합니다.
- role="tabpanel": 각각의 탭 패널에 역할을 지정합니다.
- aria-selected: 현재 선택된 탭을 나타냅니다.
- aria-controls: 이 탭이 제어하는 패널을 지정합니다.
- aria-labelledby: 이 패널이 관련된 탭을 지정합니다.
- hidden: 현재 보이지 않는 패널을 숨깁니다.
CSS
/* 탭 컨테이너 스타일 */
.tab-container {
display: flex;
}
/* 각 탭 버튼 스타일 */
[role="tab"] {
padding: 10px;
cursor: pointer;
background-color: #f1f1f1;
border: 1px solid #ccc;
margin-right: -1px;
}
/* 탭 버튼에 포커스 또는 마우스를 올렸을 때 스타일 */
[role="tab"]:focus, [role="tab"]:hover {
background-color: #ddd;
}
/* 선택된 탭 버튼 스타일 */
[role="tab"][aria-selected="true"] {
background-color: #ccc;
border-bottom: none;
}
/* 탭 패널 스타일 */
[role="tabpanel"] {
padding: 10px;
border: 1px solid #ccc;
border-top: none;
}
/* 숨겨진 탭 패널 스타일 */
[role="tabpanel"][hidden] {
display: none;
}
CSS는 참고만 하셔도 됩니다.
JavaScript로 탭 동작 구현
document.addEventListener('DOMContentLoaded', function() {
const tabs = document.querySelectorAll('[role="tab"]');
const tabList = document.querySelector('[role="tablist"]');
let tabFocus = 0;
// 키보드로 탭 이동 기능 구현
tabList.addEventListener('keydown', function(e) {
const keydownLeft = 37;
const keydownRight = 39;
// 왼쪽 화살표 키로 이동
if (e.keyCode === keydownLeft) {
tabs[tabFocus].setAttribute("tabindex", -1);
if (tabFocus === 0) {
tabFocus = tabs.length - 1;
} else {
tabFocus--;
}
}
// 오른쪽 화살표 키로 이동
else if (e.keyCode === keydownRight) {
tabs[tabFocus].setAttribute("tabindex", -1);
if (tabFocus === tabs.length - 1) {
tabFocus = 0;
} else {
tabFocus++;
}
}
tabs[tabFocus].setAttribute("tabindex", 0);
tabs[tabFocus].focus();
});
// 탭 클릭 시 탭 변경
tabs.forEach(tab => {
tab.addEventListener('click', changeTabs);
});
// 탭을 변경하는 함수
function changeTabs(e) {
const target = e.target;
const parent = target.parentNode;
const grandparent = parent.parentNode;
// 현재 선택된 탭 제거
parent
.querySelectorAll('[aria-selected="true"]')
.forEach(t => t.setAttribute('aria-selected', 'false'));
// 선택된 탭 설정
target.setAttribute('aria-selected', 'true');
// 모든 탭 패널 숨기기
grandparent
.querySelectorAll('[role="tabpanel"]')
.forEach(p => p.setAttribute('hidden', 'true'));
// 선택된 탭 패널 보이기
grandparent.parentNode
.querySelector(`#${target.getAttribute('aria-controls')}`)
.removeAttribute('hidden');
}
});
JavaScript 동작
- 키보드 왼쪽/오른쪽 화살표 키로 탭을 이동할 수 있도록 이벤트를 추가합니다.
- 탭 클릭 시, 현재 선택된 탭을 갱신하고, 해당 탭의 패널을 표시합니다.
사실 html과 javascript만 살펴보셔도 됩니다.
728x90