WCAG 3.1.2 · Level AA · EN 301 549 9.3.1.2

Language of Parts

Requires that passages and phrases in a different language than the page default are marked, so assistive technology pronounces them correctly.

In brief

A page in English with a French quotation, or a Turkish page with an English product name, is read wrongly when the screen reader assumes one language throughout. The French phrase gets English pronunciation and becomes unintelligible.

This criterion requires that the human language of each passage or phrase in the content can be programmatically determined, except for proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the surrounding text.

What does it cover?

  • Marking passages: Put a lang attribute on the element that contains text in a different language than the page default (H58). A phrase can be a single word.
  • Exceptions: Proper names, technical terms, words of indeterminate language, and words that have become part of the vernacular of the surrounding text.
  • Proper names: A name such as "Albert Camus" generally needs no change of language, even on a page in another language.
  • Technical terms: Terms such as "habeas corpus" or "hertz" that are used across languages without translation.
  • Vernacular: Borrowed words such as "rendezvous" in English. If unsure, check whether the word is pronounced the same way as in the surrounding language.
  • Best practice: Marking the source language even for exempt words can improve pronunciation, and is not required.
  • Default language: Content with no lang takes the page default, which must be declared under 3.1.1.

Who does it affect?

Screen reader and text-to-speech users, who hear each phrase with the right pronunciation. Braille users whose software switches braille tables. People with reading, cognitive or language disabilities who rely on text-to-speech. People who rely on captions that show language changes. Language learners and translation tools benefit too.

In the EAA and EN 301 549

The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. A programmatically available language for each passage is part of "understandable".

The technical counterpart is the standard EN 301 549, which incorporates WCAG 3.1.2 by reference and turns it into separate clauses for each kind of ICT.

Where WCAG 3.1.2 appears in EN 301 549
ClauseType of ICTWhat it requires
9.3.1.2Web pagesWeb content must satisfy WCAG success criterion 3.1.2.
10.3.1.2Non-web documents (PDF, Office files)Documents must mark the language of passages where the standard applies the criterion to them.
11.3.1.2Non-web software (native mobile apps)Software must identify the language of passages that differ from its own language.

Whether and how the criterion applies to non-web documents is stated in clause 10 of the standard. Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality. Check the exact numbers in the standard when you cite them.

Standard version: EN 301 549 V4.1.1 (September 2026) is based on WCAG 2.2 and is the first version prepared specifically for the EAA. It has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. The text of criterion 3.1.2 is the same in WCAG 2.1 and 2.2. It is a Level AA criterion.

A note on EAA scope: Article 2(4) of the Directive excludes certain content from the requirements, for example office file formats published before 28 June 2025 and archives that are not updated after that date. Content you publish or change after that date is not covered by these exclusions.

Directive (EU) 2019/882, EUR-Lex, opens in a new tab

Code examples for the web

1. A foreign phrase in a sentence

Wrap it with the right lang (H58).

Incorrect
<p>As the French say, c'est la vie.</p>
Correct
<p>As the French say, <span lang="fr">c'est la vie</span>.</p>

2. A quotation in another language

Mark the quotation, not the whole page.

Incorrect
<blockquote>Die Bremer Stadtmusikanten …</blockquote>
Correct
<blockquote lang="de">Die Bremer Stadtmusikanten …</blockquote>

3. A language switcher

Label each language name in its own language and mark it, so a screen reader pronounces it properly.

Incorrect
<a href="/de">Deutsch</a> <a href="/tr">Türkçe</a>
Correct
<a href="/de" lang="de" hreflang="de">Deutsch</a>
<a href="/tr" lang="tr" hreflang="tr">Türkçe</a>

4. The other-language word is a proper name or vernacular

No markup is required for the exceptions, although it is still allowed.

Incorrect
<p>We met <span lang="fr">Albert Camus</span> at the rendezvous.</p> <!-- optional, not required -->
Correct
<p>We met Albert Camus at the rendezvous.</p> <!-- exempt: proper name and vernacular -->

5. A language change inside a link or button

Put the lang attribute on the element that holds the foreign text.

Incorrect
<a href="/menu">Plat du jour</a>
Correct
<a href="/menu"><span lang="fr">Plat du jour</span></a>

6. A regional variant inside a page

A region subtag can be used on a passage too.

Incorrect
<p>In Brazil: obrigado pelo apoio.</p>
Correct
<p>In Brazil: <span lang="pt-BR">obrigado pelo apoio</span>.</p>

Code examples for mobile

Native apps can mark the language of a passage for the screen reader. The attribute is applied to the text, not to the whole screen.

iOS (SwiftUI)

import UIKit

// The speech language attribute tells VoiceOver how to pronounce this passage
let label = UILabel()
let attributed = NSMutableAttributedString(string: "As the French say, c'est la vie.")
let range = (attributed.string as NSString).range(of: "c'est la vie")
attributed.addAttribute(.accessibilitySpeechLanguage, value: "fr", range: range)
label.attributedText = attributed
label.accessibilityAttributedLabel = attributed

Android (Jetpack Compose)

import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.style.LocaleSpan
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.Locale

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val text = SpannableString("As the French say, c'est la vie.")
        val start = text.indexOf("c'est la vie")
        // LocaleSpan tells TalkBack which language the passage is in
        text.setSpan(LocaleSpan(Locale.FRENCH), start, start + "c'est la vie".length,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        findViewById<TextView>(R.id.label).text = text
    }
}

How to test

  • Find the passages: Look for quotations, phrases, product names, headings and navigation items in a different language than the page default.
  • Check the markup: Does the element that holds foreign text have a valid lang attribute?
  • Apply the exceptions: Is the word a proper name, a technical term, of indeterminate language, or part of the vernacular of the surrounding text?
  • Check language switchers: Are the names of the languages marked up in their own languages?
  • Listen: Read the page with a screen reader that switches voices. Are the foreign phrases pronounced correctly?
  • Check the markup, not only the audio: Do not rely on assistive technology output alone. Some tools drop language changes in accessible names, so inspect the code.
  • Use a checker as a starting point: Tools such as axe (rule valid-lang) detect invalid values. They cannot find passages that should be marked, so a person must read the content.

Common mistakes

  • Passages in another language with no lang: The screen reader mispronounces them.
  • Marking the whole page as the foreign language: Use the page default and mark only the passage.
  • Invalid or mismatched codes: Marking French text as lang="fr-FR" is fine, marking it as lang="french" is not.
  • Language names that are not marked: A switcher that lists "Deutsch", "Türkçe" and "Français" with no lang.
  • Marking everything: Exempt words such as proper names need not be marked.
  • Marking nothing: Quoted passages and foreign headings are overlooked.
  • Language only in aria-label: Language changes inside an accessible name can be lost, so check the markup and prefer visible text marked with lang.
  • Relying on automatic language detection: Assistive technology does not reliably guess the language of short phrases.

Sources

Standard version: EN 301 549 V4.1.1 (2026-09), WCAG 2.2. This page is for informational purposes only and is not legal advice. For binding requirements, refer to the official texts of the European Accessibility Act (Directive (EU) 2019/882) and EN 301 549.

Corpowid is recognized by Gartner

Corpowid has been recognized by Gartner, a leading global research and advisory firm, for our innovation and performance in digital accessibility. These badges reflect our commitment to creating inclusive, AI-powered web experiences.

Have questions about Corpowid?

Let’s connect.

We will get back to you as soon as possible.