CSS :lang() Pseudo-class

Beginner
6 min read
Updated: Oct 2026
3 examples
Live preview

Definition and Usage

The :lang() pseudo-class matches elements based on the language they are in.

In HTML, language usually comes from the lang attribute (or inheritance from <html lang=…>). Use it for multilingual styling, quote marks, and typography tweaks per language.

Baseline · Widely available.

Not deprecated. Standard Selectors Level 4 functional pseudo-class. Core single-code matching is widely available since July 2015.

Limited support Argument lists & wildcards

:lang(en, fr) and wildcard forms like :lang("*-Latn") are not widely supported yet (notably missing in Chrome/Edge). Prefer one language code per rule for production.

CSS Syntax

syntax.css
:lang( <language-code>) { /* styles */ }

Pass a BCP 47 language tag such as en, fr, or en-US. Matching is case-insensitive.

Common Patterns

PatternDescriptionTry it
:lang(fr)Match French content (and related tags)Try it
:lang(en-US)Match a regional English variantTry it
QuotesSet language-specific quotes for <q>Try it
Nested langA child can override the parent languageTry it
Separate rulesStyle several languages without comma listsTry it
:lang(en) rangePrimary tag matches regional variantsTry it

How to Use :lang()

Mark language in HTML first, then branch styles with :lang().

  1. Set lang on <html> and on any section in another language.
  2. Write rules like p:lang(fr) or :lang(de) > q.
  3. Use primary tags (en) when all regional variants should share styles.
  4. Use separate rules per language for the widest browser support.

Live Preview

Three paragraphs with different lang values. :lang() colors each language; the nested English word inside Polish keeps its own style.

Language sample

Uses :lang(en), :lang(fr), and :lang(pl) on sample text.

Interactive

English: Hello from a road trip playlist tip.

Français : Bonjour depuis un voyage en train.

Polski: Znak DANGER znaczy nie wchodź.

:lang(en) :lang(fr) :lang(pl)

Checking…

CSS Examples

Each snippet focuses on :lang(). Use Try It Yourself for a live editor.

Example 1 — Style French Text

Color paragraphs marked as French.

CSS
<style>
  p:lang(fr) {
    color: #1d4ed8;
    font-weight: 700;
  }
</style>

<p lang="en">Hello</p>
<p lang="fr">Bonjour</p>
Try It Yourself

How It Works

  1. Mark language in HTML. lang="fr" sets the paragraph’s language.
  2. Target with :lang(fr). Only French content gets the rule.
  3. Leave English alone. The en paragraph stays default.
  4. Inheritance works too. A child without its own lang inherits the parent’s language.

Example 2 — Regional English

Match a specific regional tag with :lang(en-US).

CSS
<style>
  p:lang(en-US) {
    outline: 2px solid #db2777;
    outline-offset: 4px;
  }
</style>

<p lang="en-US">US spelling: color</p>
<p lang="en-GB">UK spelling: colour</p>
Try It Yourself

How It Works

  1. Use a full tag. en-US is more specific than en.
  2. Match the range. :lang(en-US) targets that regional English content.
  3. Leave en-GB out. The UK paragraph does not get the outline.
  4. Prefer :lang(en) when every English variant should share one style.

Example 3 — Language-Specific Quotes

Change quotation marks for English and French <q> elements.

CSS
<style>
  :lang(en) > q {
    quotes: "\201C" "\201D" "\2018" "\2019";
  }

  :lang(fr) > q {
    quotes: "« " " »";
  }
</style>

<div lang="en"><q>Hello</q></div>
<div lang="fr"><q>Bonjour</q></div>
Try It Yourself

How It Works

  1. Wrap in a language container. lang on the parent sets the context.
  2. Select the child quote. :lang(en) > q targets quotes in English.
  3. Set quotes. English uses curly marks; French uses guillemets.
  4. Browser inserts the marks. The <q> element shows the configured pairs.

Edge Cases & Pitfalls

Language matching is smarter than a plain attribute check — but mark lang correctly first.

HTML first

Missing lang = no match

Without a usable language (attribute or inheritance), :lang() has nothing reliable to match. Always set lang on <html>.

vs attribute

Smarter than [lang|=en]

[lang|=…] only inspects the attribute string. :lang() uses the determined language and language-range rules.

lists

Comma lists are not universal

:lang(en, fr) support is limited. Write :lang(en) and :lang(fr) as separate rules for Chrome and Edge.

nested

Children can switch language

A nested lang="en" inside French text matches :lang(en), not the parent’s French rule.

Browser Support

:lang() is a browser CSS pseudo-class. Node.js, Deno, and Bun do not evaluate it.

✓ Baseline · Widely available (core matching)

:lang()

Chrome 1+, Edge 12+, Firefox 1+, Safari 3.1+, Opera 10+, Samsung Internet 4+, Internet Explorer 8+. Argument lists and wildcards have limited support.

97% Global reach
Google Chrome 1+
Full support*
Mozilla Firefox 1+
Full support
Apple Safari 3.1+
Full support
Microsoft Edge 12+
Full support*
Opera 10+
Full support*
Samsung Internet 4+
Full support*
Internet Explorer 8+
Full support
:lang(code) Widely supported

Bottom line: *Core single-code matching is safe. Prefer separate rules instead of :lang(a, b) lists. It is not a server runtime API.

Key Takeaways

  • Role: style elements by their content language.
  • Source: usually the HTML lang attribute (and inheritance).
  • Range: :lang(en) covers regional English variants.
  • Practice: one language code per rule for maximum support.

One line: mark language in HTML, then style each language with :lang().

Frequently Asked Questions

It matches elements based on their content language, usually from the HTML lang attribute or inheritance from an ancestor such as html.
From the element’s own lang attribute, or inherited from a parent. HTTP headers and the xml:lang attribute can also contribute in some documents.
:lang(en) matches any English variant, including en-US and en-GB. :lang(en-US) is more specific and matches U.S. English tags in that language range.
The attribute selector only looks at the lang attribute string. :lang() uses the element’s determined language and smarter language-range matching.
Selectors Level 4 allows a comma-separated list, but support is limited (not in Chrome/Edge yet). Prefer separate rules for widest support.
No. It is a CSS pseudo-class evaluated by the browser layout engine, not a Node.js or server runtime feature.

Next: :last-child

Learn the :last-child pseudo-class for targeting the last child in a parent.

:last-child tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful