서울시청은 키보드 접근성을 중점으로 한 접근성 준수를 목표로 작업했습니다.
웹접근성 준수
1-1. 키보드 이벤트
1-2. 초점의 이동순서 고려하기
1-3. WAI-ARIA를 통한 웹접근성 보조
슬라이드
2-1. 활성화된 슬라이드와 탭메뉴 연동
2-2. 슬라이드 재생 / 멈춤 컨트롤
키보드 접근성 체크사항
✅ 키보드만으로 모든 기능을 사용할 수 있는가?
✅ 초점의 이동 순서가 논리적인가?
✅ 특정영역이 키보드 조작을 통해 초점을 받았을 때 시각적으로 알 수 있도록 되어 있는가?
메뉴 리스트가 끝나거나 뒤로 가기를 했을 때 메뉴가 닫히는 키보드 이벤트입니다.
keydown() 메서드를 통해 메뉴 리스트의 첫번째 리스트 아이템이나 마지막 리스트 아이템에서 키보드를 눌렀을 때 이벤트를 발생시킵니다.
누른 keyCode가 9번, 즉 tab 키와 shift 키를 함께 눌러 뒤로 이동했을 때 메뉴가 닫힙니다.
같은 방식으로 마지막 리스트 아이템에서 tab 키가 눌렸을 경우 다음 해당 메뉴 리스트가 닫히며 다음 메뉴로 넘어갑니다.
/* 첫번째 리스트 아이템에서 뒤로 이동 */
$('.sc-related .sub-list .sub-item:first-child').keydown(function(e){
if ( e.keyCode === 9 && e.shiftKey ) {
//메뉴 리스트 닫기
$('.sc-related .sub').stop().slideUp(200);
//active 스타일용 클래스 on 제거
$('.sc-related .btn-related').removeClass('on');
}
});
/* 마지막 리스트 아이템에서 다음으로 이동 */
$('.sc-related .sub-list .sub-item:last-child').keydown(function(e){
if ( e.keyCode === 9 && !e.shiftKey ) {
$('.sc-related .sub').stop().slideUp(200);
$('.sc-related .btn-related').removeClass('on');
}
});
$('.sc-related .sub-list .sub-item:first-child').keydown
: 메뉴 리스트중 첫번째 리스트에서 키를 누르는 이벤트가 발생했을 때의 이벤트를 구현합니다.if ( e.keyCode === 9 && e.shiftKey )
: 키보드는 각각의 코드 값을 가지고 있는데, 탭 키를 의미하는 코드 값이 9번입니다.
해당 조건문은 탭키와 시프트키가 모두 눌렸을 경우로, 사용자가 뒤로 이동을 했을 때의 조건입니다.
keyboard event (keydown, keyup)
keydown
: 선택한 요소에서 키보드를 누를 때 이벤트 발생keyup
: 키보드를 놓을 때 이벤트 발생//방법1 window.onkeydown = (e) => console.log(e); //방법2 window.addEventListener("keydown", (e) => console.log(e));
e.shiftKey
: 시프트키가 눌렸는지 안눌렸는지를 true나 false로 반환
콘텐츠가 끝나고나서 더 볼 수 있는 버튼으로 초점이 이동하도록 초점의 이동순서를 논리적으로 구성했습니다.
1 ~ 4번째 슬라이드는 주요뉴스, 5 ~ 8번째 슬라이드는 시민참여에 해당하므로
주요뉴스를 누르면 1번째 슬라이드로 이동하고 시민참여를 누르면 5번째 슬라이드로 이동합니다.
HTML에서 data-index
속성의 값으로 이동해야할 슬라이드의 인덱스 숫자를 지정해줍니다.
idx 변수에 클릭한 버튼의 data-index
속성 값을 저장 후, slideToLoop()
로 해당 슬라이드로 이동하도록 했습니다.
<button type="button" class="btn-menu news on" data-index="0" aria-selected="true">
<i class="icon news"></i>
<span>주요뉴스</span>
</button>
<button type="button" class="btn-menu citizen" data-index="4" aria-selected="false">
<i class="icon citizen"></i>
<span>시민참여</span>
</button>
$('.sc-tabnews .btn-menu').click(function(){
const idx = $(this).data('index');
tabSlide.slideToLoop(idx);
});
💣 Error fix
처음에
slideTo()
를 사용해서 작성했는데 해당 슬라이드가 무한 반복될 수 있도록loop: true
를 지정했기 때문에 index가 꼬이는 현상이 발생하여slideToLoop()
로 수정
슬라이드가 바뀌면서 선택된 탭메뉴의 스타일도 변경되어야하므로 탭메뉴의 스타일은 [aria-selected="true"] 인 요소를 선택하여 꾸며주고
스크립트에서 현재 표시되는 슬라이드 index를 받아와 aria-selected 속성 값을 변경해줬습니다.
.sc-tabnews .group-nav .btn-menu[aria-selected="true"] {
position: relative;
background-color: #0158a8;
color: #fff;
}
/*
* - 탭뉴스 스와이퍼 버튼 스타일
* : n번째 슬라이드 나오면 해당 tabSlide 메뉴 스타일 적용
*/
tabSlide.on('slideChange', function(){
if ( this.realIndex > 3 ) {
$('.sc-tabnews .citizen').attr('aria-selected','true');
$('.sc-tabnews .news').attr('aria-selected','false');
} else {
$('.sc-tabnews .news').attr('aria-selected','true');
$('.sc-tabnews .citizen').attr('aria-selected','false');
}
});
슬라이드를 재생 시키거나 멈출 수 있는 컨트롤 버튼입니다.
버튼에 가상클래스 on의 유무로 재생 / 멈춤 버튼을 구분하고 재생, 멈춤 동작은 autoplay.start()
, autoplay.stop()
를 사용했습니다.
재생버튼에서 멈춤버튼으로 바뀌거나 반대의 상황일 때 스크린리더 사용자가 해당 버튼이 어떤 역할인지 알 수 있어야하므로 대체 텍스트도 text()
메서드를 통해 바꿔주었습니다.
<div class="btn-wrap">
<button type="button" class="btn-arrow prev"><span class="blind">이전슬라이드</span></button>
<button type="button" class="btn-autoplay"><span class="blind">자동재생 멈춤</span></button>
<button type="button" class="btn-arrow next"><span class="blind">다음슬라이드</span></button>
</div>
/**
* - 배너 스와이퍼 자동재생 버튼
* @on 붙은 상태가 자동재생 멈춤 상태
*/
$('.sc-banner .btn-autoplay').click(function(){
if ( $(this).hasClass('on') ) {
bannerSlide.autoplay.start();
$(this).children('.blind').text('자동재생 정지');
} else {
bannerSlide.autoplay.stop();
$(this).children('.blind').text('자동재생 적용');
}
});
WAI-ARIA
를 사용한 접근성 확보원래 서울 시청 사이트에서 탭메뉴 슬라이드는 어떤 메뉴가 선택 되었는지 스크린리더 사용자가 구분하기 어렵기때문에
role
속성을 이용해 tablist와 tab이라는 역할을 명시,
aria-selected
속성을 넣어 어떤 tab이 선택된 상태인지 구분했습니다.
WAI-ARIA
란?스크린리더가 브라우저를 읽을 때 각 요소가 어떤 역할을 하는지 알 수 있도록 하기 위해 만들어진 기술
aria-label
: 이미지를 사용해 시각적 표현을 할 경우 대체 텍스트역할을 한다. 텍스트보다 우선순위가 높기때문에 요소 안의 텍스트는 읽지 않는다.aria-selected
: 어떤 탭이 선택되었는지 true/false 로 구분