WCAG 성공 기준 · Level A
WCAG 2.5.2: 포인터 취소
WCAG 2.5.2는 단일 포인터(마우스, 터치 또는 스타일러스)로 트리거되는 기능이 취소되거나 되돌릴 수 있어야 하며, 이를 통해 실수로 활성화되는 것을 방지할 것을 요구합니다. 이는 의도치 않게 탭하거나 클릭할 수 있는 운동 장애가 있는 사용자를 보호합니다.
- Level A
- Wcag
- Wcag 2 2 a
- 작동 가능한
- 접근성
이 규칙의 의미
WCAG 2.5.2 포인터 취소는 단일 포인터로 작동되는 모든 기능에 적용됩니다. 여기에는 마우스 클릭, 터치스크린 탭, 스타일러스 누르기, 그리고 화면의 한 지점을 활성화하는 기타 모든 입력 장치가 포함됩니다. 이 기준은 의도하지 않은 누르기나 탭으로 인해 발생한 실수 활성화를, 실제로 효력이 발생하기 전에 취소할 수 있도록 보장하기 위해 존재합니다.
단일 포인터 상호작용이 이 기준을 준수하려면, WCAG 명세에서 정의한 다음 네 가지 조건 중 최소 하나를 충족해야 합니다.
- 다운 이벤트 없음: 기능이 다운 이벤트(예:
mousedown,touchstart,pointerdown)에서 트리거되지 않습니다. 활성화는 업 이벤트(mouseup,touchend,pointerup)에서만 발생합니다. - 중단 또는 실행 취소: 동작이 완료되기 전에 중단(abort)할 수 있는 메커니즘이 있거나, 동작이 완료된 후 실행을 취소(undo)할 수 있는 메커니즘이 제공됩니다.
- 업 리버설: 업 이벤트가 다운 이벤트에서 트리거된 결과를 되돌립니다. 예를 들어, 포인터가 대상 영역 밖에서 놓이면 원래 위치로 되돌아가는 드래그 동작이 이에 해당합니다.
- 본질적 예외: 다운 이벤트에서 트리거되는 것이 기능에 본질적으로 필수적인 경우입니다. 예를 들어, 화면상의 피아노 키보드에서 소리는 키를 누르는 순간 바로 시작되어야 합니다. 다만 이 예외는 매우 좁게 적용되며, 다운 이벤트의 타이밍이 기능적으로 근본적으로 필요할 때에만 해당됩니다.
실질적인 HTML 및 JavaScript 관점에서 보면, 이는 개발자가 이벤트 리스너를 어디에 연결하는지 매우 주의해야 한다는 뜻입니다. mousedown, touchstart, pointerdown을 사용해 양식 제출, 레코드 삭제, 페이지 이탈과 같은 동작을 즉시 그리고 되돌릴 수 없게 실행하면서, 그 동작을 취소하거나 실행을 되돌릴 수 있는 방법을 제공하지 않는 것은 이 기준의 명백한 실패입니다. 기본 <button> 및 <a> 요소에 대한 표준 브라우저 동작은 이미 기본적으로 업 이벤트에서 활성화를 발생시키므로, 올바르게 구현된 네이티브 컨트롤은 일반적으로 추가 노력 없이 이 기준을 통과합니다.
드래그 앤 드롭 인터페이스, 제스처 기반 슬라이더, 캐러셀 컨트롤, 이미지 맵과 같은 JavaScript로 만든 사용자 정의 인터랙티브 컴포넌트가 가장 흔한 실패 원인입니다. 취소나 되돌리기 기능 없이 되돌릴 수 없는 로직을 다운 이벤트 리스너에 바인딩하는 모든 컴포넌트는 이 기준을 충족하지 못합니다.
중요한 이유
포인터 취소는 주로 운동 장애가 있는 사용자를 보호하기 위해 설계된 기준이지만, 떨림, 경직, 미세 운동 조절 능력의 제한, 주의력과 정확도에 영향을 미치는 인지 장애가 있는 사용자 등 매우 폭넓은 사용자에게 이점을 제공합니다.
예를 들어, 파킨슨병이 있는 사용자가 터치스크린에서 전자상거래 결제 페이지를 탐색하고 있다고 가정해 봅시다. 손 떨림 때문에 사용자의 손가락이 의도하지 않았던 "구매 확정" 버튼 위에 떨어질 수 있습니다. 만약 구매가 손가락이 화면에 닿는 순간, 즉 touchstart 이벤트에서 트리거된다면, 사용자는 취소할 기회 없이 즉시 거래가 처리됩니다. 반대로 활성화가 touchend 이벤트에 바인딩되어 있었다면, 사용자는 손가락을 떼기 전에 버튼에서 손가락을 미끄러뜨려 벗어남으로써 동작을 취소할 수 있었을 것입니다. 업 이벤트와 다운 이벤트 바인딩의 이 단순한 차이가 수백만 사용자에게 좌절스러운 경험과 접근 가능한 경험을 가르는 차이가 될 수 있습니다.
세계보건기구(WHO)에 따르면 전 세계 약 13억 명이 어떤 형태로든 장애를 가지고 있으며, 그중 상당 부분이 운동 장애에 해당합니다. 장애 여부와 관계없이, 작은 터치스크린 기기에서의 실수 활성화는 모든 사용자에게 흔한 불편 요소이므로, 이 기준은 일반적인 사용성 측면에서도 중요합니다.
인지 장애도 또 하나의 중요한 고려 사항입니다. 정보를 더 천천히 처리하는 사용자는 버튼을 누른 뒤에야 잘못된 옵션을 선택했다는 것을 깨달을 수 있습니다. 만약 동작이 되돌릴 수 없고, 다운 이벤트에서 트리거된다면, 이들에게는 아무런 구제 수단이 없습니다. 실행 취소 메커니즘이나 업 이벤트 활성화는 이러한 사용자에게 자신의 의도를 확인할 수 있는 시간을 제공합니다.
비즈니스 관점에서 보면, 실수로 인한 양식 제출, 구매, 삭제를 줄이면 사용자 만족도가 향상되고, 지원 요청이 감소하며, 거래 포기율이 낮아집니다. 접근 가능한 포인터 상호작용 모델은 터키 및 국제적인 접근성 규제 하에서의 법적 책임 위험도 줄여 줍니다.
관련 Axe-core 규칙
WCAG 2.5.2는 수동 테스트가 필요하며 자동 접근성 스캐너만으로는 신뢰할 수 있게 평가할 수 없습니다. 이 기준에 직접적으로 매핑되는 특정 axe-core 자동 규칙은 없습니다. 자동 감지가 불충분한 이유는 다음과 같습니다.
- 포인터 취소에서 자동화가 실패하는 이유: axe-core와 같은 자동 도구는 HTML을 파싱하고 특정 ARIA나 구조적 문제를 감지할 수 있지만, JavaScript 이벤트 핸들러의 의미적 의도와 되돌릴 수 있는지 여부를 신뢰할 수 있게 판단할 수는 없습니다. 도구는 어떤 요소에
mousedown이벤트 리스너가 존재한다는 사실은 감지할 수 있지만, 그 리스너가 되돌릴 수 없는 동작을 트리거하는지, 실행 취소 메커니즘이 애플리케이션의 다른 곳에 존재하는지, 또는 다운 이벤트의 타이밍이 기능에 진정으로 필수적인지 여부는 판단할 수 없습니다. 이 기준을 평가하는 데 필요한 런타임 동작, 애플리케이션 상태, 사용자 맥락의 조합은 정적 또는 DOM 기반 자동 분석의 범위를 넘어섭니다. - 수동 테스터가 확인해야 할 사항: 테스터는 포인터 장치를 사용해 각 인터랙티브 컨트롤과 상호작용하고, 동작이 정확히 언제 발생하는지(누를 때인지, 뗄 때인지)를 관찰해야 합니다. 또한 포인터를 요소 밖으로 미끄러뜨린 뒤에 버튼을 놓으면 동작이 취소되는지, 활성화 후에 접근 가능한 실행 취소 또는 중단 메커니즘이 있는지도 확인해야 합니다.
- 자동화에서 얻을 수 있는 부분적 신호: 일부 린팅 도구나 사용자 정의 axe 규칙은
onmousedown,ontouchstart,onpointerdown속성이 있는 요소를 검토 필요 대상으로 표시할 수 있지만, 이러한 플래그는 준수 여부를 판단하기 위해 인간의 판단이 필요합니다. 이러한 자동 플래그는 최종 실패 보고가 아니라 수동 조사를 위한 신호로 취급해야 합니다.
테스트 방법
- 자동 스캔(초기 조사): 페이지에 대해 axe DevTools 또는 Lighthouse를 실행하여 인터랙티브 요소와 수동 검토 대상으로 표시된 사용자 정의 이벤트 바인딩을 식별합니다. Chrome DevTools에서는 Elements 패널을 사용해 버튼, 링크, 사용자 정의 컨트롤에 연결된 이벤트 리스너를 검사하고, 되돌릴 수 없는 동작을 트리거하는 요소에
mousedown,touchstart,pointerdown핸들러가 있는지 확인합니다. - 마우스 포인터 테스트 — 클릭 후 드래그 취소: 페이지의 각 인터랙티브 버튼, 링크, 사용자 정의 컨트롤에 대해, 요소 위에서 마우스 버튼을 누른 상태로 유지한 뒤, 버튼을 놓기 전에 포인터를 요소 경계 밖으로 드래그합니다. 버튼을 누르고 있는 동안(놓기 전)에 동작이 발생하면 실패입니다. 드래그해서 벗어났을 때, 버튼을 놓아도 동작이 발생하지 않으면 업 리버설 또는 다운 이벤트 없음 조건을 충족한 것으로 통과입니다.
- 터치 기기 테스트: 터치스크린 기기 또는 브라우저 에뮬레이터(Chrome DevTools 디바이스 모드)에서 각 인터랙티브 요소를 탭하고 누른 상태로 유지한 뒤, 손가락을 떼기 전에 요소 밖으로 미끄러뜨립니다. 손가락을 떼기 전에, 터치 순간에 동작이 즉시 발생하면(즉시 터치에서 트리거되면) 다운 이벤트 타이밍이 본질적으로 필수적인 경우가 아니라면 실패입니다. 손가락을 요소 밖에서 떼었을 때 동작이 트리거되지 않는지 확인합니다.
- 키보드 조작 확인: 이 기준은 구체적으로 포인터 상호작용에 관한 것이지만, 모든 인터랙티브 요소가 키보드로도 조작 가능한지 확인해야 합니다.
Tab키로 각 요소에 포커스를 이동하고,Enter또는Space로 활성화하여 포인터 없이도 요소에 도달하고 기능을 사용할 수 있는지 확인합니다. 이는 더 넓은 접근성 측면을 지원합니다. - 실행 취소/중단 메커니즘 검증: 본질적 예외가 적용될 수 있는, 다운 이벤트에 바인딩된 동작에 대해, 명확한 실행 취소 또는 중단 메커니즘이 존재하며 보조 기술 사용자 등 모든 사용자가 접근할 수 있는지 확인합니다. 예를 들어, 드래그 앤 드롭 동작 후에 키보드와 스크린 리더로 도달 가능한 "실행 취소" 버튼이 있는지 확인합니다.
- 스크린 리더와 포인터 조합 테스트(NVDA + Firefox, JAWS + Chrome, VoiceOver + Safari): 포인터와 스크린 리더의 가상 커서를 모두 사용해 인터랙티브 요소를 활성화합니다. 포인터로 트리거되는 동작이 스크린 리더로 트리거되는 동작과 일관되는지, 예기치 않게 즉시 되돌릴 수 없는 동작이 발생하지 않는지 확인합니다.
- 코드 리뷰: 코드베이스에서 이벤트 리스너 바인딩을 검색합니다.
addEventListener('mousedown',addEventListener('touchstart',addEventListener('pointerdown'및 인라인onmousedown,ontouchstart속성을 찾습니다. 각 발생 지점에 대해, 핸들러가 되돌릴 수 없는 동작을 트리거하는지, 그리고 네 가지 WCAG 조건 중 하나라도 충족하는지 평가합니다.
수정 방법
mousedown에서 되돌릴 수 없는 동작 — 잘못된 예
<!-- FAIL: Delete fires immediately on mousedown, no cancellation possible -->
<button onmousedown='deleteRecord(recordId)'>Delete Record</button>
<script>
function deleteRecord(id) {
// Record is deleted immediately on button press, before the user releases
fetch('/api/records/' + id, { method: 'DELETE' });
}
</script>
mousedown에서 되돌릴 수 없는 동작 — 올바른 예
<!-- PASS: Delete fires on click (up-event), native button behavior -->
<button onclick='deleteRecord(recordId)'>Delete Record</button>
<!-- Even better: provide confirmation dialog as an additional abort mechanism -->
<button onclick='confirmDelete(recordId)'>Delete Record</button>
<script>
function confirmDelete(id) {
// User can cancel via the dialog — satisfies the Abort or Undo condition
if (confirm('Are you sure you want to delete this record? This cannot be undone.')) {
fetch('/api/records/' + id, { method: 'DELETE' });
}
}
</script>
touchstart에서 터치 제스처가 실행됨 — 잘못된 예
<!-- FAIL: Action fires immediately on touchstart, no opportunity to abort -->
<div id='buy-btn'>Buy Now</div>
<script>
document.getElementById('buy-btn').addEventListener('touchstart', function() {
// Purchase initiated immediately when finger touches the element
initiatePurchase();
});
</script>
touchstart에서 터치 제스처가 실행됨 — 올바른 예
<!-- PASS: Use a native button and bind to click, which fires on touchend -->
<button id='buy-btn'>Buy Now</button>
<script>
// The 'click' event on a native button fires on the up-event (touchend/mouseup)
// giving users the ability to cancel by sliding their finger away before releasing
document.getElementById('buy-btn').addEventListener('click', function() {
initiatePurchase();
});
</script>
업 리버설이 없는 사용자 정의 드래그 앤 드롭 — 잘못된 예
<!-- FAIL: Item is moved to new position on pointerdown, not on pointerup -->
<div class='draggable' onpointerdown='moveItemToTarget(this)'>
Drag me
</div>
업 리버설이 있는 사용자 정의 드래그 앤 드롭 — 올바른 예
<!-- PASS: Item moves to target only when pointer is released over the drop zone -->
<!-- If user drags away before releasing, item returns to original position -->
<div
class='draggable'
draggable='true'
ondragstart='handleDragStart(event)'
>
Drag me
</div>
<div
class='drop-zone'
ondragover='event.preventDefault()'
ondrop='handleDrop(event)'
aria-label='Drop zone'
>
Drop here
</div>
<script>
function handleDragStart(event) {
// Only records intent; does not move the item yet
event.dataTransfer.setData('text/plain', event.target.id);
}
function handleDrop(event) {
event.preventDefault();
// Item is moved only on drop (up-event equivalent)
// If user releases outside drop zone, item returns to origin — up-reversal satisfied
const id = event.dataTransfer.getData('text/plain');
event.currentTarget.appendChild(document.getElementById(id));
}
</script>
자주 발생하는 실수
- 양식 제출, 레코드 삭제, 내비게이션과 같은 되돌릴 수 없는 동작을, 기본적으로 업 이벤트에서 발생하여 드래그로 벗어나면 취소가 가능한
click대신mousedown또는pointerdown이벤트에 바인딩하는 것. - 전자상거래나 뱅킹 인터페이스에서
touchstart를 사용해 구매, 확인, 데이터 변경을 트리거하는 것. 순간적인 손가락 접촉을 확정된 사용자 의도로 취급해서는 안 되는 상황입니다. - 버튼이 네이티브
<button>요소를 사용하므로, 그에 연결된 모든 JavaScript가 자동으로 준수한다고 가정하는 것. 되돌릴 수 없는 동작을 트리거하는addEventListener를 통해 추가된mousedown리스너는 여전히 이 기준을 위반합니다. - 포인터의 다운 이벤트에서 모달 대화상자, 오버레이, 전체 페이지 내비게이션 변경을 호출하여, 컨트롤을 활성화할 의도가 없었던 사용자를 혼란스럽게 만들고, 되돌릴 방법을 제공하지 않는 것.
pointerup또는 별도의 확인 동작을 기다리지 않고,pointerdown에서 서버에 값을 커밋하는 사용자 정의 슬라이더나 범위 컨트롤을 구현하는 것.- 다운 이벤트 동작에 대한 유일한 실행 취소 메커니즘으로 브라우저의 기본
confirm()대화상자에 의존하면서, 파괴적 동작이 완료되기 전에 보조 기술이 이 대화상자에 안정적으로 접근하고 조작할 수 있는지 테스트하지 않는 것. - 다운 이벤트 동작이 보류 중이라는 시각적 또는 프로그래밍적 피드백을 제공하지 않아, 사용자가 버튼을 놓기 전에 포인터를 옮겨서 동작을 중단할 수 있다는 사실을 이해할 수 없게 만드는 것.
- 본질적 예외를 지나치게 넓게 해석하는 것. 예를 들어, 실제로는 시간 제약이 없는데도 단지 속도를 이유로 "빠른 구매" 버튼이
mousedown에서 실행되어야 한다고 주장하는 경우처럼, 제품 편의성을 기능적 필수 요건으로 포장하는 것. - 마우스와 터치 입력 장치 모두에서 테스트하지 않는 것. 인터페이스가 마우스 상호작용에서는 업 이벤트를 올바르게 사용하면서, 별도의 모바일 전용 코드 경로에서는 여전히 되돌릴 수 없는 동작을
touchstart에 바인딩하고 있을 수 있습니다. - 다운 이벤트 활성화 이후에 포인터만 사용하는 사용자에게는 취소 메커니즘이 없도록, 실행 취소 기능을 키보드 단축키(예: Ctrl+Z)로만 제공하고 화면상의 동등한 컨트롤을 제공하지 않는 것.
터키 접근성 규정과의 관계
2025년 6월 21일 관보 제32933호에 게재된 터키 대통령령 2025/10은 WCAG 2.2 기준에 부합하는 의무적인 웹 접근성 요구 사항을 수립합니다. 이 대통령령에 따라, WCAG 2.5.2 포인터 취소를 포함한 레벨 A 기준 준수는 터키에서 디지털 서비스를 운영하는 광범위한 공공 및 민간 기관에 법적으로 요구됩니다.
이 대통령령은 매우 폭넓은 조직을 포괄합니다. 공공 기관과 정부 기관은 대통령령 공포일로부터 1년 이내에 레벨 A 기준을 완전히 준수해야 합니다. 규제 대상 민간 부문 — 전자상거래 플랫폼, 은행 및 금융 기관, 병원 및 의료 서비스 제공자, 가입자 200,000명 이상인 통신사, 여행사, 민간 운송 회사, 그리고 교육부(MoNE)의 인가를 받은 사립 학교 — 는 2년의 준수 기간이 부여됩니다.
이러한 대상 기관의 경우, 포인터 취소를 올바르게 구현하지 않으면 실제 규제 리스크가 발생합니다. 예를 들어, 터키의 한 전자상거래 플랫폼의 모바일 결제 페이지가 touchstart에서 결제 확인을 트리거한다면, 이러한 구현은 WCAG 2.5.2의 직접적인 위반이며, 나아가 대통령령 위반에 해당합니다. 떨림, 운동 장애, 단순한 오탭으로 인해 해당 플랫폼에서 실수로 구매를 시작한 사용자는, 플랫폼이 접근성 의무를 이행하지 않았다고 주장할 법적 근거를 갖게 됩니다.
규제 준수를 넘어, 터키의 조직은 포인터 취소가 단순한 기술적 체크리스트 항목이 아니라, 사용자가 디지털 서비스와 안전하고 의도적으로 상호작용할 수 있도록 보호하는 근본적인 설계 원칙이라는 점을 인식해야 합니다. 쇼핑 카트, 예약 시스템, 문서 관리 도구에 이르기까지 인터랙티브 컴포넌트 전반에 업 이벤트 활성화와 실행 취소 메커니즘을 구현하는 것은, 장애가 있는 사용자뿐 아니라 모든 사용자에게 이익이 되는 포괄적 디자인에 대한 의지를 보여 줍니다.
대통령령의 적용을 받는 조직은, 특히 모바일 최적화 페이지와 사용자 정의 인터랙티브 컴포넌트에서 JavaScript 이벤트 처리 패턴에 대한 체계적인 감사를 수행하여, 취소나 되돌리기 메커니즘 없이 다운 이벤트에서 활성화되는 부분을 식별하고 수정해야 합니다. 이러한 수정 노력을 문서화하는 것은 대통령령의 집행 조항에 따라 요구될 수 있는 준수 보고 의무를 지원하는 데에도 도움이 됩니다.
출처 및 참고자료
- W3C Understanding 2.5.2 Pointer Cancellation
- W3C Techniques for 2.5.2 Pointer Cancellation
- W3C Technique G212: Using native controls to ensure functionality is triggered on the up-event
- MDN: Pointer events
- MDN: Element: click event
- WebAIM: Motor Disabilities and Pointer Accessibility
- Deque University: Pointer Cancellation Overview
