W3docs

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 lang attribute, 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-Language response 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 no lang attribute of their own, and it matches sub-variants — :lang(fr) also matches lang="fr-CA".
  • [lang="fr"] matches only the exact element that literally carries lang="fr". It does not match descendants, and it does not match lang="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 lang attribute must be present. :lang() only works when a language is actually declared somewhere up the tree. If your document has no lang attribute, 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) matches lang="fr-CA", but :lang(fr-CA) does not match a plain lang="fr". Target the broad tag (fr) unless you truly need a regional variant.
  • It is case-insensitive. :lang(EN) and lang="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.

Practice

Practice
What does the :lang pseudo-class in CSS do?
What does the :lang pseudo-class in CSS do?
Was this page helpful?