Overview
The user interface is the psychological bridge between the immigrant and the legal aid system. UX localization is not merely the translation of strings; it is the structural adaptation of the application environment to mitigate cognitive load and build trust.
Language Selection
Critical Principle: No Flags
Never use national flags to represent languages.
| Problem | Example | Impact |
|---|---|---|
| Conflates nationality with language | Spanish flag for Spanish | Alienates Mexican, Salvadoran users |
| Political implications | PRC flag for Chinese | Alienates Taiwanese, Hong Kong users |
| Excludes diaspora | US flag for English | Confuses non-US English speakers |
Best Practice: Endonyms
Display languages using their native names:
| Language | Endonym | Wrong | Why Wrong |
|---|---|---|---|
| Spanish | Español | Spanish | Forces English comprehension |
| Chinese (Simplified) | 简体中文 | Chinese | Doesn't distinguish scripts |
| Chinese (Traditional) | 繁體中文 | Chinese | Doesn't distinguish scripts |
| Vietnamese | Tiếng Việt | Vietnamese | Forces English comprehension |
Placement Options
| Position | Pros | Cons | Best For |
|---|---|---|---|
| Header (top right) | Highly visible, standard | Takes header space | Primary sites |
| Footer | Always accessible | Less visible | Secondary option |
| Floating button | Persistent access | Can feel intrusive | Mobile apps |
| Onboarding modal | Immediate choice | Adds friction | First-time critical |
Implementation Pattern
<nav class="language-selector" aria-label="Language selection">
<button class="language-selector__trigger" aria-expanded="false">
<span class="language-selector__current">English</span>
<span class="language-selector__icon" aria-hidden="true">▼</span>
</button>
<ul class="language-selector__menu" role="menu">
<li role="menuitem"><a href="/en/" lang="en">English</a></li>
<li role="menuitem"><a href="/es/" lang="es">Español</a></li>
<li role="menuitem"><a href="/zh-hans/" lang="zh-Hans">简体中文</a></li>
<li role="menuitem"><a href="/zh-hant/" lang="zh-Hant">繁體中文</a></li>
<li role="menuitem"><a href="/vi/" lang="vi">Tiếng Việt</a></li>
</ul>
</nav>
Persistence Strategies
| Method | Persistence | Privacy |
|---|---|---|
URL path (/es/page) |
Per-session, shareable | High |
| Cookie | Cross-session | Medium |
| localStorage | Cross-session | High |
| Account setting | Permanent | Requires auth |
Recommendation: Use URL path for shareability + localStorage for returning users.
Typography
Font Selection
| Script | Recommended Font | Fallback | Notes |
|---|---|---|---|
| Latin (EN/ES) | Inter, Open Sans | System sans-serif | Standard web fonts |
| Chinese | Noto Sans CJK SC/TC | PingFang, Microsoft YaHei | Simplified vs Traditional |
| Vietnamese | Noto Sans, Inter | System sans-serif | Diacritic support critical |
Noto Sans CJK Loading
/* Subset loading for Chinese characters */
@font-face {
font-family: 'Noto Sans SC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/NotoSansSC-Regular.woff2') format('woff2');
unicode-range: U+4E00-9FFF, U+3400-4DBF; /* CJK ideographs */
}
@font-face {
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/NotoSansTC-Regular.woff2') format('woff2');
unicode-range: U+4E00-9FFF, U+3400-4DBF;
}
Font Size Considerations
| Script | Base Size | Line Height | Why |
|---|---|---|---|
| Latin | 16px | 1.5 | Standard readability |
| Chinese | 16px | 1.7-1.8 | Complex characters need space |
| Vietnamese | 16px | 1.6 | Diacritics need vertical space |
Vietnamese Diacritic Handling
/* Prevent diacritic clipping */
[lang="vi"] {
line-height: 1.6;
overflow: visible;
}
[lang="vi"] h1, [lang="vi"] h2 {
line-height: 1.4;
padding-top: 0.1em; /* Extra space for ascending diacritics */
}
Text Expansion
Expansion Rates
| Language | Expansion vs English | Example |
|---|---|---|
| Spanish | +30-50% | "Rights" → "Derechos" |
| German | +35% | (Reference) |
| Chinese | -30-50% | Shorter but needs more height |
| Vietnamese | +10-20% | Moderate expansion |
UI Accommodations
| Component | Strategy |
|---|---|
| Buttons | Min-width, flexible height, icon support |
| Headers | Multi-line support, responsive sizing |
| Navigation | Overflow handling, hamburger for mobile |
| Cards | Flexible height, text truncation with expand |
| Chat bubbles | Dynamic sizing, max-width constraints |
CSS Implementation
/* Flexible button for text expansion */
.btn {
min-width: 120px;
padding: 12px 24px;
white-space: normal; /* Allow wrapping */
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
}
/* Card with flexible content */
.card {
display: flex;
flex-direction: column;
min-height: 200px;
}
.card__body {
flex: 1;
overflow-y: auto;
}
/* Chat message with expansion */
.chat-message {
max-width: 85%;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
}
Testing Protocol
| Test | Method |
|---|---|
| Pseudo-localization | Replace all strings with expanded versions |
| Real content test | Use actual translated content |
| Extreme case test | Use longest possible strings |
| Mobile breakpoint test | Test all responsive breakpoints |
Bilingual Displays
When to Use Side-by-Side
| Scenario | Recommendation |
|---|---|
| Legal terms with translations | Yes - parenthetical or tooltip |
| Full paragraphs | No - toggle instead |
| Official forms | Yes - if space permits |
| Mobile screens | No - toggle or tabs |
Toggle Pattern
<div class="bilingual-toggle">
<button class="bilingual-toggle__btn active" data-lang="es">Español</button>
<button class="bilingual-toggle__btn" data-lang="en">English</button>
</div>
<div class="bilingual-content">
<div class="bilingual-content__text" lang="es" data-lang="es">
Usted tiene el derecho de permanecer en silencio.
</div>
<div class="bilingual-content__text" lang="en" data-lang="en" hidden>
You have the right to remain silent.
</div>
</div>
Inline Term Translations
<p>
You may be eligible for
<span class="term" lang="en">asylum</span>
<span class="term-translation" lang="es">(asilo)</span>.
</p>
Input Methods
Supporting Chinese IME
| Consideration | Implementation |
|---|---|
| Composition state | Don't submit on partial input |
| Candidate display | Allow OS-native selection |
| Enter key behavior | Distinguish between selection and submit |
// Handle Chinese IME composition
input.addEventListener('compositionstart', () => {
isComposing = true;
});
input.addEventListener('compositionend', () => {
isComposing = false;
});
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !isComposing) {
submitMessage();
}
});
Vietnamese Keyboard Support
| Input Method | Support Level |
|---|---|
| TELEX | Standard OS support |
| VNI | Standard OS support |
| VIQR | ASCII fallback |
Testing: Ensure all diacritic combinations render correctly:
- ă, â, ê, ô, ơ, ư (vowels with diacritics)
- Combined tone + vowel marks (e.g., ắ, ầ, ễ)
Voice Input
| Language | Speech-to-Text | Notes |
|---|---|---|
| Spanish | Whisper, Google STT | Excellent support |
| Chinese | Whisper, iFlytek | Mandarin focused |
| Vietnamese | Whisper | Good accuracy |
// Voice input with language routing
const recognition = new webkitSpeechRecognition();
recognition.lang = userLanguage; // 'es', 'zh-CN', 'vi'
recognition.continuous = false;
recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript;
handleVoiceInput(transcript, userLanguage);
};
Accessibility
WCAG 2.1 AA Requirements
| Requirement | Multilingual Consideration |
|---|---|
| Color contrast | 4.5:1 minimum for all scripts |
| Text resize | Support up to 200% for dense scripts |
| Keyboard navigation | IME-compatible focus management |
| Screen readers | lang attribute on all content |
Language Attributes
<html lang="es">
<head>...</head>
<body>
<p>Información en español</p>
<!-- Inline language switch -->
<p>
Contact <span lang="en">Immigration Services</span> for help.
</p>
<!-- Quotation in different language -->
<blockquote lang="en">
"You have the right to remain silent."
</blockquote>
</body>
</html>
Screen Reader Testing
| Screen Reader | Languages | Notes |
|---|---|---|
| NVDA | All | Free, Windows |
| VoiceOver | All | macOS/iOS native |
| JAWS | All | Paid, Windows |
| TalkBack | All | Android native |
Trauma-Informed Design
Visual Calmness
| Element | Approach |
|---|---|
| Colors | Soft blues, greens; avoid red alerts |
| Typography | Clean, readable; avoid harsh fonts |
| Imagery | Welcoming; avoid law enforcement imagery |
| Animations | Subtle, optional; no sudden movements |
Language Tone
| Avoid | Use Instead |
|---|---|
| "Warning!" | "Important information" |
| "You must..." | "You have the option to..." |
| "Failure to..." | "If you choose not to..." |
| "Illegal" | "Undocumented" |
Progress & Certainty
| Pattern | Purpose |
|---|---|
| Progress indicators | Reduce anxiety about process |
| Clear next steps | Provide sense of control |
| Save progress | Prevent loss of work |
| Confirmation messages | Acknowledge user actions |
RTL Readiness
Future-Proofing for Arabic
| CSS Property | LTR | RTL |
|---|---|---|
text-align: start |
left | right |
margin-inline-start |
margin-left | margin-right |
padding-inline-end |
padding-right | padding-left |
/* RTL-ready CSS using logical properties */
.card {
margin-inline-start: 1rem;
padding-inline-end: 1rem;
text-align: start;
}
/* Direction-aware flexbox */
.nav {
display: flex;
flex-direction: row;
}
[dir="rtl"] .nav {
flex-direction: row-reverse;
}
Mobile-First Patterns
Smartphone Dominance
| Population | Primary Device |
|---|---|
| Many immigrant communities | Smartphone only |
| Low-income households | Single shared device |
| Recent arrivals | Mobile-first |
Mobile Optimizations
| Pattern | Implementation |
|---|---|
| Touch targets | Minimum 44x44px |
| One-handed use | Important actions in thumb zone |
| Offline support | Service worker for core content |
| Low bandwidth | Compressed images, lazy loading |
Chatbot Mobile UX
/* Mobile chat input */
.chat-input {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px;
background: white;
border-top: 1px solid #e0e0e0;
}
.chat-input__field {
width: 100%;
padding: 12px 16px;
font-size: 16px; /* Prevent iOS zoom */
border-radius: 24px;
}
Implementation Checklist
Phase 1: Foundation
- [ ] Implement endonym-based language selector
- [ ] Configure font loading for all scripts
- [ ] Set up language persistence (URL + localStorage)
- [ ] Add
langattributes throughout
Phase 2: Typography
- [ ] Load Noto Sans CJK for Chinese
- [ ] Configure Vietnamese line heights
- [ ] Test diacritic rendering
- [ ] Implement text expansion handling
Phase 3: Input
- [ ] Test Chinese IME compatibility
- [ ] Verify Vietnamese keyboard support
- [ ] Implement voice input option
- [ ] Configure mobile keyboard handling
Phase 4: Accessibility
- [ ] Verify color contrast for all languages
- [ ] Test screen reader pronunciation
- [ ] Validate keyboard navigation
- [ ] Run automated accessibility checks
Phase 5: Polish
- [ ] Apply trauma-informed design principles
- [ ] Test on actual mobile devices
- [ ] Validate offline functionality
- [ ] Community user testing
Next Steps
- Review language-specific guides for content considerations
- Understand community context for cultural adaptation
- Set up translation workflow for content sync
- Plan full implementation timeline