5 min read
On this page

Accessibility and Internationalization

Building software that works for everyone — regardless of ability, language, or culture.

Web Accessibility (a11y)

WCAG (Web Content Accessibility Guidelines)

The international standard for web accessibility. Four principles (POUR):

Perceivable: Information must be presentable in ways users can perceive (not invisible to all senses).

Operable: Interface must be operable (navigable, interactive) by all users.

Understandable: Information and UI must be understandable.

Robust: Content must be interpretable by a wide variety of user agents and assistive technologies.

WCAG Conformance Levels

Level A: Minimum accessibility. Basic requirements (alt text, keyboard access).

Level AA: Standard target for most websites. Addresses major barriers (color contrast 4.5:1, resize text, clear navigation).

Level AAA: Highest level. Enhanced requirements (contrast 7:1, sign language for video, simple language). Not always feasible.

Legal requirement: Many jurisdictions require Level AA (ADA in US, EN 301 549 in EU, Accessibility Regulations in UK).

Key Accessibility Practices

Images: Provide alt text for meaningful images. Empty alt="" for decorative images.

<img src="chart.png" alt="Sales increased 25% from Q1 to Q2 2024">
<img src="decorative-line.png" alt="">

Headings: Use proper heading hierarchy (h1 → h2 → h3). Don't skip levels. Screen readers use headings for navigation.

Forms: Associate labels with inputs. Provide error messages. Group related fields with fieldset/legend.

<label for="email">Email address</label>
<input type="email" id="email" name="email" aria-required="true"
       aria-describedby="email-help">
<span id="email-help">We'll never share your email</span>

Color: Don't rely on color alone to convey information. Use icons, patterns, or text alongside color. Meet contrast ratios (4.5:1 for normal text, 3:1 for large text).

Keyboard: All functionality must be accessible via keyboard. Tab order must be logical. Focus indicators must be visible. No keyboard traps.

Semantic HTML: Use proper elements (<nav>, <main>, <article>, <button>, <table>) instead of generic <div> with click handlers.

ARIA (Accessible Rich Internet Applications)

ARIA attributes provide semantic information for assistive technologies when HTML semantics aren't sufficient.

<!-- Role: tell screen readers what the element IS -->
<div role="alert">Error: Invalid email address</div>

<!-- State: dynamic state information -->
<button aria-expanded="false" aria-controls="menu">Menu</button>

<!-- Properties: relationships and descriptions -->
<input aria-labelledby="label-name" aria-invalid="true">

First rule of ARIA: Don't use ARIA if a native HTML element provides the semantics you need. <button> is better than <div role="button">.

Screen Readers

Software that reads screen content aloud for visually impaired users.

Major screen readers: NVDA (Windows, free), JAWS (Windows, commercial), VoiceOver (macOS/iOS, built-in), TalkBack (Android, built-in).

Testing: Use a screen reader to navigate your application. Identify missing labels, confusing reading order, and inaccessible interactions.

Focus Management

For dynamic content (SPAs, modals, notifications):

// When opening a modal, move focus to it
modal.focus();

// When closing, return focus to the trigger
triggerButton.focus();

// Trap focus within the modal (Tab cycles within modal only)

Focus trap: In a modal dialog, Tab should cycle within the modal (not escape to the background page).

Testing Accessibility

Automated: axe-core, Lighthouse, WAVE, Pa11y. Catch ~30-40% of issues automatically (missing alt text, contrast, missing labels).

Manual: Keyboard navigation, screen reader testing, zoom to 200%, cognitive review.

User testing: Include people with disabilities in usability testing.

Internationalization (i18n)

Unicode

Unicode: Universal character set. Assigns a unique code point to every character from every writing system.

UTF-8: Variable-length encoding of Unicode.

  • ASCII characters: 1 byte (backward compatible)
  • Latin/Cyrillic/Arabic: 2 bytes
  • CJK characters: 3 bytes
  • Emoji, rare characters: 4 bytes

UTF-8 is the standard. Use it everywhere: source code, databases, APIs, file systems. String in Rust is always valid UTF-8.

Grapheme clusters: A single "character" as perceived by the user may be multiple code points. "é" can be one code point (U+00E9) or two (e + combining accent). "🏳️‍🌈" is 4 code points. Always operate on grapheme clusters for user-facing text operations.

s ← "Héllo 🌍"
graphemes ← GRAPHEME_CLUSTERS(s)
// ["H", "é", "l", "l", "o", " ", "🌍"]

Locale Handling

A locale specifies language + region + cultural conventions: en-US, fr-FR, ja-JP, ar-SA.

Affects: Number formatting (1,000.50 vs 1.000,50), date formatting (MM/DD/YYYY vs DD/MM/YYYY), currency, sorting, text direction.

Date and Time

Store in UTC. Display in the user's local timezone.

utc_now ← CURRENT_TIME_UTC()
// Store in database as UTC

// Display for user in Tokyo (UTC+9)
tokyo ← TIMEZONE(offset: +9 hours)
local ← CONVERT_TIMEZONE(utc_now, tokyo)

ISO 8601: Standard format for dates/times: 2024-03-15T10:30:00Z.

Timezone database (IANA/Olson): America/New_York, Asia/Tokyo. Use database identifiers, not offsets (offsets change with DST).

Number and Currency Formatting

English (US):  1,234,567.89  $1,234.56
German:        1.234.567,89  1.234,56 €
Indian:        12,34,567.89  ₹12,34,567
Arabic:        ١٬٢٣٤٬٥٦٧٫٨٩

Use the locale-aware formatting libraries. Never format numbers with string concatenation.

RTL (Right-to-Left) Support

Arabic, Hebrew, Persian, and Urdu are written right-to-left.

<html dir="rtl" lang="ar">

Logical properties (CSS): Use margin-inline-start instead of margin-left. padding-inline-end instead of padding-right. These automatically flip for RTL.

Bidirectional text: A paragraph may contain both RTL and LTR text. The Unicode Bidirectional Algorithm handles this automatically (mostly).

Pluralization

Different languages have different plural rules:

| Language | Forms | Example | |---|---|---| | English | 2 (one, other) | 1 item, 2 items | | Russian | 3 (one, few, many) | 1 файл, 2 файла, 5 файлов | | Arabic | 6 (zero, one, two, few, many, other) | Complex rules | | Japanese | 1 (other) | No plural forms |

ICU MessageFormat: Standard for handling plurals, gender, and other variations.

{count, plural,
    =0 {No items}
    one {# item}
    other {# items}
}

Translation Workflow

  1. Externalize strings: No hardcoded text in code. Use message catalogs.
  2. Use keys: msg_welcome_user instead of "Welcome, {name}".
  3. Provide context: Comments for translators ("this button submits a payment form").
  4. Handle variables: Use placeholders {name}, not string concatenation.
  5. Review translations: Native speakers review for accuracy and natural phrasing.
  6. Test: Check layout (text expansion — German is ~30% longer than English), RTL, special characters.

Tools: gettext (classic), i18next (JS), Fluent (Mozilla), ICU MessageFormat.

Inclusive Design Principles

  1. Recognize exclusion: Permanent (blind), temporary (eye surgery), situational (bright sunlight).
  2. Solve for one, extend to many: Captions help deaf users AND people in noisy environments.
  3. Learn from diversity: Include diverse perspectives in design and testing.

Applications in CS

  • Legal compliance: ADA, EU Accessibility Act, Section 508 require accessible digital products.
  • Market reach: 1 billion people have disabilities. Accessible products reach more users.
  • Global products: i18n enables serving users worldwide. Localization is a competitive advantage.
  • Search engine optimization: Semantic HTML and alt text improve SEO.
  • Mobile: Touch targets, screen reader support, font scaling — accessibility is essential for mobile.
  • Developer experience: Error messages, documentation, CLI tools should be clear and accessible.