IntlPull
Guide
17 min read

Localisation UI : Gérer l'Expansion du Texte, les Langues RTL & le Design Responsif (2026)

Guide technique de la localisation UI pour développeurs. Corrigez le débordement de texte, supportez les langues RTL, gérez les limites de caractères et testez les interfaces multilingues.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Guide technique de la localisation UI pour développeurs. Corrigez le débordement de texte, supportez les langues RTL, gérez les limites de caractères et testez les interfaces multilingues.

Le Lancement Qui a Tout Cassé

Le lancement allemand était prévu pour 9h. À 8h55, quelqu'un a ouvert la version allemande.

Boutons coupés au milieu du mot. Navigation cassée. Formulaires illisibles. L'interface soigneusement conçue ressemblait à la peinture au doigt d'un tout-petit.

Que s'est-il passé ? L'anglais "Save" (4 carac.) est devenu l'allemand "Speichern" (10 carac.). L'UI n'était pas prête pour ça.

Ce guide vous apprend comment construire des UI qui fonctionnent dans n'importe quelle langue, du japonais compact à l'allemand verbeux en passant par l'arabe de droite à gauche.

Les Trois Problèmes Difficiles

1. Expansion du Texte (Le Problème Allemand)

Différentes langues prennent différentes quantités d'espace pour la même signification :

AnglaisAllemandExpansion
SaveSpeichern+150%
DeleteLöschen+75%
SettingsEinstellungen+120%
OKOK0%

Expansion moyenne par langue :

LangueExpansion vs Anglais
Allemand+30%
Français+15-20%
Espagnol+20-30%
Italien+15-20%
Portugais+15-25%
Russe+10-15%
Japonais-10% à -20% (plus compact)
Chinois-30% (très compact)
Arabe+20-25%

2. Mises en Page Droite-à-Gauche (RTL)

L'arabe, l'hébreu, le persan, l'ourdou se lisent de droite à gauche. Votre mise en page entière doit se retourner.

Ce qui change :

  • Navigation : Droite → Gauche
  • Alignement du texte : Par défaut à droite
  • Icônes : Miroir horizontalement
  • Fil d'Ariane : Ordre inverse
  • Formulaires : Étiquettes à droite
  • Barres de défilement : À gauche

Ce qui reste pareil :

  • Vidéos/images (ne pas refléter)
  • Numéros de téléphone, adresses
  • Logos (généralement)
  • Blocs de code

3. Limites de Caractères

Twitter autorise 280 caractères, pas octets.

Votre base de données varchar(50) pourrait contenir 50 octets, ce qui n'est que 16 caractères chinois.

Gérer l'Expansion du Texte

Stratégie 1 : Mises en Page Flexibles

❌ Mauvais : Largeurs fixes

CSS
.button {
  width: 80px; /* Casse en Allemand */
}

✅ Bon : Largeur auto avec remplissage

CSS
1.button {
2  padding: 0.5rem 1rem;
3  min-width: 80px; /* Empêche les boutons minuscules */
4  max-width: 200px; /* Empêche absurdement long */
5  white-space: nowrap; /* Ou autoriser le retour à la ligne */
6}

Stratégie 2 : Troncature avec Infobulles

TSX
1// Composant React
2function TruncatedText({ text, maxLength = 30 }) {
3  const isTruncated = text.length > maxLength;
4  const displayText = isTruncated
5    ? text.slice(0, maxLength) + '...'
6    : text;
7
8  return isTruncated ? (
9    <span title={text}>{displayText}</span>
10  ) : (
11    <span>{displayText}</span>
12  );
13}

Stratégie 3 : Typographie Responsive

CSS
1/* Réduire la taille de police pour le texte plus long */
2.button {
3  font-size: clamp(0.75rem, 2vw, 1rem);
4}

Stratégie 4 : Tester avec Pseudo-Localisation

Simuler l'expansion du texte avant de traduire :

JavaScript
1function pseudoLocalize(text) {
2  // Ajouter des crochets et des caractères supplémentaires pour simuler l'expansion
3  const expanded = text
4    .split('')
5    .map(char => {
6      // Remplacer par des versions accentuées
7      const map = {
8        'a': 'á', 'e': 'é', 'i': 'í', 'o': 'ó', 'u': 'ú',
9        'A': 'Á', 'E': 'É', 'I': 'Í', 'O': 'Ó', 'U': 'Ú'
10      };
11      return map[char] || char;
12    })
13    .join('');
14
15  // Ajouter 30% de longueur supplémentaire
16  const padding = 'x'.repeat(Math.ceil(text.length * 0.3));
17
18  return `[[${expanded}${padding}]]`;
19}

Si votre UI casse avec la pseudo-localisation, elle cassera avec de vraies langues.

Implémenter le Support RTL

Étape 1 : Détecter la Direction

JavaScript
1function getDirection(locale) {
2  const rtlLanguages = ['ar', 'he', 'fa', 'ur'];
3  const language = locale.split('-')[0];
4  return rtlLanguages.includes(language) ? 'rtl' : 'ltr';
5}
6
7// Définir sur l'élément HTML racine
8document.documentElement.dir = getDirection(currentLocale);
9document.documentElement.lang = currentLocale;

Étape 2 : Utiliser les Propriétés CSS Logiques

❌ Ancienne façon (directionnelle) :

CSS
1.sidebar {
2  float: left;
3  margin-right: 20px;
4  padding-left: 10px;
5  border-left: 1px solid #ccc;
6}

✅ Nouvelle façon (logique) :

CSS
1.sidebar {
2  float: inline-start; /* gauche en LTR, droite en RTL */
3  margin-inline-end: 20px;
4  padding-inline-start: 10px;
5  border-inline-start: 1px solid #ccc;
6}

Étape 3 : Miroir de Mise en Page

Flexbox :

CSS
1.nav {
2  display: flex;
3  /* Inverse automatiquement en RTL */
4}

Étape 4 : Gérer Images/Icônes

Ne pas tout refléter :

CSS
1/* Refléter les icônes qui indiquent la direction */
2.icon-arrow {
3  transform: scaleX(var(--rtl-mirror, 1));
4}
5
6html[dir="rtl"] {
7  --rtl-mirror: -1; /* Retourner horizontalement */
8}
9
10/* Ne pas refléter les logos, photos */
11.logo,
12.photo {
13  transform: scaleX(1) !important;
14}

Étape 5 : Tester la Mise en Page RTL

Astuce DevTools :

JavaScript
// Commande console pour tester RTL
document.documentElement.dir = 'rtl';

Gérer les Limites de Caractères

Problème : Contraintes de Base de Données

Solution 1 : Augmenter les limites

SQL
1-- ✅ Tenir compte des caractères multi-octets
2CREATE TABLE products (
3  name VARCHAR(200)  -- Marge de sécurité 4x
4);

Solution 2 : Utiliser les types TEXT

SQL
1-- ✅ Pas de limite de longueur
2CREATE TABLE products (
3  name TEXT
4);

Problème : Limites d'Affichage UI

Valider le nombre de caractères, pas le nombre d'octets :

TSX
1function validateInput(text, maxChars) {
2  // ✅ Compter les clusters de graphèmes (caractères perçus par l'utilisateur)
3  const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
4  const segments = Array.from(segmenter.segment(text));
5
6  return segments.length <= maxChars;
7}

Problème : Troncature

✅ Troncature intelligente :

JavaScript
1function smartTruncate(text, maxLength, locale = 'en') {
2  const segmenter = new Intl.Segmenter(locale, { granularity: 'word' });
3  const segments = Array.from(segmenter.segment(text));
4
5  if (segments.length <= maxLength) return text;
6
7  // Tronquer à la limite du mot, pas au milieu du mot
8  let truncated = '';
9  // ... logique
10  return truncated.trim() + '...';
11}

Design Multilingue Responsif

Défi : Même espace, différentes langues

Une barre de navigation qui convient à l'anglais pourrait déborder en Allemand.

Solution : Points de rupture responsifs par langue

CSS
1/* Allemand a besoin de plus d'espace */
2html[lang="de"] .nav {
3  gap: 0.5rem; /* Espacement plus serré */
4  font-size: 0.9rem; /* Légèrement plus petit */
5}
6
7/* Japonais peut être plus compact */
8html[lang="ja"] .nav {
9  gap: 1.5rem; /* Plus d'espace de respiration */
10}

Considérations Mobiles

Problème : Le mobile a encore moins d'espace.

TSX
1function MobileNav() {
2  const { t } = useTranslation('common');
3  const isMobile = useMediaQuery('(max-width: 768px)');
4
5  return (
6    <nav>
7      {isMobile ? (
8        // Utiliser des étiquettes plus courtes sur mobile
9        <>
10          <a href="/settings">{t('nav.settings_short')}</a>
11        </>
12      ) : (
13        <a href="/settings">{t('nav.settings')}</a>
14      )}
15    </nav>
16  );
17}

Stratégies de Test

1. Test de Régression Visuelle

JavaScript
1// Exemple Playwright
2locales.forEach(locale => {
3  test(`Homepage looks correct in ${locale}`, async ({ page }) => {
4    await page.goto(`/${locale}`);
5    await expect(page).toHaveScreenshot(`homepage-${locale}.png`);
6  });
7});

2. Détection de Débordement de Texte

JavaScript
1// Test automatisé pour débordement de texte
2function detectOverflow() {
3  const elements = document.querySelectorAll('button, .nav-item, .card-title');
4  // ... vérifier scrollWidth > clientWidth
5}

3. Vérification de Mise en Page RTL

JavaScript
1test('RTL layout is correct for Arabic', async ({ page }) => {
2  await page.goto('/ar');
3  const dir = await page.$eval('html', el => el.dir);
4  expect(dir).toBe('rtl');
5  // ... vérifier alignement texte
6});

4. Liste de Contrôle de Test Manuel

  • Tester toutes les langues sur mobile (espace restreint)
  • Tester les langues RTL (Arabe, Hébreu)
  • Tester les langues CJK (Chinois, Japonais, Coréen)
  • Tester la langue la plus longue (généralement Allemand)

Solutions Spécifiques au Framework

React

TSX
1// Fournisseur de direction
2function DirectionProvider({ locale, children }) {
3  const direction = getDirection(locale);
4  // ...
5  return (
6    <DirectionContext.Provider value={direction}>
7      {children}
8    </DirectionContext.Provider>
9  );
10}

Tailwind CSS

JavaScript
1// tailwind.config.js
2module.exports = {
3  plugins: [
4    require('@tailwindcss/rtl'),
5  ],
6};

Le Résumé

La localisation UI n'est pas juste de la traduction - c'est :

  1. Mises en page flexibles qui gèrent 30% d'expansion de texte
  2. Support RTL avec propriétés CSS logiques
  3. Limites de caractères comptées correctement
  4. Design responsif pour mobile + multilingue
  5. Tests avec pseudo-localisation

Gains rapides :

  • Remplacer tous les left/right par inline-start/inline-end
  • Utiliser min-width au lieu de width pour les boutons
  • Tester avec Arabe (RTL) et Allemand (expansion de texte)

Besoin d'aide avec la localisation UI ?

Essayez IntlPull - Fournit un contexte visuel aux traducteurs.

Tags
ui-localization
rtl
text-expansion
responsive-design
i18n
css
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.