WCAG 성공 기준 · Level A
WCAG 3.1.1: 페이지의 언어
WCAG 3.1.1은 각 웹 페이지의 기본 인간 언어를 프로그래밍 방식으로 결정할 수 있어야 한다고 요구하며, 주로 HTML 요소에 유효한 lang 속성을 설정함으로써 이를 달성한다. 이는 스크린 리더와 같은 보조 기술이 콘텐츠를 올바르게 발음할 수 있게 하고, 인지 및 언어 기반 장애가 있는 사용자가 페이지를 이해하는 데 도움을 준다.
- Level A
- Wcag
- Wcag 2 2 a
- 이해할 만한
- 접근성
이 규칙의 의미
WCAG 3.1.1 — 페이지의 언어는 이해 가능성(Understandable) 원칙 아래의 레벨 A 성공 기준이다. 이는 모든 웹 페이지의 기본 인간 언어가 보조 기술이 프로그래밍 방식으로 감지할 수 있는 방식으로 노출되어야 함을 요구한다. 실제로는 거의 항상 페이지의 <html> 요소에 유효한 lang 속성을 직접 지정하는 것을 의미한다.
lang 속성 값은 유효한 BCP 47 언어 태그여야 한다. BCP 47 태그는 기본 언어 서브태그(예: 영어의 en, 터키어의 tr, 프랑스어의 fr)와, 선택적으로 하이픈으로 구분된 지역 서브태그(예: en-US, tr-TR, pt-BR)로 구성된다. 언어 태그는 페이지 콘텐츠가 작성된 지배적인 언어를 정확히 반영해야 한다. 주로 터키어로 작성된 페이지는 lang='tr' 또는 lang='tr-TR'를 선언해야 하고, 영어로 작성된 페이지는 lang='en' 또는 그 지역 변형을 선언해야 한다.
<html> 요소가 비어 있지 않고 구문상 유효한 BCP 47 언어 태그를 값으로 가지며, 그 값이 페이지의 기본 언어를 올바르게 식별할 때 페이지는 이 기준을 준수한다. lang 속성이 완전히 누락되었거나, 값이 비어 있거나(lang=''), 값이 인식 가능한 BCP 47 언어 태그가 아닐 때(예: 하이픈 대신 밑줄을 사용한 lang='en_US'나 lang='turkish') 페이지는 실패한다.
XML MIME 타입으로 제공되는 XHTML 페이지의 경우, lang 속성과 XML 네임스페이스 속성인 xml:lang이 모두 존재해야 하며, 그 값은 일치해야 한다. 예를 들어 lang='en'과 xml:lang='tr'처럼 두 값이 서로 다를 경우, 이 기준과 관련 axe-core 규칙인 html-xml-lang-mismatch 모두에 대한 실패가 된다.
WCAG는 한 가지 예외를 명시적으로 언급한다. 페이지가 순수하게 장식용이거나, 의도적으로 식별 가능한 언어가 없도록 설계된 CAPTCHA이거나, 텍스트 없이 이미지로만 구성된 페이지처럼 전적으로 비언어적 콘텐츠로만 이루어진 경우에는 언어를 결정할 수 없을 수 있다. 그러나 이 예외는 매우 좁게 적용되며, 실제 세계의 대부분의 페이지는 언어 선언이 필요할 만큼 충분한 텍스트를 포함하고 있다.
중요한 이유
올바르게 선언된 페이지 언어의 주요 수혜자는 스크린 리더 사용자이며, 이들 대부분은 시각장애가 있거나 심각한 저시력 상태이다. NVDA, JAWS, VoiceOver와 같은 스크린 리더는 적절한 음성 합성(TTS) 음성과 발음 엔진을 선택하기 위해 lang 속성을 사용한다. 터키어 사용자가 lang='tr'가 올바르게 선언된 페이지를 방문하면, 스크린 리더는 터키어 TTS 음성으로 전환하여 올바른 터키어 음운, 강세 패턴, 발음 기호를 적용한다. 이 선언이 없으면 스크린 리더는 사용자의 시스템 언어 또는 완전히 잘못된 언어로 기본 설정될 수 있으며, 그 결과 내용이 이해 불가능한 잡음 같은 발음이 생성된다.
구체적인 상황을 생각해 보자. 시각장애가 있는 터키 시민이 정부 양식을 다운로드하기 위해 공공기관 웹사이트를 방문한다. 사이트에는 lang 속성이 없다. 사용자의 NVDA 설치는 기본적으로 영어 TTS 프로필을 사용한다. 터키어 단어는 영어 음운으로 읽히며, "şehir"(도시)나 "başvuru"(신청) 같은 단어는 알아들을 수 없게 된다. 사용자는 시력이 있는 사람의 도움 없이는 양식을 작성할 수 없으며, 이는 디지털 서비스의 목적을 완전히 무너뜨린다.
인지 및 학습 장애가 있는 사용자도 혜택을 본다. 브라우저는 정확한 번역 제안을 제공하기 위해 lang 속성을 사용한다. 난독증이 있는 일부 사용자는 콘텐츠를 더 쉽게 처리할 수 있는 언어로 변환하기 위해 브라우저 기반 번역 도구에 의존한다. lang 속성이 잘못되었거나 누락되면 이러한 도구는 원본 언어를 잘못 식별하여 번역 품질이 떨어지거나 번역 제안 자체가 나타나지 않게 된다.
Dragon NaturallySpeaking과 같은 음성 제어 소프트웨어에 의존하는 운동 장애가 있는 사용자는, 소프트웨어가 페이지의 언어를 올바르게 해석하여 음성 명령을 화면의 텍스트와 일치시키는 것에 의존한다. 페이지 언어가 잘못 식별되면 이 매칭이 깨진다.
접근성을 넘어, 눈에 보이는 SEO 이점도 있다. 검색 엔진은 페이지의 대상 언어와 지역을 판단하기 위한 여러 신호 중 하나로 lang 속성을 사용하여, 현지화된 검색 결과의 정확성을 높인다. 올바른 언어 태깅은 보조 기술 사용자뿐 아니라 모든 사용자를 위한 브라우저 맞춤법 검사 및 문법 검사 기능의 신뢰성도 향상시킨다. 세계보건기구(WHO)에 따르면 전 세계적으로 약 22억 명이 어떤 형태로든 시각장애를 가지고 있으며, 이들 중 상당수가 스크린 리더에 의존한다. 따라서 올바른 언어 선언은 가장 큰 영향을 주면서도 구현 노력은 가장 적은 접근성 개선 중 하나이다.
관련 Axe-core 규칙
- html-has-lang — 이 규칙은
<html>요소에lang속성이 존재하는지 여부를 검사한다. 문서의 다른 곳에 속성이 있더라도, 루트<html>태그에서lang속성이 완전히 누락된 모든 페이지를 표시한다. 수정이 단일 속성 추가로 끝나기 때문에, 가장 흔하면서도 영향력이 큰 자동 검출 항목 중 하나이다. - html-lang-valid — 이 규칙은
<html>요소의lang속성 값이 유효한 BCP 47 언어 태그인지 검사한다.lang='turkish'(ISO 639-1 코드tr대신 영어 전체 이름을 사용),lang='en_US'(하이픈 대신 밑줄 사용),lang='xx'(언어가 할당되지 않은 플레이스홀더)처럼 인식 가능한 언어 코드가 아닌 값을 표시한다.lang속성이 존재하지만 잘못된 값을 포함하는 경우, 보조 기술이 이를 신뢰할 수 없기 때문에 속성이 아예 없는 것만큼이나 문제가 된다. - html-xml-lang-mismatch — 이 규칙은
<html>요소에lang속성과xml:lang속성이 모두 있는 XHTML 페이지에만 적용된다. 예를 들어lang='en'과xml:lang='tr'처럼 두 속성이 서로 다른 언어 코드를 지정하는 경우를 표시한다. 값이 충돌하면 보조 기술과 XML 프로세서는 상반된 신호를 받게 되어 예측 불가능하게 동작할 수 있다. 두 값 모두 동일한 기본 언어 서브태그를 지정해야 한다.
이 세 규칙은 가장 흔한 프로그래밍 수준의 실패를 다루지만, 자동화 도구는 의미적 정확성 — 즉, 선언된 언어가 실제로 페이지가 작성된 언어와 일치하는지 — 를 검증할 수 없다. 전적으로 터키어로 작성된 페이지가 lang='en'을 선언하면, 세 가지 axe-core 규칙을 모두 통과하더라도 선언된 언어가 페이지의 실제 기본 언어를 반영하지 않기 때문에 WCAG 3.1.1에서는 여전히 실패가 된다. 따라서 선언된 언어가 올바른지 확인하기 위해서는 자동 스캔과 함께 항상 수동 검토가 필요하다.
테스트 방법
- axe DevTools 또는 Lighthouse를 사용한 자동 스캔: Chrome 또는 Firefox에서 페이지를 연다. DevTools(F12)를 열고 axe DevTools 패널 또는 Lighthouse 탭으로 이동한 뒤 전체 접근성 감사를 실행한다.
html-has-lang,html-lang-valid,html-xml-lang-mismatch규칙 아래의 위반 사항을 특히 확인한다. Axe는<html>요소를 강조 표시하고 구체적인 실패 내용을 설명한다. Lighthouse는 접근성(Accessibility) 카테고리에서 유사한 문제를 보여준다. 표시된 모든 위반과 권장 수정 사항을 기록한다. - 수동 소스 검사: 페이지 소스(대부분의 브라우저에서 Ctrl+U)를 열고 시작
<html>태그를 찾는다. 여기에lang속성이 있는지, 속성 값이 유효한 BCP 47 태그인지(IANA Language Subtag Registry를 기준으로 확인), 그리고 페이지 콘텐츠가 작성된 언어를 정확히 반영하는지 확인한다. XHTML 페이지의 경우,xml:lang속성이 있다면 그 기본 언어 서브태그가lang과 동일한지도 확인한다. - NVDA와 Firefox를 사용한 스크린 리더 테스트: NVDA(무료, Windows)를 설치하고 Firefox에서 페이지를 연다. NVDA+T를 눌러 페이지 제목을 읽고 사용 중인 TTS 음성을 들어본다. 페이지가 터키어라면 음성은 터키어 TTS 음성이어야 하고, 터키어 단어가 올바르게 발음되어야 한다. 터키어 콘텐츠에서 영어 또는 다른 잘못된 음성이 들린다면
lang속성이 없거나 잘못된 것이다. Chrome에서 JAWS, macOS의 Safari에서 VoiceOver(Cmd+F5로 VoiceOver 활성화 후 페이지로 이동하여 본문 텍스트 발음을 청취)로도 반복한다. - 브라우저 언어 감지 확인: Chrome에서 페이지를 연다. 브라우저의 내장 번역 표시줄을 확인한다. Chrome은 브라우저 설정과 다른 언어로 된 페이지를 감지하면 번역을 제안한다. Chrome이 페이지 언어를 잘못 식별하거나 번역 제안을 해야 할 상황에서 제안하지 않는다면, 이는
lang속성이 잘못되었거나 누락되었음을 시사하는 실질적인 신호이다. 이는 결정적인 접근성 테스트는 아니지만 유용한 보조 지표이다. - 의미적 정확성 확인(수동만 가능): 페이지 콘텐츠를 읽고 선언된
lang값이 페이지의 실제 기본 언어와 일치하는지 확인한다. 자동화 도구는 이 검사를 수행할 수 없다. 서로 다른 URL에서 다른 언어 버전을 제공하는 다국어 사이트에 특히 주의를 기울여야 한다. 각 URL의 페이지는 전역 기본값을 상속하는 것이 아니라, 자신에게 맞는 올바른 언어를 선언해야 한다.
수정 방법
lang 속성 누락 — 잘못된 예
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Başvuru Formu</title>
</head>
<body>
<h1>Hoş Geldiniz</h1>
</body>
</html>
lang 속성 누락 — 올바른 예
<!DOCTYPE html>
<html lang='tr'>
<!-- lang='tr'은 스크린 리더에게 터키어 TTS 음성을 사용하라고 알려준다 -->
<head>
<meta charset='UTF-8'>
<title>Başvuru Formu</title>
</head>
<body>
<h1>Hoş Geldiniz</h1>
</body>
</html>
유효하지 않은 lang 속성 값 — 잘못된 예
<!DOCTYPE html>
<html lang='turkish'>
<!-- 'turkish'는 유효한 BCP 47 태그가 아니며, axe는 html-lang-valid 위반으로 표시한다 -->
<head>
<title>Kurumsal Site</title>
</head>
<body>
<p>Şirketimiz hakkında bilgi edinmek için buraya tıklayın.</p>
</body>
</html>
유효하지 않은 lang 속성 값 — 올바른 예
<!DOCTYPE html>
<html lang='tr'>
<!-- 영어 단어 'turkish'가 아니라 ISO 639-1 두 글자 코드 'tr'을 사용한다 -->
<head>
<title>Kurumsal Site</title>
</head>
<body>
<p>Şirketimiz hakkında bilgi edinmek için buraya tıklayın.</p>
</body>
</html>
XHTML xml:lang 불일치 — 잘못된 예
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' lang='en' xml:lang='tr'>
<!-- lang와 xml:lang이 일치하지 않음 — html-xml-lang-mismatch 위반 -->
<head><title>XHTML Sayfası</title></head>
<body><p>İçerik burada.</p></body>
</html>
XHTML xml:lang 불일치 — 올바른 예
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' lang='tr' xml:lang='tr'>
<!-- lang와 xml:lang이 모두 'tr'로, 일관되고 유효하다 -->
<head><title>XHTML Sayfası</title></head>
<body><p>İçerik burada.</p></body>
</html>
다국어 사이트에서 잘못된 언어 선언 — 잘못된 예
<!-- 사이트의 영어 버전이지만 lang가 전역적으로 'tr'로 설정되어 있음 -->
<html lang='tr'>
<head><title>About Us</title></head>
<body>
<p>Welcome to our company. We specialize in accessible web solutions.</p>
</body>
</html>
다국어 사이트에서 잘못된 언어 선언 — 올바른 예
<!-- 각 언어 버전이 자신에게 맞는 lang 속성을 선언함 -->
<html lang='en'>
<!-- 이 페이지는 영어 페이지이며, /tr/에 있는 터키어 페이지는 lang='tr'을 선언한다 -->
<head><title>About Us</title></head>
<body>
<p>Welcome to our company. We specialize in accessible web solutions.</p>
</body>
</html>
자주 발생하는 실수
- BCP 47 코드 대신 언어의 영어 전체 이름 사용 —
lang='turkish',lang='english',lang='arabic'처럼 작성하는 대신 올바른 코드인tr,en,ar를 사용해야 한다. 이러한 값은 보조 기술에서 인식되지 않는다. - 지역 구분자로 밑줄 사용 —
lang='en_US'나lang='tr_TR'처럼 작성하는 대신, 하이픈을 사용하는lang='en-US'와lang='tr-TR'를 사용해야 한다. BCP 47은 밑줄이 아닌 하이픈을 요구한다. - <html> 대신 <body>에 lang 속성 설정 —
lang속성은 axe-core의html-has-lang규칙을 충족하고, 보조 기술이 콘텐츠를 파싱하기 전에 페이지 수준의 언어 컨텍스트를 얻을 수 있도록 루트<html>요소에 있어야 한다. - lang를 빈 문자열로 두기 —
lang=''로 설정하면 대부분의 보조 기술에서 속성이 없는 것과 동일하게 취급되며, 빈 문자열은 유효한 언어 태그가 아니기 때문에html-has-lang규칙에 의해 표시된다. - 다른 언어 프로젝트에서 템플릿을 복사하면서 lang 속성을 업데이트하지 않기 — 영어 보일러플레이트를 재사용하면서
<html>태그의lang='en'을lang='tr'로 변경하지 않는 경우처럼, 터키 개발 워크플로에서 매우 흔한 문제이다. - 올바른 lang 속성을 선언했지만 사이트의 새 언어 버전을 출시할 때 업데이트하지 않기 — 서버 사이드 렌더링을 사용하는 다국어 사이트는 공유 레이아웃 템플릿에 단일 값으로 하드코딩하는 것이 아니라, 로케일별로 lang 속성이 동적으로 설정되도록 해야 한다.
- CMS나 프레임워크가 lang 속성을 자동으로 올바르게 설정한다고 가정하기 — 많은 CMS 플랫폼(일부 WordPress, Joomla, 커스텀 프레임워크 구성 포함)은 기본적으로 유효한 lang 속성을 설정하지 않는다. 개발자는 템플릿 수준에서 이를 검증해야 하며, 자동으로 처리된다고 가정해서는 안 된다.
- HTML용 lang 속성과 Content-Language HTTP 헤더를 혼동하기 — HTTP 헤더는 캐싱과 콘텐츠 협상에 영향을 주지만, 스크린 리더에서는 사용되지 않는다. WCAG 3.1.1을 준수하기 위한 올바른 메커니즘은
<html>의 문서 내lang속성이다. - 다른 방언을 의미하는 잘못된 지역 서브태그를 사용하기 — 예를 들어, 간체 중국어(
zh-CN)로 작성된 페이지에lang='zh-TW'(번체 중국어, 대만)를 선언하면 스크린 리더가 잘못된 음성 프로필과 발음 규칙을 선택할 수 있다. - 단일 페이지 애플리케이션(SPA)에서 동적으로 주입되는 전체 페이지 콘텐츠에 lang를 설정하지 않기 — SPA가 동일한 문서 셸 내에서 여러 언어의 콘텐츠를 로드하면서
lang속성을 업데이트하지 않으면, 사용자가 언어 섹션 간을 이동할 때 새 콘텐츠 섹션에 대해 올바른 TTS 발음을 제공받지 못한다.
터키 접근성 규정과의 관계
WCAG 3.1.1 페이지의 언어는 2025년 6월 21일 관보 제32933호에 게재된 2025/10호 대통령령에 따라 터키에서 직접적인 법적 효력을 가진다. 이 대통령령은 WCAG 2.2와 정렬된 의무적 웹 접근성 요구사항을 수립하고, 모든 적용 대상에 대해 레벨 A 적합성을 최소 의무 기준으로 지정한다.
이 대통령령은 공공 및 민간 부문의 광범위한 조직을 포괄한다. 부처, 지방자치단체, 국립대학, 공공병원, 모든 중앙 및 지방 정부 기관을 포함한 공공기관은 대통령령 공포 후 1년 이내에 레벨 A 완전 적합성을 달성해야 한다. 규제 대상인 민간 부문은 2년의 준수 기간을 가지며, 전자상거래 플랫폼, 은행 및 금융기관, 민간 병원 및 의료 서비스 제공자, 200,000명 이상의 가입자를 보유한 통신 사업자, 여행사, 민간 운송 회사, 그리고 교육부(MoNE)의 인가를 받아 운영되는 사립학교를 포함한다.
WCAG 3.1.1이 레벨 A 기준이기 때문에, 대통령령이 적용되는 모든 주체에 대한 의무적 기준선에 포함된다. 공공기관 웹사이트의 <html> 요소에서 lang='tr'를 누락하거나, 잘못되었거나 유효하지 않은 언어 태그를 선언하는 것은 법적으로 의무화된 표준을 직접적으로 준수하지 않는 것이다. 은행이나 전자상거래 플랫폼과 같은 민간 부문 조직의 경우, 준수 기간 내에 동일한 실패가 발생하면 규제 위반이 된다.
이 기준이 터키 웹 팀에 주는 실질적인 의미는 크다. 모든 페이지 템플릿, 모든 CMS 레이아웃, 모든 SPA 셸, 모든 동적으로 생성되는 페이지는 루트 HTML 요소에 유효한 lang='tr'(또는 적절한 변형)가 존재하는지 감사해야 한다. 이는 단순한 모범 사례 권고가 아니라, 2025/10호 대통령령에 따른 법적 의무이다. axe-core 규칙인 html-has-lang과 html-lang-valid가 이러한 실패의 대부분을 자동으로 감지할 수 있다는 점을 고려하면, 준수 기한이 도래하기 전에 이 문제를 식별하고 수정하는 데 기술적 장벽은 없다.
대통령령의 적용을 받는 조직은 WCAG 3.1.1 준수를 최우선 시정 항목으로 취급해야 한다. 이는(단일 요소에 단일 속성을 추가하는) 가장 수정하기 쉬운 기준 중 하나이면서, 스크린 리더 사용자에게 모든 페이지의 접근성에 미치는 영향은 매우 크다. 이들은 규정이 가장 직접적으로 보호하려는 권리의 주체이기 때문이다.
