[FRONT] 웹 접근성

접근성 이해하기

Posted by lim.Chuck on December 26, 2024

[FRONT]

  1. [FRONT] 프론트엔드 쿠키 이슈 해결하기
  2. [FRONT] Nuxt Proxy 설정과 활용
  3. [FRONT] 웹 캐시 전략과 구현
  4. [FRONT] Next.js와 Nuxt.js 비교 분석
  5. [FRONT] Monorepo vs Multi-repo vs Monolith 아키텍처
  6. [FRONT] mitmproxy를 활용한 디버깅
  7. [FRONT] Storybook 활용 가이드
  8. [FRONT] Vercel Turbopack 소개
  9. [FRONT] 캐시와 캐싱 전략
  10. [FRONT] SWC 컴파일러 이해하기
  11. [FRONT] 인터섹션 옵저버로 인터섹션 여부 감지하기
  12. [FRONT] BroadcastChannel 사용해서 같은 도메인 브라우저 간 통신하기
  13. [FRONT] DOM이벤트 버블링(Bubbling)과 캡처링(Capturing)
  14. [FRONT] XSS와 CSRF
  15. [FRONT] 웹 성능 최적화
  16. [FRONT] 브라우저 렌더링 과정
  17. [FRONT] 웹 접근성
  18. [FRONT] URL과 Domain 정확히 이해하자 (url구조)
  19. [FRONT] HTTP 헤더 이해하기

웹 접근성 완벽 가이드 ♿️

1. 웹 접근성이란?

모든 사용자(장애인, 고령자 등)가 웹 사이트를 불편함 없이 이용할 수 있도록 하는 것

2. 기본적인 접근성 마크업

1) 이미지 접근성

1
2
3
4
5
6
7
8
9
10
<!-- 나쁜 예시 (❌) -->
<img src="logo.png" />

<!-- 좋은 예시 (✅) -->
<img src="logo.png" alt="회사 로고" <!-- 스크린리더가 읽을 설명 -- />
/>

<!-- 장식용 이미지 -->
<img src="decoration.png" alt="" <!-- 스크린리더가 무시 -- />
role="presentation" />

2) 폼 접근성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 나쁜 예시 (❌) -->
<input type="text" />
<input type="checkbox" />

<!-- 좋은 예시 (✅) -->
<div class="form-group">
  <label for="username">사용자 이름</label>
  <input id="username" type="text" aria-required="true" aria-invalid="false" />
</div>

<div class="checkbox-group">
  <input id="agree" type="checkbox" aria-checked="false" />
  <label for="agree">이용약관 동의</label>
</div>

3. ARIA (Accessible Rich Internet Applications)

1) ARIA 역할(roles)

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 내비게이션 -->
<nav role="navigation">
  <ul role="menubar">
    <li role="menuitem"></li>
    <li role="menuitem">소개</li>
  </ul>
</nav>

<!-- 모달 다이얼로그 -->
<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
  <h2 id="dialog-title">알림</h2>
  <p>저장하시겠습니까?</p>
</div>

2) ARIA 상태와 속성

1
2
3
4
5
6
7
8
<!-- 토글 버튼 -->
<button aria-pressed="false" aria-expanded="false" onclick="toggleMenu()">
  메뉴 열기
</button>

<!-- 에러 메시지 -->
<input type="email" aria-invalid="true" aria-errormessage="email-error" />
<span id="email-error" role="alert"> 올바른 이메일을 입력해주세요 </span>

4. 키보드 접근성

1) 포커스 관리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 키보드 포커스 가능한 요소 -->
<div
  tabindex="0"
  role="button"
  onclick="handleClick()"
  onkeypress="handleKeyPress(event)"
>
  클릭하세요
</div>

<style>
  /* 포커스 스타일 */
  :focus {
    outline: 2px solid #007bff;
    outline-offset: 2px;
  }
</style>

2) 건너뛰기 링크

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 메인 콘텐츠로 바로 이동 -->
<a href="#main-content" class="skip-link"> 메인 콘텐츠로 건너뛰기 </a>

<style>
  .skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: #000;
    color: white;
    padding: 8px;
    z-index: 100;
  }

  .skip-link:focus {
    top: 0;
  }
</style>

5. 색상 및 대비

1
2
3
4
5
6
7
8
9
10
11
12
/* 충분한 색상 대비 */
.text-content {
  /* 배경색 대비 4.5:1 이상 */
  color: #333; /* 어두운 회색 */
  background-color: #fff;
}

/* 색맹을 위한 추가 표시 */
.error-message {
  color: #ff0000; /* 빨간색 */
  border: 2px solid currentColor; /* 색상에 의존하지 않는 표시 */
}

6. 실제 구현 예시

1) 접근성 있는 모달

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class 접근성모달 {
  constructor() {
    this.모달 = document.querySelector(".modal");
    this.열기버튼 = document.querySelector(".open-modal");
    this.닫기버튼 = document.querySelector(".close-modal");
    this.마지막포커스 = null;
  }

  열기() {
    this.마지막포커스 = document.activeElement;
    this.모달.setAttribute("aria-hidden", "false");
    this.모달.focus();
    // 모달 외부 포커스 방지
    this.모달외부포커스방지();
  }

  닫기() {
    this.모달.setAttribute("aria-hidden", "true");
    this.마지막포커스?.focus();
  }

  모달외부포커스방지() {
    const 포커스가능요소 = this.모달.querySelectorAll(
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
    );
  }
}

7. 체크리스트 ✅

  1. HTML 구조

    • 시맨틱 태그 사용
    • 적절한 헤딩 구조
    • 이미지에 alt 속성
  2. 키보드 접근성

    • 모든 기능 키보드로 사용 가능
    • 포커스 순서 논리적
    • 포커스 표시 명확
  3. ARIA 사용

    • 적절한 role 지정
    • 상태 정보 제공
    • 오류 메시지 연결
  4. 시각적 디자인

    • 충분한 색상 대비
    • 색상에만 의존하지 않는 정보 전달
    • 텍스트 크기 조정 가능

이제 웹 접근성에 대해 이해되셨나요? 모두가 사용할 수 있는 웹을 만드는 것이 중요합니다! 😊