Home / Snippets / UI Components /

Language-based styling

Adapt typography, quotes, and text direction per language using the :lang() pseudo-class.

:lang(en)

English text flows left-to-right with serif type. Quoted text uses proper curly quotes.

:lang(ar)

النص العربي يتدفق من اليمين إلى اليسار. نص مقتبس يستخدم علامات اقتباس مناسبة.

:lang(ja)

日本語テキストは広い行間で表示されます。引用テキストは鉤括弧を使います。

Widely Supported
uino-jstypography

Quick implementation

/* Base text styles */
:lang(en) {
  direction: ltr;
  font-family: Georgia, "Times New Roman", serif;
  line-height: 1.6;
  quotes: "\201C" "\201D" "\2018" "\2019";
}

:lang(ar) {
  direction: rtl;
  font-family: "Noto Sans Arabic", Tahoma, sans-serif;
  line-height: 1.8;
  quotes: "\00AB" "\00BB";
}

:lang(ja) {
  direction: ltr;
  font-family: "Hiragino Kaku Gothic Pro", "Yu Gothic", sans-serif;
  line-height: 2;
  quotes: "\300C" "\300D" "\300E" "\300F";
}

/* Quoted text picks up language-specific quote marks */
q { quotes: inherit; }

/* RTL-aware spacing */
:lang(ar) .icon-before { margin-inline-end: 0.5rem; }
:lang(en) .icon-before { margin-inline-start: 0.5rem; }

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building a multilingual CSS system.

Goal: Language-aware typography using the :lang() pseudo-class — no JavaScript.

Technical constraints:
- Use :lang(en), :lang(ar), and :lang(ja) selectors.
- Set direction (ltr/rtl), font-family stacks per script, and line-height per language.
- Configure the quotes property for locale-correct quotation marks.
- Use oklch() for any demo colors, not hex or rgba().
- :lang() must match the inherited lang attribute from any ancestor element.

Framework variant (pick one):
A) Vanilla CSS that works with <html lang="..."> or per-element lang attributes.
B) React component — accept a lang prop and apply the correct styles.

Edge cases to handle:
- RTL layout for Arabic: direction, text-align, and logical properties (margin-inline).
- Nested language spans (e.g., English quote inside Arabic paragraph).
- Fallback font stacks for systems without CJK or Arabic fonts installed.
- <q> elements must inherit the correct quote characters per language.
- Interaction between dir attribute and :lang() — they are independent axes.

Return CSS.

Why this matters in 2026

Global audiences demand content in their own language and script. The :lang() pseudo-class lets you ship one stylesheet that adapts typography, quote marks, and text direction automatically — no runtime detection, no JavaScript, no class toggling. Combined with logical properties like margin-inline, your layouts stay correct whether the page reads left-to-right or right-to-left.

The logic

The :lang() pseudo-class matches elements based on the language determined by a combination of the lang attribute, <meta> tags, or HTTP headers. Unlike [lang="ar"], the :lang(ar) selector matches any descendant of an element with lang="ar", even if the descendant has no lang attribute of its own. This inheritance behavior means you set lang once on a container and every child element picks up the correct styles. The quotes property works with <q> elements to insert culturally appropriate quotation marks — curly quotes for English, guillemets for Arabic, corner brackets for Japanese.

Accessibility & performance

Setting direction: rtl via CSS works for visual layout, but screen readers rely on the HTML dir attribute for correct reading order — always pair :lang(ar) styles with dir="rtl" on the markup. The :lang() selector has the same specificity as any other pseudo-class and the browser resolves it at parse time, so there is zero runtime cost compared to class-based approaches. Appropriate line-height values per script improve readability — CJK and Arabic text generally need more vertical space than Latin text to remain legible at body sizes.