티스토리 뷰

반응형

aria-hidden 속성의 문제는 주로 접근성(Accessibility) 관점에서 발생합니다. 이 문제는 aria-hidden이 설정된 요소나 그 상위 요소에 포커스된 엘리먼트가 포함된 경우 발생하며, 이는 스크린 리더와 같은 보조 기술 사용자들에게 문제를 일으킬 수 있습니다.

 

문제의 원인

  1. aria-hidden 설정된 요소에 포커스가 이동: aria-hidden="true"가 설정된 요소나 상위 요소에 자식이 포커스를 가지면, 해당 포커스는 보조 기술에서 무시됩니다.
  2. aria-hidden과 모달 창의 충돌: 부트스트랩 모달 창은 보통 모달이 열린 상태에서 배경의 접근성을 차단하기 위해 aria-hidden을 사용합니다. 하지만 잘못된 설정으로 모달 내부의 버튼이나 포커스 가능한 요소에 문제가 생길 수 있습니다.

근본적인 해결 방법

  1. inert 속성 사용 고려:
    • inert 속성은 화면에서 포커스를 차단하고, 해당 요소를 보조 기술에서 숨깁니다.
    • 예시:
      <div inert> <!-- 이 요소는 접근성과 포커스를 차단 -->
          <p>이 내용은 포커스에서 제외됩니다.</p>
      </div>
      
  2. aria-hidden 사용 최소화:
    • aria-hidden은 보조 기술에서만 요소를 숨기며, 키보드 포커스를 차단하지 못합니다.
    • 이를 inert와 조합하여 사용하는 것이 더 안전합니다.
  3. 모달 포커스 관리 개선:
    • 모달을 열고 닫을 때, 포커스를 모달 내부로 강제하고 닫힌 후 원래 포커스로 복귀하도록 관리해야 합니다.
    • 부트스트랩 모달의 포커스 관리 방법:
      $('#order_form_write').on('shown.bs.modal', function () {
          $('#close_modal1').focus(); // 모달 내 버튼으로 포커스 이동
      });
      
  4. 적절한 접근성 도구 사용:
    • aria-modal="true"는 모달 활성 상태를 선언합니다. 모달이 열려 있을 때, 배경의 다른 요소는 자동으로 접근성에서 제외되어야 합니다.
    • tabindex="-1"을 사용하여 불필요한 요소에 포커스가 가지 않도록 해야 합니다.
  5. 포커스 트랩 구현:
    • 모달 내에서 탭 순서가 벗어나지 않도록 포커스를 제어합니다.
    • 부트스트랩 기본 동작을 유지하면서 포커스를 개선하는 코드:
      $('#order_form_write').on('shown.bs.modal', function () {
          $(this).find('[autofocus]').focus(); // 기본 포커스 대상 설정
      });
      
  6. 모달 내부 포커스 확인:
    • aria-hidden이 설정된 요소가 모달 내부에 있는 경우, aria-hidden 속성을 제거합니다.
    • 문제 해결 코드 예시:
      $('#order_form_write').on('shown.bs.modal', function () {
          $(this).removeAttr('aria-hidden'); // 모달 내부의 aria-hidden 제거
      });
      

부트스트랩의 접근성 설계

부트스트랩은 웹 접근성 표준에 맞추어 설계되었으며, aria-hidden, aria-modal, role="dialog" 등의 속성을 적극적으로 사용합니다. 이를 비활성화하면 보조 기술 사용자에게 접근성 문제가 발생할 수 있으므로, 기본 설정을 유지하되 문제를 유발하는 특정 요소를 수정하는 접근이 필요합니다.

aria-hidden 문제가 계속 발생한다면, 모달을 사용할 때 문제 요소를 식별하여 위 방법으로 해결할 수 있습니다.

 

aria-hidden 문제는 부트스트랩 모달 창을 사용할 때 자주 발생하는데, 특히 모달 내부 요소나 상위 요소에 잘못된 aria-hidden 속성이 적용되어 생길 수 있습니다. 이 문제를 해결하려면 aria-hidden의 작동 방식을 이해하고, 포커스 관리 및 접근성 설정을 올바르게 적용해야 합니다.


aria-hidden 문제의 핵심 이해

  • aria-hidden 역할:
    • 보조 기술(스크린 리더 등)이 해당 요소와 그 하위 요소를 읽지 못하게 합니다.
    • 그러나 키보드 포커스는 차단하지 않으므로, aria-hidden="true"가 설정된 상태에서 자식 요소가 포커스를 가지면 충돌이 발생합니다.
  • 문제 상황:
    • aria-hidden="true"가 설정된 상태에서 자식 요소가 활성화되거나 포커스를 가지는 경우.
    • 부트스트랩 모달 창 내부에서 버튼, 입력 필드 등 포커스 가능한 요소가 있는데, 상위 aria-hidden으로 인해 스크린 리더 접근에 문제가 생김.

문제 해결 방법 (세부 단계)

  1. aria-hidden 속성 확인 및 제거
    • 문제의 근본 원인은 잘못된 aria-hidden 설정입니다.
    • 모달이 열렸을 때, 상위 요소에 설정된 aria-hidden="true"를 제거해야 합니다.
    • 아래 코드는 모달이 열릴 때 aria-hidden 속성을 제거합니다:
      $('#order_form_write').on('shown.bs.modal', function () {
          $(this).removeAttr('aria-hidden'); // 모달에서 aria-hidden 제거
      });
      
  2. 모달 외부 요소 비활성화
    • 모달이 열려 있는 동안 배경 요소에 포커스를 이동하지 못하도록 처리해야 합니다.
    • 부트스트랩은 기본적으로 aria-hidden을 사용하지만, inert 속성을 사용하는 것이 더 안전합니다:
      $('#order_form_write').on('shown.bs.modal', function () {
          $('body > *').not('.modal').attr('inert', ''); // 모달 외 요소 비활성화
      });
      $('#order_form_write').on('hidden.bs.modal', function () {
          $('body > *').not('.modal').removeAttr('inert'); // 비활성화 해제
      });
      
  3. 포커스 트랩 구현
    • 포커스가 모달 내부를 벗어나지 않도록 해야 합니다.
    • 아래 코드는 탭 키로 이동할 때 포커스를 모달 내부로 제한합니다:
      $('#order_form_write').on('shown.bs.modal', function () {
          var modal = $(this);
          modal.find('[autofocus]').focus(); // 초기 포커스 설정
      
          modal.on('keydown', function (e) {
              var focusableElements = modal.find('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])').filter(':visible');
              var firstElement = focusableElements[0];
              var lastElement = focusableElements[focusableElements.length - 1];
      
              if (e.key === 'Tab') {
                  if (e.shiftKey && document.activeElement === firstElement) {
                      lastElement.focus(); // Shift+Tab -> 마지막 요소로 이동
                      e.preventDefault();
                  } else if (!e.shiftKey && document.activeElement === lastElement) {
                      firstElement.focus(); // Tab -> 첫 번째 요소로 이동
                      e.preventDefault();
                  }
              }
          });
      });
      
  4. 모달 내부 포커스 오류 수정
    • aria-hidden이 모달 내부 요소에서 발생한다면, 직접 해당 속성을 관리합니다.
    • 예: 버튼에 포커스가 필요하지만, 상위 aria-hidden 때문에 문제가 발생한다면:
      $('#close_modal1').on('focus', function () {
          $(this).parents('.modal').removeAttr('aria-hidden'); // 상위 aria-hidden 제거
      });
      
  5. 부트스트랩 기본 기능 활용
    • 부트스트랩의 모달 라이브러리는 기본적으로 focus 이벤트와 tab 키 관리를 제공합니다. 하지만 모달이 복잡하거나 동적 요소를 포함하면 설정이 깨질 수 있습니다.
    • shown.bs.modal와 hidden.bs.modal 이벤트를 활용해 포커스를 적절히 관리하세요.

전체 적용 예제

아래 코드는 위에서 설명한 주요 해결 방안을 하나의 흐름으로 적용한 예입니다:

$(document).ready(function () {
    // 모달 열릴 때
    $('#order_form_write').on('shown.bs.modal', function () {
        var modal = $(this);

        // 상위 aria-hidden 제거
        modal.removeAttr('aria-hidden');

        // 배경 요소 비활성화
        $('body > *').not('.modal').attr('inert', '');

        // 초기 포커스 설정
        modal.find('[autofocus]').focus();

        // 포커스 트랩 구현
        modal.on('keydown', function (e) {
            var focusableElements = modal.find('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])').filter(':visible');
            var firstElement = focusableElements[0];
            var lastElement = focusableElements[focusableElements.length - 1];

            if (e.key === 'Tab') {
                if (e.shiftKey && document.activeElement === firstElement) {
                    lastElement.focus();
                    e.preventDefault();
                } else if (!e.shiftKey && document.activeElement === lastElement) {
                    firstElement.focus();
                    e.preventDefault();
                }
            }
        });
    });

    // 모달 닫힐 때
    $('#order_form_write').on('hidden.bs.modal', function () {
        // 배경 요소 비활성화 해제
        $('body > *').not('.modal').removeAttr('inert');

        // 포커스 트랩 이벤트 해제
        $(this).off('keydown');
    });
});

추가 참고 사항

  1. aria-hidden과 inert 비교:
    • aria-hidden은 보조 기술에서 요소를 숨깁니다.
    • inert는 포커스와 보조 기술 모두에서 요소를 차단합니다.
    • 최신 브라우저에서는 inert가 더 권장됩니다.
  2. role="dialog" 및 aria-modal="true" 확인:
    • 모달 최상위 요소에 role="dialog"와 aria-modal="true"가 설정되어 있는지 확인하세요. 이 속성은 부트스트랩 모달 기본 설정에 포함되어야 합니다.
  3. 문제가 계속될 경우:
    • HTML 구조가 올바른지 검토하세요. aria-hidden이 불필요하게 설정된 경우를 찾아 제거하거나 조정해야 합니다.

이 단계들을 통해 aria-hidden 문제를 근본적으로 해결하고, 접근성과 사용자 경험 모두를 개선할 수 있습니다.

반응형
댓글