concept/HTML, CSS, DOM

웹 접근성

오연 : Oana 2025. 3. 13. 16:32

웹 접근성이란?

  • 모든 사용자가 웹사이트의 정보와 기능을 동등하게 이용할 수 있도록 보장하는 것
  • ex. 장애를 가진 사용자, 노령 사용자, 기술적 제약을 가진 사용자 모두가 웹 사이트의 정보를 이용하는데 문제가 되지 않도록 제공
  • 법적 요구사항이자 윤리적 책임

웹 접근성을 향상시킬 수 있는 방법

  • HTML Semantic 마크업
  • ARIA
  • 색상 대비와 텍스트 크기 조정
  • 키보드 접근성과 포커스 관리

HTML Semantic 마크업

Semantic Tag

  • 의미가 있는 태그라는 뜻
  • 개발자가 의미론적으로 의도한대로 브라우저가 식별할 수 있는 요소에 대해 표준화된 이름을 사용해 웹 사이트의 일관성 향상에 도움
  1. 검색 최적화에 유리
    1. 검색 엔진에 풍부하고 구조화된 데이터를 제공함으로서 매력적이고 유익한 검색 결과 노출이 가능
  2. 웹 접근성에 유리
    • 키보드만으로 웹 사이트를 이용하는 경우
    • 리더기로 웹사이트를 음성으로 읽어야 하는 경우
  3. 가독성 향상
    • 유지보수에 유리

구조 정리에 필요한 Semantic Tag List

  • <header>
  • <nav>
  • <main>
  • <aside>
    • 페이지 콘텐츠를 제외한 콘텐츠
    • 사이드바
    • 광고
  • <article>
    • 포스트 하나, 기사 하나
    • 이 자체만으로 독립적으로 다른 페이지에 보여줬을 때 아무 문제가 없는 태그
  • <section>
    • 아티클 안 혹은 메인 안 어디서나 연관있는 내용을 하나로 묶어 섹션별로 나누고 싶을 때
  • <figure>
    • 일러스트레이션, 다이어그램, 사진, 코드 목록 등과 같은 자체 포함된 콘텐츠
    • <figcaption> 으로 해당 요소에 대한 캡션 및 설명 정의 가능
    <figure>
      <img src="pic_trulli.jpg" alt="Trulli" style="width:100%">
      <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
    </figure>
    
  • <footer>
    • 문서 또는 섹션의 바닥글
    • 일반적으로 연락처 정보, 사이트 맵, 소셜 미디어 링크

추가 의미를 가진 Semantic Tag List

  • <i> vs <em>
    • 모두 이탤릭체로 표기가 되지만
    • <i> 는 시각적으로만 이탤릭체
    • <em> 은 강조하는 이탤릭체
    • 스크린 리더기로 읽었을 때, <em> 으로 쓴 글이 조금 더 강조되어 읽힘
  • <b> vs <strong>
    • <b> 시각적으로만 볼드체
    • <strong> 정말 중요한 강조 내용
  • <ol> vs <ul> vs <dl>
    • <dl> <dt> <dd>
  • <img> vs css background-image
    • <img> 이미지가 문서의 내용에서 중요한 역할을 하는 경우
    • css background-image 오직 스타일링을 위해서만 쓰이는 경우
  • <button> vs <a>
    • <button> 사용자의 액션이 필요한 경우
    • <a> 사용자의 액션으로 인해 다른 페이지나 경로로 이동하는 경우
  • <details>
    • 사용자가 보거나 숨길 수 있는 추가 세부 정보를 정의하는 태그

프로젝트에 적용

태그 위계 구조

  • <header>
  • <nav>
  • <aside>
  • <footer>
  • <main>
    • <section>
    • <article>
      • <figure>
      • <p>
    • <section> 과 <article> 은 같은 위계여도 괜찮고, 서로를 포함하는 관계여도 괜찮음

구조적 활용

  • <main>
    • next.js app router로 간다면? root layout.tsx 파일에 하나만 작성
  • <header>
    • GNB 컴포넌트에 작성
  • <nav>
    • Navigation 컴포넌트에 작성
    • header와 nav 가 겹치는 경우 header 안에 nav 를 작성
  • <footer>
    • Footer 컴포넌트에 작성

컨텐츠적 활용

  • 배경 이미지
    • 태그는 <div> 태그를 사용하고 css background-image 속성으로 적용
  • 콘텐츠 이미지
    • <figure>과 <img> 활용
    <figure>
      <img src="pic_trulli.jpg" alt="Trulli" style="width:100%">
      <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
    </figure>
    
  • 스타일링을 위해서 태그 묶음이 필요한 경우
    • <div> 활용
  • 본문 텍스트 단락 구성
    • <p>
  • 텍스트의 특정 부분만 스타일링 혹은 그룹화 할 때
    • <span>
  • 텍스트 인풋, 비밀번호, 이메일, 체크박스, 라디오버튼
    • <input>
    • <input type=”text”> 를 사용하는 경우 <label> 태그를 붙여 입력 필드가 어떤 역할을 하는지 명시
  • <h1~4>
    • <h1> 페이지 당 하나의 큰 제목에만 사용
    • <h2> 주요 섹션
    • <h3> 섹션 내 하위 섹션
  • 대부분의 주요 컨텐츠
    • <section> 과 <article> 활용

WAI-ARIA (Web Accessibility Initiative’s Accessible Rich Internet Applications)

  • HTML을 보충해 일반적으로 보조 기술이 알 수 없는 상호작용에 대한 정보를 제공
  • 스크린리더 사용자가 조금 더 쉽게 브라우저를 읽게 돕기 위함
  • 사용 방법
    • 태그에 role 속성을 활용해서 태그의 역할 지정Landmark Role HTML5 관련 요소
      role=”application” 동일한 역할의 요소 없음. 주로 <div> 요소와 같이 그룹 역할을 하는 요소로 대체할 수 있다.
      role=”banner” 동일한 역할의 요소 없음. 비슷한 의미로 <header> 사용 가능, <header role="banner">로 사용 시 1페이지에서 1개만 사용하기를 권장한다.
      role=”navigation” <nav>와 동일하다. 다른 페이지 또는 페이지 내 특정 영역으로 이동하는 링크 콘텐츠 영역으로 주로 메인 메 뉴 및 서브 메뉴 등에 사용할 수 있다.
      role=”main” <main>과 동일하다. 본문의 주요 콘텐츠 영역으로 한 페이지 내에 1개만 사용이 가능하며, <article>, <aside>, <footer> 요소의 하위 요소로 사용할 수 없다.
      role=”aside” <aside>와 동일하다. 주요 컨텐츠와 연관이 적은 의미를 가진 영역이다.
      role=”form” <form>과 동일하다. 폼과 관련된 요소의 모임을 표현하는 영역으로 서버에 전송될 수 있는 콘텐츠를 포함할 수 있다.
      role=”search” 동일한 역할의 요소 없음. 검색 역할을 담당하는 서식 영역을 의미하며 <div>또는 <form> 요소를 사용하는 것을 권장한다.
      role=”contentinfo” 동일한 역할의 요소 없음. <footer>와 비슷하나 <footer role="contentinfo">로 사용 시 한 페이지에 한 개의 <footer> 요소만 사용하는 것을 권장한다.
      role=”button” p, span, div에서도 버튼 컨트롤로 사용된다는 것을 스크린리더에 인식시킬 수 있다. 가능하다면 button role보다 기본 html의 <button>, <input type="button">, <input type="submit">을 사용해야 한다. 기본 html 요소들은 추가 사용자 정의 없이도 키보드 포커스를 지원한다.
      role =”tablist” 탭 메뉴 등의 리스트임을 사용자에게 전달한다.
      role=”tab” 보조기기가 탭으로 인식 (버튼에 tab 역할을 주어, 메뉴를 컨트롤하는 의미를 추가하는 것이 가능하다.)
      role=”tabpanel” 보조기기가 탭 패널로 인식한다.
      role=”presentation”, role=”none” semantic 의미를 요소와 그 자식요소로부터 제거하기 위해서 사용한다. 시각적으로 게시하는 용도의 요소에 적용한다. none은 최근에 나온 속성값으로 presentation과 같은 역할을 한다. 호환성 문제가 있을 수 있으니까 두개 다 기입해 주는것이 좋다.
      role=”group” 라디오 버튼과 같이 여러개의 옵션 중 한 가지를 선택 할 때, name 속성값에 같은 값을 넣어줘서 그룹화하더라도 스크린리더 사용자는 시각적으로 볼수있는 사용자와 달리 묶여있는 그룹이라는 것을 인식하기 어렵다. 이러한 경우 role=”group”를 부여하여 같은 그룹이라는 것을 인식시킨다.
    • 태그에 aria-label 속성을 활용해서 이름표
      • 브라우저가 스크린리더 사용자에게 전달해야 할 내용을 상황에 따라 개발자가 직접 적는다.
      • ex. aria-label="채팅창으로 이동"
  • 주의 사항
    • 시맨틱 태그와 중복해서 사용하지 않는다. 시맨틱 태그 자체가 의미있는 태그이기 때문에 role은 붙일 필요가 없다.
    • role 속성이 없는 경우에 aria-label을 붙이지 않는다.
    • <div aria-label="펼치기"><i class="ico ico-arrow"></i></div> //x <div role="button" aria-label="펼치기"><i class="ico ico-arrow"></i></div> //o
    • aria가 사용된 모든 요소는 키보드로 제어할 수 있어야 한다.
      • role=”button” 이라면 tab으로 focus 한 후, enter 키나 return 키를 눌렀을 때, active 상태가 되어야 한다.

색상 대비와 텍스트 크기 조정

  • 텍스트와 배경 사이 색상 대비가 최소 4.5:1 임을 권장
  • 사용자가 텍스트 크기를 조정할 수 있도록 하는 방법
    • 사용자가 자신의 시각적 요구에 맞게 텍스트 크기를 조정할 수 있도록 CSS를 사용하여 상대적 단위(예: em, rem)로 텍스트 크기를 설정하는 것이 좋다.
  • 웹 접근성을 위한 명도 대비를 자가진단점검할 수 있는 툴
  • Colour Contrast Analyzer - TPGi

키보드 접근성과 포커스 관리

  • 모든 인터랙티브 요소 (링크, 버튼, 폼, 필드 등) 가 키보드만으로 접근 가능하게 구성
  • 사용자가 현재 포커스 맞춰진 곳이 어디인지 명확하게 알 수 있도록 스타일 지정
  • 상호작용하는 태그인 <a> <input> <select> <button> 들은 기본적으로 키보드에 포커스가 잡힘.
    • 포커스를 주고 싶지 않다면? tabindex=-1 로 처리 가능
  • 상호작용하지 않는 태그인 <div> <span> 등의 태그에도 포커스를 잡아주고 싶은 경우에는 tabindex 속성으로 포커스를 줄 수 있음
    • 포커스를 주고 싶다면? tabindex=0 로 처리 가능
    • tabindex의 값으로 준 양수값에 따라 순서를 지정할 수 있음 (tabindex="1", tabindex="2", tabindex="3", …, tabindex="0" 순으로 포커스가 이동)

참고 자료

https://deugdeugi.github.io/2023/08/08/aria.html

https://velog.io/@a_in/WAI-ARIA-role-aria-label