Global Attributes & i18n

Global attributes work on any HTML element regardless of tag. A small set of them -- `lang`, `dir`, `id`, `class`, `data-*`, and `hidden` -- are the foundation of accessible, internationalised, and well-structured pages.

HTML6 min readConcept 36 of 42

What global attributes are

Global attributes are HTML attributes you can place on any element, not just specific ones. class and id are the most familiar: id must be unique per page and serves as a fragment target, an AT label anchor, and a JavaScript handle; class carries zero semantic meaning but is the primary CSS and JS hook. hidden is a boolean attribute that removes an element from both the visual layout and the accessibility tree, which makes it stronger than display:none in CSS alone because assistive technology also ignores it.

The data-* family lets you store arbitrary key-value pairs directly in the markup. Any attribute starting with data- is valid. JavaScript reads and writes them through the dataset API: el.dataset.userId reads data-user-id. CSS can target them with [data-state='open'] selectors. They carry no semantic meaning for assistive technology, so they are the right place to store UI state that drives JavaScript behaviour without polluting the class list.

Why lang and dir matter for i18n

The lang attribute on <html> tells the browser, search engines, and screen readers what language the page is in. Screen readers use it to choose the correct voice and pronunciation engine. Without it, an English reader might pronounce French or Arabic text using English phonetics, making it unintelligible. WCAG 3.1.1 (Language of Page, Level AA) requires it. When a passage within a page switches language, wrap it in any element with lang set to the new language; this covers WCAG 3.1.2 (Language of Parts, Level AA).

The dir attribute controls the text direction and -- crucially -- the inline layout direction. Setting dir="rtl" on a container does more than align text to the right: it mirrors the reading flow, reverses the order of flex children that use flex-start/flex-end, swaps the meaning of logical CSS properties (margin-inline-start becomes the right margin instead of the left), and moves form labels and icons to the expected side for Arabic, Hebrew, and Persian users. Always pair dir on <html> or a container with the matching lang attribute.

How to use them correctly

Set lang on the <html> element using a valid BCP 47 language tag: lang="en" for English, lang="ar" for Arabic, lang="zh-Hant" for Traditional Chinese. For inline overrides, wrap the foreign passage: <span lang="fr">Bonjour</span>. Do not guess the tag; look it up in the IANA Language Subtag Registry.

For bidirectional text, prefer dir="auto" on mixed-content containers and dir="rtl" on fully RTL containers. Use CSS logical properties (padding-inline-start, text-align: start, border-inline-end) instead of physical properties (padding-left, text-align: left) so your layout adapts automatically when direction changes. Avoid hard-coded left and right in RTL-capable layouts.

Use data-* attributes to drive JavaScript and CSS hooks. Name them with hyphens in HTML (data-is-open) and access them in JS via dataset.isOpen (camelCase conversion is automatic). In CSS, select by state: [data-is-open='true'] { display: block; }. Never use data-* to pass information that assistive technology needs to understand; use ARIA for that.

Try it

Toggle dir between ltr and rtl and watch the layout mirror. Switch the active lang to see how the attribute is applied inline.

Text direction

Language

Brand
AboutWorkContact

Build for everyone.

Open settings

Applied attribute

dir="ltr"

Default direction. Flex children flow left to right. margin-inline-start = left side.

Applied attribute

lang="en" — screen reader uses English voice

WCAG 3.1.1 satisfied. AT uses English pronunciation.

data-* attributes

<!-- HTML -->
<button data-panel-open="false" data-panel-id="settings">
  Open settings
</button>

<!-- JavaScript -->
const btn = document.querySelector('[data-panel-id="settings"]');
btn.dataset.panelOpen;        // "false"
btn.dataset.panelOpen = "true";

<!-- CSS -->
[data-panel-open="true"] { display: block; }

dataset converts hyphen-cased attribute names to camelCase automatically. Use data-* for JS and CSS hooks; use ARIA for anything assistive technology needs to understand.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Which WCAG success criterion does a missing lang attribute on the html element violate?
  2. 2What does setting dir="rtl" on a container affect beyond text alignment?
  3. 3An element has data-panel-open="true". How does JavaScript read this value?

Remember this

  • lang on <html> is required for WCAG 3.1.1 (AA). Use a valid BCP 47 tag like "en" or "ar".
  • dir="rtl" mirrors the full inline layout, not just text -- flex ordering and logical CSS properties are affected.
  • data-* attributes store UI state for JS and CSS; they carry no semantic meaning for AT.
  • hidden removes an element from both the visual layout and the accessibility tree.

Done with this concept?

Mark it complete to track your progress. No login needed.