CSS :lang() Pseudo Class
The :lang() CSS pseudo-class selects the elements with a lang attribute with the specified value. Read about the pseudo-class and try examples.
The :lang() pseudo-class selects elements based on the language they are written in. It lets you apply different styles to content in different languages — for example, French quotation marks for French text and English quotation marks for English text — from a single stylesheet.
This page explains how the browser decides an element's language, how :lang() differs from the [lang] attribute selector, the typographic problems it solves, and the gotchas to watch for.
How the language is determined
A :lang(xx) rule matches an element when its language is xx (or a sub-variant of xx). The browser works out an element's language from the nearest ancestor that declares one, using, in order:
- The HTML
langattribute, e.g.<html lang="it">or<p lang="fr">. This is the most common source. See HTML language codes for the full list of values. - The
<meta>Content-Language declaration. - The HTTP
Content-Languageresponse header sent by the server.
Language values follow BCP 47: a primary subtag like it (Italian) or fr (French), optionally with a region subtag, like fr-CA for Canadian French or en-GB for British English.
:lang() vs. the [lang] attribute selector
It is tempting to write [lang="fr"] instead of :lang(fr), but they behave differently:
:lang(fr)is inherited. It matches every element inside a French region, even those that have nolangattribute of their own, and it matches sub-variants —:lang(fr)also matcheslang="fr-CA".[lang="fr"]matches only the exact element that literally carrieslang="fr". It does not match descendants, and it does not matchlang="fr-CA".
In short, use :lang() to style content by language, and use the attribute selector only when you specifically need to match the attribute string itself.
/* Matches the <html> tag AND every element inside it,
including lang="fr-CA". */
:lang(fr) {
font-style: italic;
}
/* Matches ONLY an element with exactly lang="fr". */
[lang="fr"] {
font-style: italic;
}When would I use it?
The classic use case is language-correct quotation marks. Different languages use different quote glyphs: English uses curly “…”, French uses guillemets « … », German uses „…“. By combining :lang() with the quotes property and the <q> element, the right marks appear automatically based on the surrounding language. Other uses include language-specific fonts, line spacing, or hyphenation (often paired with font-language-override).
Syntax
:lang(language-code) {
/* declarations */
}language-code is a single language tag such as en, fr, or fr-CA. The pseudo-class is typically attached to or combined with a type selector, e.g. p:lang(fr) or :lang(en) > q.
Example: styling text by language
The rule below targets every <p> that is in French (lang="fr"), leaving other paragraphs untouched.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p:lang(fr) {
background: #1c87c9;
color: #eee;
}
</style>
</head>
<body>
<p>I am from France.</p>
<p lang="fr">Je m'appelle Ann</p>
</body>
</html>Example: language-correct quotation marks
Here :lang() is combined with the child combinator (>) and the quotes property so that each <q> gets the punctuation that matches its language — straight English quotes inside the English block and French guillemets inside the French block.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
:lang(en) > q {
quotes: '\201C' '\201D' '\2018' '\2019';
}
:lang(fr) > q {
quotes: '« ' ' »';
}
</style>
</head>
<body>
<h2>:lang() selector example</h2>
<div lang="en">
<q>Lorem ipsum is simply dummy text</q>
</div>
<div lang="fr">
<q>Lorem ipsum is simply dummy text</q>
</div>
</body>
</html>Common gotchas
- The
langattribute must be present.:lang()only works when a language is actually declared somewhere up the tree. If your document has nolangattribute, nothing matches. Add<html lang="en">(or the correct code) to your page root. - Sub-tags match, but not the other way around.
:lang(fr)matcheslang="fr-CA", but:lang(fr-CA)does not match a plainlang="fr". Target the broad tag (fr) unless you truly need a regional variant. - It is case-insensitive.
:lang(EN)andlang="en"match each other; language tags are matched case-insensitively.
Browser support
:lang() with a single language tag is supported in all modern browsers (and as far back as Internet Explorer 8). The newer comma-separated form, :lang(en, fr), is only available in recent browser versions, so stick to one tag per selector for the widest support.
Related chapters
- CSS
quotes— set the quotation marks used by<q>andcontent. - CSS selectors — including the
[lang]attribute selector. - CSS
font-language-override— control language-specific glyphs. - HTML language codes — valid values for the
langattribute.