[번역] HTML 랜드마크 역할을 사용하여 접근성 향상시키기

sejin kim·2023년 8월 20일
0

번역

목록 보기
4/6
post-thumbnail

이 글은 mdn blog의 아티클 'Using HTML landmark roles to improve accessibility'를 한국어로 옮긴 것입니다. 원본 콘텐츠의 저작자는 Schalk Neethling이며, Creative Commons Attribution-ShareAlike license (CC-BY-SA 2.5) 라이선스가 부여되어 있습니다.


스크린 리더와 같은 보조 기술을 사용하는 사용자를 포함하여, 모든 사용자들이 웹 사이트에 접근할 수 있는지 확인하는 것은 중요합니다. 이를 위한 한 가지 방법은 ARIA 랜드마크 역할(ARIA landmark roles)을 사용하여 스크린 리더 사용자가 웹 사이트를 쉽게 탐색할 수 있도록 하는 것입니다. 랜드마크 역할을 사용하면 HTML의 의미론적 체계를 개선하고, 웹 사이트의 스타일링을 더 쉽게 할 수 있는 이점이 있습니다. 이 글에서는 이러한 랜드마크에 대해 자세히 살펴보고, 간단한 예제를 통해 웹 사이트에서 어떻게 이것을 활용하는지 살펴보겠습니다.






HTML 랜드마크 역할이 무엇인가요?

랜드마크란 ARIA(Accessible Rich Internet Applications) Spec에서 '사용자가 빠르게 액세스하기를 원하는 페이지 영역'으로 정의됩니다. 이것이 특별히 스크린 리더 사용자를 위한 것이라고 명시되어 있지는 않지만, 이들은 특히 도움이 될 수 있는 사용자 그룹입니다. ARIA 스펙에서는 아래와 같은 8가지의 역할이 정의되어 있습니다 :


  • banner
  • navigation
  • search
  • main
  • region
  • complementary
  • form
  • contentinfo

일반적으로 요소(element)에 특정한 역할을 할당하는 방법은 role 속성을 사용하는 것입니다. 예를 들면 :


<div class="banner" role="banner"></div>

요소의 역할을 명시적으로 설정해야 하는 경우가 있을 수 있지만, 일부 HTML 요소는 이미 연관된 역할을 가지고 있을 수 있습니다. 이 글의 나머지 부분에서는 아래와 같은 ARIA의 첫 번째 규칙을 준수할 것입니다.


만약 요소의 용도를 변경하고 액세스할 수 있도록 ARIA 역할, 상태 또는 속성을 추가하는 것 대신에, 이미 내장된(built-in) 의미와 동작을 가지는 네이티브 HTML 요소 또는 속성을 사용하여 구현할 수 있는 경우라면, 그렇게 하세요.






랜드마크 역할을 사용하는 방법

HTML 랜드마크가 작동하는 방식을 설명하기 위해, 스크린 리더 사용자를 위한 사용자 경험과 접근성을 향상시키는 기본 웹 페이지를 구축합니다. CSS를 작성하지 않고 깨끗하고 의미있는 HTML(Semantic HTML)을 작성하는 데 중점을 두겠습니다.

다음의 HTML을 index.html 파일로 저장하고 원하는 브라우저에서 엽니다.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Mr. Pineapple's Pizzeria</title>
    </head>
    <body></body>
</html>

브라우저 탭에 "Mr. Pineapple's Pizzeria"라는 제목의 빈 페이지가 표시되어야 합니다. 각 랜드마크에 대해 적절한 HTML을 추가하고, 접근성 트리를 검사하여 어떻게 변경되는지 확인해 봅니다.



배너 랜드마크는 웹 페이지의 헤더(머리말)를 식별하는 데 사용됩니다. 일반적으로 이 헤더에는 웹 사이트의 로고, 내비게이션 및 검색 입력이 포함되어 있습니다. <header> 요소가 <main> 요소나 다른 섹션 요소의 자식 요소로 사용되지 않을 때는 banner 역할이 할당됩니다.

페이지에 배너 랜드마크를 추가했을 때 어떻게 보이는지 살펴보겠습니다.


<body>
    <header>
        <a class="logo" href="/">
            <span class="visually-hidden">Mr. Pineapple's Pizzeria</span>
        </a>
    </header>
</body>

페이지를 새로고침하고 개발자 도구를 엽니다. 브라우저에 따라 접근성 트리에 액세스하는 방법이 다릅니다. 자세한 내용은 아래 링크를 참조하세요.


  • Firefox
  • Chromium (Edge, Chrome, Arc)
  • Safari에서는, 개발자 도구(Web Inspector로 지칭되는)를 열고 Elements 탭에서 요소를 선택합니다. 맨 오른쪽에서 Node 탭을 선택하고 Accessibility 섹션을 확장합니다.


스크린샷에서 볼 수 있듯이, <header> 요소를 선택하면 역할이 banner로 표시됩니다. 출발이 아주 좋습니다!


참고 Firefox 개발자 도구의 접근성 검사기는 요소에 대한 적절한 역할을 표시하지 않습니다. 대신 이러한 모든 요소의 역할을 '랜드마크'로 표시합니다. 이 문제는 현재 해결되었고 Firefox 114에 포함될 것입니다. 개발자용 Firefox를 사용하고 있었다면 이 문제는 이미 해결되었을 것입니다.



navigation 랜드마크는 사용자가 웹 페이지 또는 관련된 웹 페이지를 탐색하는 데 도움이 되는 링크의 집합을 식별하는 데 사용됩니다. 이는 사이드바 내비게이션, 사이트의 메인 내비게이션 또는 페이지의 푸터에 있는 관련 링크 집합 등을 포함할 수 있습니다.

앞에서 언급했듯이, 페이지의 헤더에서 자주 찾을 수 있는 요소 중 하나는 사이트의 메인 내비게이션입니다. 페이지에 한 가지를 추가해 보겠습니다 :


<nav aria-label="Primary">
    <ul>
        <li><a aria-current="page" href="/">Home</a></li>
        <li><a href="/menu">Our pizzas</a></li>
        <li><a href="/contact">Get in touch</a></li>
    </ul>
</nav>

여기서는 <nav> 요소를 사용했습니다. 왜냐하면 이 요소는 암묵적으로 '탐색', navigation의 역할을 가지고 있기 때문입니다. 페이지에는 여러 개의 내비게이션 요소가 존재할 수 있으므로, 이러한 랜드마크를 각각 고유하게 식별하는 것이 중요합니다. 이를 위해 aria-label 속성을 사용하여 내비게이션 랜드마크에 "Primary"라는 이름을 지정합니다.


참고 스크린 리더가 위의 내비게이션 랜드마크를 설명할 때에는 '주요(primary) 내비게이션'이라고 할 것입니다. 이것이 aria-label 값에 '탐색(navigation)'이라는 단어가 포함되지 않은 이유입니다.


<nav> 요소를 검사하면 두 가지를 알 수 있게 됩니다. 요소는 내비게이션 랜드마크로 식별되며, aria-label을 통해 할당한 값을 노출합니다.




search 랜드마크

search 랜드마크는 웹 사이트의 검색 수단을 함께 제공하는 일련의 관련된 요소들을 그룹화는 데 사용됩니다. 이 역할을 사용하는 가장 일반적인 방법은 폼을 사용하는 것입니다.


<form name="site-search" action="/search" method="get" role="search">
    <label for="query">Find your perfect pizza</label>
    <input type="search" id="query" name="query" />
</form>

여기서는 요소에 역할을 명시적으로 할당해야 하는 첫 번째 경우를 마주하게 됩니다. '검색'이라는 암묵적인 역할을 가진 네이티브 HTML 요소가 없기 때문에, 이 예제에서는 <form> 요소에 역할을 할당합니다. 이는 이 글의 후반부에서 논의할 새로운 HTML 요소의 도입으로 변경될 것입니다.

개발자 도구를 사용하여 폼 요소를 검사해 보면, 해당 랜드마크가 올바르게 search 랜드마크로 식별된 것을 확인할 수 있습니다.




main 랜드마크

이제 헤더에서 벗어나 페이지의 본문 영역으로 진입합니다. 이로써 다음 랜드마크, 적절히 명명된 main이 소개됩니다. 중요한 점은, 페이지에는 단 하나의 <main> 요소만 존재할 수 있다는 점에 유의합니다.



개발자 도구에서 <main> 요소를 선택해 보면 메인 콘텐츠를 올바르게 식별합니다.



region 랜드마크

메인 콘텐츠는 여러 유형의 콘텐츠나 영역으로 구성될 수 있고, 각자의 역할이 존재합니다. 하지만 region은 흥미로운 역할 중 하나입니다. 기술적으로는 지역/영역(region)의 역할을 암묵적으로 가지는 HTML 요소가 존재하긴 하지만, 해당 요소는 다소 논란의 여지가 있기도 합니다.

제가 언급하고 있는 요소는 바로 <section> 요소이며, 어떤 사람들은 이것을 <div>의 다른 이름으로 지칭하기도 합니다. 논란이 발생하는 이유는, 아래 예제와 같이 사용되었을 때 이 요소가 어떠한 의미론적(semantic)인 내용을 가지지 않기 때문입니다.


<section>
    <h2>Our pizzas</h2>
    <ul>
        <li>Margherita with pineapple</li>
        <li>Veggie with pineapple</li>
        <li>Meaty with pineapple</li>
    </ul>
</section>

개발자 도구로 검사해보면, 해당 요소가 지역(region) 탐색 랜드마크로 식별되지 않는 것을 확인할 수 있습니다.



그렇다면 이것을 어떻게 '지역'의 의미를 가지도록 바꿀 수 있을까요? 이를 위해 aria-labelledby 속성을 사용하여 섹션에 헤딩(heading) 요소를 연결시킬 수 있습니다. 이는 두 가지 목적을 가집니다. 첫째는 섹션을 지역 내비게이션 랜드마크로 바꾸는 것이고, 둘째는 헤딩을 통해 해당 지역에 대한 고유한 이름이 부여되도록 하는 것입니다.

<secion> 요소에 연결할 만한 제목이 없는 특수한 경우에는, aria-label 속성을 사용하여 같은 결과를 얻을 수도 있습니다. 이전의 코드를 이렇게 업데이트해 보겠습니다 :


<section aria-labelledby="our-pizzas-heading">
    <h2 id="our-pizzas-heading">Our pizzas</h2>
    <p>
        All our pizzas come with the best pizza topping in the world. Pineapple!
    </p>
    <ul>
        <li>Margherita with pineapple</li>
        <li>Veggie with pineapple</li>
        <li>Meaty with pineapple</li>
    </ul>
</section>

이제 <section> 요소를 검사하면, 올바르게 지역 랜드마크로 식별되고 헤딩 요소에서 상속된 이름이 표시될 것입니다 :



이쯤에서 랜드마크를 사용하는 이유를 강조해 보자면 다음과 같습니다. 랜드마크란 사용자가 가장 관심을 갖고 탐색하고자 하는 페이지의 주요 영역들을 식별하기 위한 것입니다. 따라서 페이지의 어느 영역을 랜드마크로 강조할 것인지 결정하려는 때에는 신중해야 합니다.



complementary 랜드마크

complementary 랜드마크는 메인 콘텐츠와 분리되어도 여전히 의미를 가지면서, 메인 콘텐츠를 보완하는 콘텐츠를 식별하기 위한 것입니다. 여기에는 관련 기사, 공연 시간표 또는 날씨 정보 등이 포함될 수 있습니다. 우리 페이지에서는 몇 가지 훌륭한 피자 레시피에 대한 링크를 제공할 것입니다.

이번에는 랜드마크에 사용할 수 있는 네이티브 HTML 요소가 존재합니다 :


<aside aria-labelledby="pizza-recipe-heading">
    <h3 id="pizza-recipe-heading">Make your own pie!</h3>
    <p>Below is a list of our favorite pizza recipes.</p>
    <ul>
        <li><a href="/mushroom-pizza">The shroom</a></li>
        <li><a href="/smokey-joe">Smokey Joe</a></li>
        <li><a href="/fromage">Fromage</a></li>
    </ul>
</aside>

<aside> 요소는 암묵적으로 보완의 역할을 가지므로, 우리의 요구사항에 완벽하게 부합하는 선택입니다. 한 페이지에 여러 개의 보완 영역을 가질 수 있기 때문에, 각각을 고유하고 설명적으로 명명하는 것이 중요합니다. 이를 위해 <aside> 요소에 aria-labelledby 속성으로 헤딩 요소를 연결하거나, aria-label 속성을 사용할 수 있습니다.

개발자 도구에서 요소를 검사해보면 보완 탐색(complemantary navigational) 랜드마크 역할로 식별되며, 관련된 헤딩 요소에서 이름을 상속받았음을 확인할 수 있습니다.




form 랜드마크

언뜻 보기에는 당연해 보일 수 있지만, <section> 요소에 대한 논의와 유사한 뉘앙스를 고려해 보면 그렇지 않을 수도 있습니다. 페이지에 뉴스레터 구독 폼을 추가해 보겠습니다.


<div class="newsletter">
    <h3>Subscribe to Mr. Pineapple's newsletter</h3>
    <p>
        In our newsletter, you can expect even more wonderful pizza recipes, all featuring the versatile pineapple.
    </p>
    <form name="newsletter" action="/subscribe" type="post">
        <label for="email">Please provide your email address</label>
        <input type="email" id="email" name="email" />

        <button type="submit">Pineapple Me 🍍</button>
    </form>
</div>

<form> 요소를 검사했을 때 form 랜드마크가 아닌 일반 섹션으로 식별되어 실망할 수 있습니다.



어떻게 된 일일까요? 이전의 <section> 요소와 마찬가지로, 폼에 헤딩 요소를 연결하거나 aria-label 속성을 사용해야 합니다. 이미 설명적인 제목이 존재하므로 폼과 제목을 연결하기만 하면 됩니다.


<div class="newsletter">
    <h3 id="newsletter-subscribe-form-heading">
        Subscribe to Mr. Pineapple's newsletter
    </h3>
    <p>
        In our newsletter, you can expect even more wonderful pizza recipes, all featuring the versatile pineapple.
    </p>
    <form
        aria-labelledby="newsletter-subscribe-form-heading"
        name="newsletter"
        action="/subscribe"
        type="post"
    >
        <label for="email">Please provide your email address</label>
        <input type="email" id="email" name="email" />

        <button type="submit">Pineapple Me 🍍</button>
    </form>
</div>

이러한 변경 사항을 적용하고 <form> 요소를 검사하면, 예상한 결과를 확인할 수 있습니다 :




contentinfo 랜드마크

contentinfo 랜드마크는 저작권 정보나 개인정보 보호 정책 링크와 같이 웹 페이지에 대한 정보를 식별하는 데 사용됩니다. 가장 흔한 사용례는 페이지의 푸터입니다. 이번에도 구조적으로 사용할 수 있는 네이티브 HTML 요소가 존재합니다.


<footer>
    <p>Copyright &copy; Mr. Pineapple's Pizzeria - 2023</p>
</footer>

<header> 요소와 마찬가지로, <footer> 요소가 <main> 요소나 다른 섹션 요소의 내부에 위치하지 않도록 주의해야 합니다. 그렇게 되면 <footer> 요소는 contentinfo의 암묵적인 역할을 가지지 않게 됩니다. <footer> 요소가 <body> 요소의 직계 자식인 것을 고려하고 개발자 도구에서 검사하면 예상한 결과를 확인할 수 있습니다.




새로운 검색 HTML 요소

이제 우리는 모든 랜드마크 역할을 다루었고, 각 랜드마크에는 네이티브 HTML 요소가 존재했습니다. regionform 랜드마크에서는 약간의 추가 작업을 해야 했습니다만, role 속성을 명시적으로 사용할 필요는 없었습니다.

하지만, search 랜드마크는 어떨까요? 우리는 폼에 role 속성을 사용해야만 했습니다. 이런! 하지만 글 후반부에서 의외의 소식을 전해드릴 것이라고 언급한 적이 있었습니다. 새로운 <search> 요소를 도입함으로 인해 폼에 명시적으로 search 역할을 할당해야 하는 시대는 끝나고 있습니다. 그렇다면 어떻게 사용할 수 있을까요? 이전의 search 랜드마크를 새 요소를 사용하도록 업데이트해 보겠습니다 :


<search>
    <form name="site-search" action="/search" method="get" role="search">
        <label for="query">Find your perfect pizza</label>
        <input type="search" id="query" name="query" />
    </form>
</search>

하지만 이것은 최신 기술이므로, 오늘날(2023년 초) <search> 요소를 검사하면 접근성 트리에서 무시된 것으로 표시되는 것을 확인할 수 있습니다.



<form> 요소에서 role 속성을 유지했던 이유가 이것입니다. 브라우저와 스크린 리더가 <search> 요소를 구현하기 시작하면, 더 이상 폼에는에 role 속성이 필요하지 않을 것입니다. 과거 <main> 요소의 경우에도 인터넷 익스플로러에서의 지원이 부족하여 동일한 문제가 있었고, 해당 요소에 명시적으로 role="main"을 추가해야 했던 적이 있습니다.

이제 우리가 함께 구축했던 멋진 접근성 트리를 돌아보겠습니다 :



아름다운 작품이지 않습니까?



Chrome에서 전체 접근성 트리 활성화하기

이러한 트리를 표시하는 것은 크로미움 계열 브라우저의 실험적인 기능입니다. 개발자 도구에서 접근성 탭을 선택했을 때 왼쪽에 체크박스가 선택되어 있지 않은 '전체 페이지 접근성 트리 사용(Enable full-page accessibility tree)'이라는 항목이 표시되어야 합니다.



체크박스를 선택하면 DevTools를 다시 로드하라는 알림이 표시됩니다. 버튼을 클릭하고 DevTools를 다시 로드한 후, Elements 패널의 우측 상단에 새로운 아이콘이 표시됩니다. 이 아이콘을 클릭하면 전체 접근성 트리가 표시됩니다.




스크린 리더로 랜드마크 시연하기

이제 모든 것들을 종합하여 우리의 랜드마크가 스크린 리더와 함께 어떻게 동작하는지 살펴보겠습니다.







요약

HTML 랜드마크는 스크린 리더 사용자에게 더 나은 웹 페이지 접근성을 제공하는 중요한 도구입니다. 웹 페이지에 랜드마크를 정의함으로써 사용자들이 더 쉽게 페이지를 탐색하고 필요한 정보들을 빠르게 찾을 수 있도록 도울 수 있습니다. 가능한 경우 적절한 HTML 요소를 사용하고, 랜드마크에 명확한 레이블을 지정하여 사용자가 해당 랜드마크의 목적을 인지할 수 있도록 해야 한다는 사실을 기억하세요.



유용한 자료들

profile
퇴고를 좋아하는 주니어 웹 개발자입니다.

0개의 댓글