Principes de design pour les ingénieurs logiciels
Fondamentaux du design pour les ingénieurs logiciels : typographie, couleur, espacement, animation, modèles d’interface IA, design tokens et 48 études de cas de produits actuels.
Mis à jour le 18 mai 2026
Mise à jour du 18 mai 2026 : actualisation de l’index des Études de design pour l’aligner sur le corpus actuel de 48 études, et enrichissement des patterns d’interfaces IA avec des preuves issues de workflows agentiques : checkpoints, états d’approbation, fiabilité des sources et vérification visible.
Mise à jour de mai 2026 : ajout d’une note sur le brouillon de travail de mars 2026 pour WCAG 3.0 et sur la position du W3C selon laquelle WCAG 2.2 et 3.0 coexisteront. WCAG 2.2 reste la norme à viser pour les travaux d’accessibilité actuels.
Mise à jour de février 2026 : ajout de deux nouvelles sections : Patterns d’interaction (8 paradigmes issus de l’étude de Framer, Flighty, Halide, Warp, Bear, Craft et Superhuman) et Patterns d’interfaces IA (design axé sur les citations, phases de streaming, transparence des erreurs à partir de Perplexity). Mise à jour des Web Patterns pour 2026 avec anchor positioning, animations pilotées par le défilement et @starting-style. Mise à jour de l’accessibilité pour refléter la normalisation ISO de WCAG 2.2. Consultez Études de design pour des analyses approfondies de 48 produits d’exception.
J’ai passé des années à étudier le design tout en développant des logiciels, à assimiler les principes de légendes comme Dieter Rams et à disséquer les interfaces de produits comme Linear, Stripe et Raycast. Ce guide condense cette compréhension en la référence complète que j’aurais aimé trouver lorsque j’ai commencé à m’intéresser à l’apparence et au ressenti de mes logiciels.
Le design n’est pas de la décoration. C’est de la communication. Chaque pixel communique une fonction, une hiérarchie et un sens. Ce qui distingue un logiciel qui donne une impression d’amateurisme d’un logiciel qui paraît professionnel, c’est la compréhension de ces principes et leur application cohérente.
Ce guide part du principe que vous savez déjà écrire du code. Il vous apprend à voir — à comprendre pourquoi certaines interfaces semblent évidentes tandis que d’autres paraissent chaotiques, et surtout, comment créer les premières.
Table des matières
Partie 1 : Fondations
- Psychologie de la Gestalt
- Typographie
- Théorie des couleurs
- Hiérarchie visuelle
- Espacement et rythme
- Principes d’animation
Partie 2 : Interaction et IA
Partie 3 : Philosophie du design
Partie 4 : Mise en œuvre
Partie 5 : Référence
Psychologie de la Gestalt
« Le tout est autre chose que la somme de ses parties. » — Kurt Koffka
La psychologie de la Gestalt, développée dans l’Allemagne des années 1920, explique comment les êtres humains perçoivent l’information visuelle. Le cerveau ne voit pas des pixels individuels — il organise les éléments en patterns signifiants. Maîtrisez ces principes pour contrôler la façon dont les utilisateurs perçoivent vos interfaces.
Proximité
Les éléments proches les uns des autres sont perçus comme un groupe.
C’est le principe de Gestalt le plus puissant en design UI. L’espace communique la relation entre les éléments plus que toute autre propriété visuelle.
INCORRECT (espacement égal = pas de regroupement) :
┌─────────────────┐
│ Label │
│ │
│ Input Field │
│ │
│ Label │
│ │
│ Input Field │
└─────────────────┘
CORRECT (espacement inégal = groupes distincts) :
┌─────────────────┐
│ Label │
│ Input Field │ ← Serré (4px) - éléments liés
│ │
│ │ ← Large (24px) - séparation des groupes
│ Label │
│ Input Field │ ← Serré (4px) - éléments liés
└─────────────────┘
Implémentation CSS :
.form-group {
margin-bottom: 24px; /* Between groups: wide */
}
.form-group label {
margin-bottom: 4px; /* Label to input: tight */
display: block;
}
Implémentation SwiftUI :
VStack(alignment: .leading, spacing: 4) { // Tight within group
Text("Email")
.font(.caption)
.foregroundStyle(.secondary)
TextField("you@example.com", text: $email)
.textFieldStyle(.roundedBorder)
}
.padding(.bottom, 24) // Wide between groups
Similarité
Les éléments partageant des caractéristiques visuelles semblent liés.
Lorsque des éléments se ressemblent, les utilisateurs supposent qu’ils ont la même fonction. C’est pourquoi les systèmes de design utilisent des styles cohérents pour les boutons, les cartes et la typographie.
Exemple de navigation :
┌───────────────────────────────────┐
│ [Dashboard] [Projects] [Settings] │ ← Même style = même fonction
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Card │ │Card │ │Card │ │ ← Même style = même type de contenu
│ └─────┘ └─────┘ └─────┘ │
│ │
│ [+ New Project] │ ← Style différent = fonction différente
└───────────────────────────────────┘
Figure-fond
Le contenu doit clairement se distinguer de l’arrière-plan.
Le cerveau a besoin de distinguer la « figure » (ce sur quoi se concentrer) du « fond » (l’arrière-plan). Une mauvaise relation figure-fond crée de la confusion visuelle.
Techniques : - Contraste (figure claire sur fond sombre, ou inversement) - Ombres (élever la figure au-dessus du fond) - Bordures (délimiter les contours de la figure) - Flou (flouter l’arrière-plan, affiner la figure)
/* Strong figure-ground relationship */
.card {
background: var(--color-surface); /* Figure */
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); /* Elevation */
}
.modal-overlay {
background: rgba(0, 0, 0, 0.5); /* Dim ground */
backdrop-filter: blur(4px); /* Blur ground */
}
Région commune
Les éléments à l’intérieur d’une limite sont perçus comme groupés.
Entourer des éléments dans un conteneur visuel (carte, boîte, zone bordée) signale qu’ils appartiennent au même ensemble.
Continuité
L’œil suit les chemins, les lignes et les courbes.
Utilisez l’alignement et le flux visuel pour guider l’attention à travers votre interface.
CONTINUITÉ DANS L'ALIGNEMENT :
┌────────────────────────────────┐
│ Logo [Nav] [Nav] [Nav] │ ← Alignés sur l'axe horizontal
├────────────────────────────────┤
│ │
│ Headline │
│ ───────────────────────────── │ ← L'œil suit le bord gauche
│ Paragraph text continues │
│ along the same left edge │
│ │
│ [Primary Action] │ ← Toujours sur le bord gauche
└────────────────────────────────┘
Clôture
Le cerveau complète les formes incomplètes.
Les utilisateurs n’ont pas besoin que chaque pixel soit dessiné — ils complètent mentalement les formes familières. Cela permet des designs plus minimalistes et élégants.
/* Horizontal scroll with partial card (closure) */
.card-carousel {
display: flex;
gap: 16px;
overflow-x: auto;
padding-right: 48px; /* Show partial card = scroll hint */
}
.card-carousel .card {
flex: 0 0 280px; /* Fixed width, partial visible */
}
Référence rapide Gestalt
| Principe | Règle | Utilisation principale |
|---|---|---|
| Proximité | Lié = proche, non lié = éloigné | Champs de formulaire, sections de contenu |
| Similarité | Même apparence = même fonction | Boutons, cartes, navigation |
| Figure-fond | Séparation claire des couches | Cartes, modales, overlays |
| Région commune | Les limites regroupent le contenu | Sections de paramètres, fiches utilisateur |
| Continuité | Suivre les lignes et l’alignement | Chronologies, flux de lecture |
| Clôture | Le cerveau complète les formes | Icônes, indices de défilement, squelettes |
Typographie
« La typographie est l’art de donner au langage humain une forme visuelle durable. » — Robert Bringhurst
La typographie est le socle du design d’interface. Le texte communique la fonctionnalité, la hiérarchie et l’identité de marque. Une typographie médiocre rend les interfaces plus difficiles à utiliser ; une typographie réussie est invisible — elle fonctionne, tout simplement.
Échelle typographique
Une échelle cohérente crée une harmonie visuelle. Utilisez un ratio mathématique.
L’échelle 1.25 (recommandée pour les UI) :
:root {
/* Base: 16px (1rem) */
--text-xs: 0.64rem; /* 10.24px - use sparingly */
--text-sm: 0.8rem; /* 12.8px - captions, labels */
--text-base: 1rem; /* 16px - body text */
--text-lg: 1.25rem; /* 20px - lead text */
--text-xl: 1.563rem; /* 25px - h4 */
--text-2xl: 1.953rem; /* 31.25px - h3 */
--text-3xl: 2.441rem; /* 39px - h2 */
--text-4xl: 3.052rem; /* 48.8px - h1 */
}
Hauteur de ligne (interligne)
La hauteur de ligne affecte considérablement la lisibilité. Différents types de contenu nécessitent des interlignes différents.
| Type de contenu | Hauteur de ligne | Pourquoi |
|---|---|---|
| Titres | 1.1 - 1.2 | Serré, gras, court |
| Texte UI | 1.3 - 1.4 | Labels, boutons |
| Corps de texte | 1.5 - 1.7 | Paragraphes lisibles |
| Texte long | 1.7 - 2.0 | Articles, documentation |
Longueur de ligne (mesure)
Une longueur de ligne optimale prévient la fatigue oculaire et améliore la compréhension en lecture.
- Optimale : 45-75 caractères par ligne
- Cible : 50-65 caractères
- Maximum absolu : 85 caractères
p {
max-width: 65ch; /* ch unit = width of '0' character */
}
.article-body {
max-width: 70ch;
margin: 0 auto;
}
Choix de la police
Les polices système en priorité. Elles se chargent instantanément, correspondent à la plateforme et sont optimisées pour les écrans.
:root {
--font-sans: system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-mono: ui-monospace, 'SF Mono', 'Cascadia Code',
'JetBrains Mono', Consolas, monospace;
}
Utilisez des polices personnalisées pour : - La différenciation de marque (sites marketing) - Un rendu éditorial ou de publication - Une intention de design spécifique impossible à obtenir avec les polices système
Graisse de police pour la hiérarchie
Utilisez la graisse pour établir la hiérarchie, pas uniquement la taille.
h1 { font-weight: 700; } /* Bold */
h2 { font-weight: 600; } /* Semibold */
h3 { font-weight: 600; } /* Semibold */
.lead { font-weight: 500; } /* Medium */
p { font-weight: 400; } /* Regular */
.meta { font-weight: 400; color: var(--text-muted); }
Référence rapide typographique
| Propriété | Corps de texte | Titres | Labels UI |
|---|---|---|---|
| Taille | 16-18px | 24-48px | 12-14px |
| Graisse | 400 | 600-700 | 500 |
| Hauteur de ligne | 1.5-1.7 | 1.1-1.2 | 1.3-1.4 |
| Longueur de ligne | 45-75ch | N/A | N/A |
| Alignement | Gauche | Centre possible | Gauche |
Théorie des couleurs
« La couleur est une puissance qui influence directement l’âme. » — Wassily Kandinsky
Les couleurs communiquent plus vite que les mots. Elles installent une ambiance, guident l’attention, signalent le sens et renforcent la reconnaissance de marque.
La règle 60-30-10
La répartition des couleurs la plus fiable pour des interfaces équilibrées.
┌──────────────────────────────────────────┐
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ 60% - Dominant (Background)
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 30% - Secondary (Cards, sections)
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 10% - Accent (Buttons, links)
└──────────────────────────────────────────┘
Construire une palette de couleurs
Toute interface a besoin des couleurs sémantiques suivantes :
:root {
/* Brand */
--color-primary: hsl(220, 80%, 50%);
--color-primary-hover: hsl(220, 80%, 45%);
/* Semantic */
--color-success: hsl(142, 76%, 36%); /* Green - positive */
--color-warning: hsl(38, 92%, 50%); /* Amber - caution */
--color-error: hsl(0, 84%, 60%); /* Red - danger */
/* Neutrals */
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(220, 14%, 96%);
--color-border: hsl(220, 13%, 91%);
/* Text */
--color-text: hsl(220, 13%, 13%);
--color-text-secondary: hsl(220, 9%, 46%);
--color-text-muted: hsl(220, 9%, 64%);
}
Psychologie des couleurs
| Couleur | Psychologie | Utilisation UI |
|---|---|---|
| Bleu | Confiance, stabilité, calme | Finance, tech, entreprises |
| Vert | Croissance, nature, réussite | Santé, écologie, états positifs |
| Rouge | Énergie, urgence, danger | Alertes, ventes, erreurs |
| Orange | Chaleur, enthousiasme | CTA, marques ludiques |
| Jaune | Optimisme, prudence | Avertissements, mises en évidence |
| Violet | Luxe, créativité | Produits premium |
| ### Design pensé d’abord pour le mode sombre (Vercel) | ||
| Vercel conçoit d’abord pour le mode sombre, puis en déduit le mode clair. Cela produit de meilleures interfaces sombres, car le mode sombre devient la considération principale plutôt qu’une réflexion après coup. |
/* Design dark first, derive light */
:root {
/* Dark mode defaults */
--color-background: hsl(0, 0%, 0%);
--color-surface: hsl(0, 0%, 7%);
--color-border: hsl(0, 0%, 15%);
--color-text: hsl(0, 0%, 93%);
--color-text-secondary: hsl(0, 0%, 63%);
}
@media (prefers-color-scheme: light) {
:root {
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(0, 0%, 97%);
--color-border: hsl(0, 0%, 89%);
--color-text: hsl(0, 0%, 9%);
--color-text-secondary: hsl(0, 0%, 40%);
}
}
Quand l’utiliser : Outils de développement, applications multimédias, tableaux de bord, dans les contextes où les utilisateurs restent longtemps et où le mode sombre réduit la fatigue visuelle.
Contraste d’accessibilité
| Niveau | Texte normal | Texte de grande taille | Composants UI |
|---|---|---|---|
| AA | 4,5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4,5:1 | N/A |
| WCAG 2.2 est devenu une norme ISO (ISO/IEC 40500:2025) en octobre 2025, avec l’ajout de critères portant sur la visibilité du focus, la saisie redondante et l’authentification accessible. Ajouts clés : les indicateurs de focus ne doivent pas être entièrement masqués par d’autres contenus (2.4.11), et l’authentification ne doit pas reposer uniquement sur des tests de fonction cognitive (3.3.8). Le W3C a publié une version mise à jour de WCAG 2.2 en décembre 2024, qui devrait être publiée comme ISO/IEC 40500:2026 d’ici fin 2026. |
WCAG 3.0 est encore un brouillon de travail. La dernière révision a été publiée en mars 2026 et ne remplace pas WCAG 2.2 ; le W3C indique que les deux standards coexisteront. L’Accessibility Guidelines Working Group prévoit de publier en 2026 un calendrier prévisionnel pour WCAG 3, mais WCAG 2.2 reste le standard à viser pour les travaux actuels.
Outils : WebAIM Contrast Checker, sélecteur de couleurs de Chrome DevTools
Hiérarchie visuelle
« Le design est l’ambassadeur silencieux de votre marque. » — Paul Rand
La hiérarchie visuelle contrôle ce que les utilisateurs voient en premier, en deuxième et en troisième. Sans hiérarchie claire, les utilisateurs doivent faire un effort pour trouver l’information. Avec elle, les interfaces paraissent naturelles.
Les six outils de la hiérarchie
1. Taille — Les éléments plus grands attirent l’attention en premier
.hero-title { font-size: 3rem; } /* Dominant */
.section-title { font-size: 1.5rem; } /* Secondary */
.body-text { font-size: 1rem; } /* Baseline */
2. Graisse — Le gras se détache, le léger s’efface
h1 { font-weight: 700; }
.lead { font-weight: 500; }
p { font-weight: 400; }
3. Couleur et contraste — Un contraste élevé = attention
.title { color: var(--color-text); } /* Near black */
.meta { color: var(--color-text-muted); } /* Gray */
4. Position — Les positions clés comptent
F-PATTERN (content pages): Z-PATTERN (landing pages):
████████████████████████ 1 ──────────────────► 2
████████ ↘
████ ↘
██ ↘
3 ──────────────────► 4
5. Espaces vides — L’isolement crée de l’importance
.hero { padding: 120px 48px; } /* Generous space */
.data-table { padding: 12px; } /* Dense content */
6. Profondeur et élévation — Les éléments qui se détachent vers l’avant exigent l’attention
:root {
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}
.card { box-shadow: var(--shadow-sm); }
.card:hover { box-shadow: var(--shadow-md); }
.modal { box-shadow: var(--shadow-lg); }
Motifs appliqués
Présence collaborative (Figma) : Plusieurs curseurs d’utilisateurs accompagnés d’étiquettes de nom, de surlignages de sélection et de contours de composants créent un document vivant. La couleur de chaque collaborateur est distincte mais de poids équivalent : aucun curseur n’est « plus voyant » qu’un autre.
Indicateurs d’état discrets (Vercel) : Le statut de déploiement s’appuie sur des indicateurs subtils et persistants plutôt que sur des alertes intrusives. Une fine barre de couleur en haut communique l’état (build en cours, déployé, échoué) sans interrompre le flux de travail.
Analogies de design ancrées dans le réel (Flighty) : Les visualisations de progression de vol reflètent les instruments d’aviation physiques : courbes d’altitude, indicateurs de vitesse et plans de porte d’embarquement utilisent des métaphores visuelles familières plutôt que des barres de progression abstraites.
Le test du plissement des yeux
Plissez les yeux devant votre design. Pouvez-vous encore percevoir la hiérarchie ? Si oui, elle est solide.
Espacement et rythme
« L’espace blanc est comme l’air : il est nécessaire pour que le design respire. » — Wojciech Zieliński
L’espacement est la structure invisible du design. Un espacement cohérent crée un rythme visuel : cette impression que les éléments appartiennent au même système cohérent.
La grille de 8 px
La grille de 8 px est le standard du secteur, car : - Elle se divise régulièrement (8, 16, 24, 32, 40, 48…) - Elle fonctionne avec les densités d’écran courantes (1x, 1.5x, 2x, 3x) - Elle crée un rythme cohérent sans calcul
:root {
--space-1: 4px; /* Tight: icon gaps */
--space-2: 8px; /* Compact: inline elements */
--space-3: 12px; /* Snug: form fields */
--space-4: 16px; /* Default: most gaps */
--space-6: 24px; /* Spacious: card padding */
--space-8: 32px; /* Section gaps */
--space-12: 48px; /* Major sections */
--space-16: 64px; /* Page sections */
--space-20: 80px; /* Hero spacing */
}
Espacement interne vs espacement externe
Interne (padding) : espace à l’intérieur d’un élément Externe (margin) : espace entre les éléments
Règle : l’espacement interne doit généralement être plus important que l’espacement externe au sein de groupes liés.
.card {
padding: 24px; /* Internal: spacious */
margin-bottom: 16px; /* External: less than padding */
}
Schémas d’espacement des composants
Cartes :
.card { padding: 24px; border-radius: 12px; }
.card-header { margin-bottom: 16px; }
.card-title { margin-bottom: 4px; } /* Tight to subtitle */
Boutons :
.btn { padding: 12px 24px; border-radius: 8px; }
.btn--sm { padding: 8px 16px; }
.btn--lg { padding: 16px 32px; }
.btn-group { display: flex; gap: 12px; }
Formulaires :
.form-row { margin-bottom: 24px; }
.form-label { margin-bottom: 4px; }
.form-help { margin-top: 4px; }
.form-actions { margin-top: 32px; display: flex; gap: 12px; }
Aide-mémoire sur l’espacement
| Contexte | Espacement recommandé |
|---|---|
| De l’icône au texte | 4 à 8px |
| Du libellé au champ | 4px |
| Entre groupes de formulaire | 24px |
| Marge interne de carte | 20 à 24px |
| Écart entre cartes | 16 à 24px |
| Marge interne de section (mobile) | 48 à 64px |
| Marge interne de section (desktop) | 80 à 96px |
| Marge interne du bouton (h/v) | 24px / 12px |
| — |
Principes d’animation
« Animation is not the art of drawings that move but the art of movements that are drawn. » — Norman McLaren
L’animation donne vie aux interfaces. Bien exécutée, elle guide l’attention, communique l’état et crée une connexion émotionnelle. Mal exécutée, elle frustre et distrait.
Le principe fondamental
L’animation doit sembler inévitable, jamais décorative.
Une bonne animation : 1. Communique quelque chose que le design statique ne peut pas transmettre 2. Réduit la charge cognitive en montrant les relations 3. Paraît naturelle et attendue 4. Disparaît de la conscience
Une mauvaise animation : 1. N’existe que parce que « ça fait joli » 2. Ralentit l’utilisateur 3. Attire l’attention sur elle-même 4. Crée de l’anxiété ou de l’impatience
Principes clés pour les interfaces
1. Anticipation — Préparez les utilisateurs à ce qui va suivre.
.button {
transition: transform 0.1s ease-out;
}
.button:active {
transform: scale(0.97); /* Slight press before action */
}
2. Suivi du mouvement — Laissez le mouvement s’achever naturellement avec un effet de ressort.
.panel {
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) {
isOpen = true
}
3. Ease-In, Ease-Out — Rien dans la nature ne se déplace à vitesse constante.
| Courbe | Quand l’utiliser | Caractère |
|---|---|---|
ease-out |
Éléments entrants | Démarrage rapide, arrêt en douceur |
ease-in |
Éléments sortants | Démarrage en douceur, sortie rapide |
ease-in-out |
Changements d’état | Fluide de bout en bout |
linear |
Indicateurs de chargement | Continu, mécanique |
4. Mise en scène — Dirigez l’attention vers ce qui compte. Un seul élément doit bouger à la fois, sauf s’il s’agit d’une chorégraphie de groupe.
5. Échelonnement — Les éléments doivent apparaître en séquence, pas tous en même temps.
.list-item {
animation: fadeSlideIn 0.3s ease-out both;
}
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
.list-item:nth-child(4) { animation-delay: 150ms; }
@keyframes fadeSlideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
Repères de durée
| Durée | Cas d’usage | Ressenti |
|---|---|---|
| 50-100ms | Micro-interactions (survol, pression) | Retour instantané |
| 150-200ms | Changements d’état simples (bascule, sélection) | Vif |
| 250-350ms | Transitions moyennes (glissement de panneau, retournement de carte) | Fluide |
| 400-500ms | Grands mouvements (transitions de page, modales) | Délibéré |
Performance : la règle d’or
N’animez que transform et opacity — ces propriétés sont accélérées par le GPU et ne déclenchent pas de recalcul de mise en page.
/* BAD: Animating layout */
.panel { transition: left 0.3s, width 0.3s; }
/* GOOD: Using transform */
.panel { transition: transform 0.3s; }
Quand NE PAS animer
-
L’utilisateur a activé
prefers-reduced-motioncss @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } -
L’animation n’apporte aucune information — spinners gratuits, éléments qui rebondissent
- L’utilisateur est pressé — états d’erreur, validation de formulaire, résultats de recherche
- L’animation ralentirait des actions répétées — les raccourcis clavier doivent contourner l’animation
- Les données sont déjà chargées — Bear utilise zéro état de chargement en préchargeant le contenu, ce qui rend l’application instantanée. Si vous pouvez précharger, supprimez entièrement le skeleton/spinner.
// Bear's approach: preload so no loading state is needed
struct NoteListView: View {
@Query var notes: [Note] // SwiftData loads from disk instantly
// No loading state, no skeleton, no spinner — data is always there
var body: some View {
List(notes) { note in
NoteRow(note: note)
}
}
}
Référence rapide pour l’animation
:root {
/* Durations */
--duration-instant: 0.1s;
--duration-fast: 0.15s;
--duration-normal: 0.25s;
--duration-slow: 0.4s;
/* Easings */
--ease-out: cubic-bezier(0.0, 0.0, 0.58, 1.0);
--ease-in: cubic-bezier(0.42, 0.0, 1.0, 1.0);
--ease-in-out: cubic-bezier(0.42, 0.0, 0.58, 1.0);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
}
Modèles d’interaction
« The best interface is no interface. » — Golden Krishna
Les modèles d’interaction définissent comment les utilisateurs manipulent, naviguent et comprennent votre produit. Ces modèles sont extraits de l’étude de produits qui offrent des interactions exceptionnelles.
Manipulation directe (Framer)
Rendez les concepts abstraits tangibles. Framer transforme les breakpoints CSS — des nombres abstraits — en poignées glissables. Les utilisateurs voient les mises en page s’adapter en temps réel.
/* Breakpoint handle styling */
.breakpoint-handle {
position: absolute;
top: 0;
bottom: 0;
width: 4px;
background: var(--accent);
cursor: col-resize;
opacity: 0.6;
transition: opacity 0.15s ease;
}
.breakpoint-handle:hover,
.breakpoint-handle:active {
opacity: 1;
width: 6px;
}
Quand l’utiliser : pour tout paramètre dont le résultat est visuel — redimensionnement par glisser, sélecteurs de couleur, défilement de timeline.
Interfaces contextuelles (Flighty, Figma)
N’affichez que ce qui est pertinent à l’instant présent. Flighty utilise 15 états distincts pour le suivi de vol. Le panneau de propriétés de Figma se transforme entièrement selon ce que vous avez sélectionné.
| Phase (Flighty) | Ce que voient les utilisateurs |
|---|---|
| 24 h avant | Code de confirmation, infos terminal |
| À l’aéroport | Numéro de porte, heure d’embarquement |
| En vol | Temps restant, progression, heure d’arrivée estimée |
| Atterrissage | Portes de correspondance, itinéraire à pied |
enum ContextState: CaseIterable {
case farOut, dayBefore, headToAirport, atAirport
case atGate, boarding, inFlight, landed, connection
static func current(for flight: Flight, context: UserContext) -> ContextState {
// Factor in: time, location, flight status
// Return the single most relevant state
}
}
Anti-pattern : afficher tous les contrôles et griser ceux qui ne sont pas pertinents. Cela crée du bruit visuel.
Activation intelligente (Halide)
Les outils doivent détecter le contexte et s’activer d’eux-mêmes. La loupe de mise au point de Halide apparaît lorsqu’on glisse pour faire la mise au point et disparaît au relâchement. Aucun bouton à basculer.
struct IntelligentlyActivated<Content: View>: ViewModifier {
let isInteracting: Bool
@State private var isVisible = false
func body(content: Content) -> some View {
content
.opacity(isVisible ? 1 : 0)
.scaleEffect(isVisible ? 1 : 0.95)
.animation(.easeInOut(duration: 0.2), value: isVisible)
.onChange(of: isInteracting) { _, newValue in
if newValue {
withAnimation { isVisible = true }
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
if !isInteracting { isVisible = false }
}
}
}
}
}
Conception bimodale (Halide, Warp)
Les changements de mode doivent transformer l’interface, pas simplement basculer des éléments. Les modes Auto et Manuel de Halide sont deux interfaces complètement différentes. Warp fait le pont entre CLI et GUI grâce à quatre méthodes de saisie (frappe, palette, IA, souris) sans imposer un seul paradigme aux utilisateurs.
Contenu structuré (Warp, Bear, Craft)
Ajoutez de la structure à un contenu traditionnellement non structuré. Warp transforme la sortie terminal en blocs distincts que l’on peut copier, partager ou relancer. Bear permet d’organiser les notes en ligne pendant l’écriture (#tag/subtag). Craft permet à n’importe quel bloc de devenir une page — la structure émerge de l’usage, pas d’une hiérarchie prédéfinie.
Formation progressive (Superhuman)
Enseignez la méthode rapide par l’exposition répétée. La palette Cmd+K de Superhuman affiche systématiquement les raccourcis clavier à côté des résultats. Chaque utilisation est une micro-leçon.
/* Always show shortcut alongside command name */
.command-result {
display: flex;
justify-content: space-between;
padding: 8px 12px;
}
.command-shortcut {
font-family: var(--font-mono);
font-size: 12px;
color: var(--text-muted);
background: var(--bg-subtle);
padding: 2px 6px;
border-radius: 4px;
}
Anti-pattern : les modales de tutoriel qui expliquent les fonctionnalités. L’explication s’oublie ; la pratique se retient.
Modèles d’interface IA
« Les meilleures interfaces IA rendent le processus de la machine visible et ses résultats vérifiables. »
Les interfaces IA présentent des défis particuliers : les utilisateurs ne peuvent ni prévoir les résultats, ni en vérifier l’exactitude d’un simple coup d’œil, et peinent souvent à déterminer si le système fonctionne correctement ou non.
Le problème fondamental
| Logiciels traditionnels | Logiciels d’IA |
|---|---|
| Les résultats sont prévisibles | Les résultats varient |
| Les erreurs sont évidentes | Les erreurs semblent plausibles |
| Les utilisateurs vérifient en testant | Les utilisateurs vérifient les sources |
| Chargement = attente | Chargement = travail en cours (montrez-le) |
| Confiance par défaut | La confiance doit se mériter |
Conception axée sur les citations (Perplexity)
Chaque affirmation factuelle doit renvoyer à sa source. Perplexity intègre des citations [1] directement dans chaque affirmation, avec des aperçus au survol et un panneau des sources toujours accessible.
.citation-marker {
position: relative;
color: var(--accent);
cursor: pointer;
font-size: 0.8em;
vertical-align: super;
}
.citation-preview {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
width: 280px;
padding: 12px;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
Anti-pattern : les interfaces IA qui génèrent des affirmations sans sources traçables. Si le modèle ne peut pas citer de source, l’interface doit le signaler.
Indicateurs des phases de génération en continu (Perplexity)
Montrez aux utilisateurs ce que fait l’IA, et pas seulement qu’elle travaille. Remplacez les indicateurs de chargement génériques par des indications de phase : « Recherche en cours… » → « Lecture de 4 sources… » → « Rédaction de la réponse… »
.phase-indicator {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
background: color-mix(in srgb, var(--phase-color) 10%, transparent);
border-radius: 16px;
font-size: 13px;
color: var(--phase-color);
transition: all 0.3s ease;
}
.loading-dots span {
width: 4px;
height: 4px;
background: currentColor;
border-radius: 50%;
animation: pulse 1.4s ease-in-out infinite;
}
Transparence des erreurs
Lorsque l’IA échoue ou exprime une incertitude, indiquez-le clairement : ne le dissimulez pas derrière un texte au ton assuré.
| Situation | Mauvais modèle | Bon modèle |
|---|---|---|
| Faible niveau de confiance | Présenter l’information avec assurance | « Je n’en suis pas certain, mais… » avec une mise en forme plus discrète |
| Aucune source trouvée | Inventer du contenu | « Je n’ai trouvé aucune source étayant cette affirmation » |
| Sources contradictoires | En choisir une sans le signaler | Présenter les deux en mettant le conflit en évidence |
| Informations obsolètes | Les présenter comme actuelles | « En date du [date]… » avec un indicateur de récence |
Idée clé : les utilisateurs pardonnent à une IA qui reconnaît honnêtement son incertitude. Ils ne pardonnent pas à une IA qui se trompe avec assurance.
Preuves du workflow agentique
Les agents IA ont besoin d’états d’interface qui prouvent le travail accompli, plutôt que de simplement décrire les efforts fournis. Un bon workflow agentique rend la progression lisible grâce à des points de contrôle : plan accepté, sources rassemblées, modifications appliquées, tests exécutés, révision en attente et publication bloquée ou prête.
| État de l’agent | Modèle d’interface | Pourquoi est-ce important ? |
|---|---|---|
| Planification | Objectif et critères d’acceptation explicites | Empêche l’agent d’optimiser l’activité plutôt que le résultat |
| Exploration | Liste des sources avec niveau de confiance et récence | Permet aux utilisateurs de distinguer les faits vérifiés des hypothèses de travail |
| Exécution | Résumé des fichiers modifiés associé aux points de contrôle | Permet de vérifier les modifications sans lire toute la transcription |
| Vérification | Preuve issue d’un test, d’une route, d’une capture d’écran ou de l’exécution | Distingue les preuves d’une confiance artificielle |
| Publication | État de l’approbation, du déploiement ou de la révision native | Évite qu’une publication masque un travail inachevé derrière des vérifications locales réussies |
Anti-pattern : un unique état « Terminé » pour le travail d’un agent comportant plusieurs étapes. Un travail complexe exige une chaîne de responsabilité visible : ce qui a changé, ce qui l’a validé, ce qui a été écarté et ce qui nécessite encore un jugement humain.
Dieter Rams : dix principes
« Moins, mais mieux. » — Dieter Rams
Dieter Rams est le designer industriel le plus influent du XXe siècle. Directeur du design chez Braun de 1961 à 1995, il a créé des produits qui restent intemporels plusieurs décennies plus tard. Son travail a directement inspiré le langage visuel d’Apple.
Les dix principes d’un bon design
1. Un bon design est innovant Ne copiez pas. Associez les avancées technologiques à un design innovant.
2. Un bon design rend un produit utile Chaque élément doit avoir une fonction. La forme suit la fonction.
3. Un bon design est esthétique La beauté n’est pas superficielle : elle est essentielle. Les produits que nous utilisons au quotidien influencent notre bien-être.
4. Un bon design rend un produit compréhensible Les utilisateurs ne devraient pas avoir besoin d’instructions. L’interface s’explique d’elle-même.
5. Un bon design est discret Le design doit soutenir le contenu, sans l’écraser. Le contenu de l’utilisateur tient le premier rôle, pas votre UI.
/* Obtrusive: UI competes with content */
.editor {
background: linear-gradient(135deg, purple, blue);
border: 3px dashed gold;
}
/* Unobtrusive: UI recedes, content shines */
.editor {
background: var(--color-background);
border: 1px solid var(--color-border);
}
6. Un bon design est honnête N’utilisez pas de dark patterns. Ne faites pas de promesses excessives. Présentez les limites en toute transparence.
7. Un bon design est durable Évitez les tendances qui vieilliront rapidement. Préférez l’intemporel à l’éphémère.
TRENDY (will date): TIMELESS:
- Extreme glassmorphism - Clean typography
- Neon colors, glitch effects - Subtle elevation
- Aggressive gradients - Neutral palette with considered accent
8. Un bon design est abouti jusque dans les moindres détails Rien ne doit être arbitraire. États de chargement, états vides, états d’erreur : tout doit être conçu.
9. Un bon design est respectueux de l’environnement La performance a une dimension environnementale. Respectez l’attention de l’utilisateur. Écrivez du code efficace.
10. Un bon design se limite à l’essentiel Supprimez tout ce qui n’est pas nécessaire. Le meilleur design est invisible.
Patterns web 2026
Le CSS natif remplace désormais JavaScript pour un nombre croissant de problèmes de mise en page et d’interaction. Les années 2025-2026 ont vu arriver le positionnement par ancrage, les animations pilotées par le défilement et @starting-style dans les navigateurs destinés à la production, tandis que mi-2026 ont été ajoutés le dimensionnement automatique des contrôles de formulaire, les décorations d’espacement et l’ajustement automatique du texte.
Ici, l’état de la prise en charge compte davantage que la nouveauté. Une fonctionnalité disponible dans un seul moteur constitue une amélioration progressive ; une fonctionnalité classée Baseline Newly available peut servir de base en toute sécurité. Le tableau ci-dessous distingue les deux catégories en août 2026.
| Fonctionnalité | Chrome | Firefox | Safari | État |
|---|---|---|---|---|
field-sizing |
123 | 152 | 26.2 | Baseline Newly available |
shape-outside: rect() / xywh() |
149 | 149 | 17.2 | Baseline Newly available |
background-clip: border-area |
150 | — | 18.2 | Deux moteurs |
Décorations d’espacement (column-rule dans grid/flex) |
149 | — | — | Chrome uniquement |
text-fit |
150 | — | — | Chrome uniquement |
focusgroup |
150 | — | — | Chrome uniquement |
Sources : Nouveautés de la plateforme web en juin et juillet, web.dev.
Requêtes de conteneur
Dimensionnez les composants en fonction de leur conteneur, et non de la fenêtre d’affichage.
.card-grid {
container-type: inline-size;
container-name: card-grid;
}
.card {
display: grid;
gap: 16px;
padding: 20px;
}
@container card-grid (min-width: 400px) {
.card {
grid-template-columns: auto 1fr;
}
}
@container card-grid (min-width: 600px) {
.card {
padding: 32px;
gap: 24px;
}
}
Le sélecteur :has()
Sélection du parent en fonction de ses enfants — auparavant impossible sans JavaScript.
/* Card with image gets different padding */
.card:has(img) {
padding: 0;
}
.card:has(img) .card-content {
padding: 20px;
}
/* Form group with error */
.form-group:has(.input:invalid) .form-label {
color: var(--color-error);
}
/* Highlight navigation when on that page */
.nav-item:has(a[aria-current="page"]) {
background: var(--color-surface);
}
Imbrication en CSS
Imbrication native sans préprocesseur.
.card {
background: var(--color-surface);
border-radius: 12px;
padding: 24px;
& .card-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
}
& .card-body {
color: var(--color-text-secondary);
line-height: 1.6;
}
&:hover {
box-shadow: var(--shadow-md);
}
@media (min-width: 768px) {
padding: 32px;
}
}
Décorations d’espacement
Les espacements des grilles et des conteneurs flex peuvent avoir leurs propres traits, si bien que les séparateurs ne nécessitent plus de pseudo-éléments, de bordures sur chaque enfant ni d’élément englobant pour chaque colonne. Cette fonctionnalité est réservée à Chrome 149 et versions ultérieures, ce qui en fait une amélioration progressive plutôt qu’une fondation.
.pricing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 32px;
/* Vertical rules between columns, horizontal between rows */
column-rule: 1px solid var(--color-border);
row-rule: 1px solid var(--color-border);
}
L’ancienne approche appliquait un border-left à chaque élément sauf au premier, mais elle cessait de fonctionner dès que la grille revenait à la ligne. Les décorations d’espacement dessinent le trait dans l’espace lui-même, de sorte que les retours à la ligne restent corrects.
La prise en charge étant limitée à un seul moteur, considérez ces traits comme purement décoratifs et ne leur confiez jamais la séparation sémantique du contenu. Une mise en page qui devient ambiguë sans eux échoue dans Firefox et Safari.
Contrôles de formulaire adaptés à leur contenu
field-sizing: content permet aux champs de saisie, aux zones de texte et aux listes de sélection de s’agrandir ou de rétrécir selon la saisie de l’utilisateur, remplaçant ainsi le JavaScript fondé sur la hauteur de défilement que chaque base de code finit par réimplémenter.
.comment-box {
field-sizing: content;
min-height: 3lh; /* floor: three lines */
max-height: 12lh; /* ceiling: then scroll */
}
.tag-input {
field-sizing: content;
min-width: 8ch;
}
Associez-le toujours à des limites min-/max-. Sans limite inférieure, un champ vide se réduit presque entièrement ; sans limite supérieure, un long contenu collé repousse le bouton d’envoi hors de l’écran.
Cette fonctionnalité a obtenu le statut Baseline Newly available en juin 2026 : elle peut donc servir de mécanisme principal plutôt que de simple amélioration.
Texte adapté à son cadre
text-fit ajuste la taille de la police pour remplir la largeur de son conteneur, notamment pour les grands titres et les chiffres imposants des tableaux de bord qui nécessitaient auparavant un script de mesure.
.stat-value {
text-fit: consistent; /* one size for the whole box */
}
Chrome 150 uniquement. Définissez d’abord un font-size normal afin que les autres moteurs utilisent une taille choisie plutôt qu’une valeur par défaut :
.stat-value {
font-size: clamp(2rem, 8vw, 6rem); /* the real answer everywhere */
text-fit: consistent; /* refinement where supported */
}
clamp() répond déjà à la plupart des besoins pour lesquels cette fonctionnalité pourrait sembler utile, et sa prise en charge est universelle. Utilisez text-fit lorsque la longueur du contenu varie au point qu’aucune valeur clamp unique ne convient.
Bordures en dégradé sans bricolage
background-clip: border-area peint un arrière-plan dans la boîte de bordure, réduisant ainsi les bordures en dégradé à une règle de deux lignes, sans élément imbriqué ni astuce reposant sur mask-composite.
.featured-card {
border: 2px solid transparent;
border-radius: 12px;
background:
linear-gradient(var(--color-surface), var(--color-surface)) padding-box,
linear-gradient(135deg, #6366f1, #ec4899) border-area;
}
Chrome 150 et Safari 18.2 ; Firefox ne prend pas encore cette fonctionnalité en charge. Déclarez d’abord un border-color uni afin que la solution de repli affiche une véritable bordure plutôt qu’une bordure transparente.
Navigation avec les touches fléchées sans gestionnaire keydown
L’attribut focusgroup indique au navigateur qu’un ensemble de contrôles forme une seule unité de navigation au clavier : Tab permet d’entrer une seule fois dans le groupe, les touches fléchées permettent de s’y déplacer et Tab permet d’en sortir. Les barres d’outils, les barres d’onglets, les contrôles segmentés et les groupes de boutons de type radio nécessitent tous ce comportement, qui est aussi celui que les composants développés sur mesure implémentent le plus souvent de manière incorrecte.
<div role="toolbar" focusgroup="wrap">
<button>Bold</button>
<button>Italic</button>
<button>Underline</button>
</div>
wrap fait revenir la flèche du dernier élément au premier. Par défaut, la navigation s’arrête aux extrémités.
Chrome 150 uniquement : conservez donc le gestionnaire keydown existant jusqu’à ce que la prise en charge s’élargisse. Cet attribut mérite néanmoins d’être connu dès maintenant, car il désigne précisément le comportement accessible attendu : une barre d’outils doit constituer un seul arrêt de tabulation, et non cinq, une attente qui précède l’attribut de plusieurs décennies. Les pratiques de création ARIA décrivent ce pattern, quelle que soit la manière dont il est implémenté.
Intégration de HTMX
Interactivité pilotée par le serveur sans frameworks JavaScript lourds.
<!-- Load content on click -->
<button hx-get="/api/more-items"
hx-target="#item-list"
hx-swap="beforeend"
hx-indicator="#loading">
Load More
</button>
<!-- Form with inline validation -->
<form hx-post="/api/contact"
hx-target="#form-response"
hx-swap="outerHTML">
<input type="email" name="email"
hx-post="/api/validate-email"
hx-trigger="blur"
hx-target="next .error" />
<span class="error"></span>
</form>
Positionnement par ancrage
Positionnement natif en CSS d’un élément par rapport à un autre — sans JavaScript. Pour les infobulles, les popovers et les menus déroulants qui suivent leur élément déclencheur.
/* Anchor an element to another */
.trigger {
anchor-name: --my-trigger;
}
.tooltip {
position: fixed;
position-anchor: --my-trigger;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
}
Animations pilotées par le défilement
Liez la progression d’une animation à la position de défilement. Indicateurs de progression de lecture, effets de parallaxe et séquences d’apparition sans JavaScript.
/* Reading progress bar */
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px;
background: var(--color-primary);
transform-origin: left;
animation: progress linear;
animation-timeline: scroll();
}
@keyframes progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
@starting-style
Définissez les styles initiaux des éléments qui entrent dans le DOM, afin de créer des animations d’entrée uniquement en CSS, sans JavaScript.
.card {
opacity: 1;
transform: translateY(0);
transition: opacity 0.3s ease, transform 0.3s ease;
@starting-style {
opacity: 0;
transform: translateY(10px);
}
}
Système de design tokens
Un système complet de tokens pour garantir la cohérence dans toute votre application.
:root {
/* Colors */
--color-text: #1a1a1a;
--color-text-secondary: #666666;
--color-text-muted: #999999;
--color-background: #ffffff;
--color-surface: #f8f9fa;
--color-surface-elevated: #ffffff;
--color-border: #e5e7eb;
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
/* Typography */
--font-sans: system-ui, -apple-system, sans-serif;
--font-mono: "SF Mono", Consolas, monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 2rem;
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
/* Spacing (8px base) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
/* Borders */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-full: 9999px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
/* Transitions */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--duration-fast: 100ms;
--duration-normal: 200ms;
}
Un mode sombre bien conçu
Ne vous contentez pas d’inverser les couleurs : repensez l’interface pour les environnements sombres.
@media (prefers-color-scheme: dark) {
:root {
/* Neutrals */
--color-background: hsl(220, 13%, 10%);
--color-surface: hsl(220, 13%, 15%);
--color-surface-elevated: hsl(220, 13%, 18%);
--color-border: hsl(220, 13%, 23%);
/* Text (inverted) */
--color-text: hsl(220, 9%, 93%);
--color-text-secondary: hsl(220, 9%, 70%);
--color-text-muted: hsl(220, 9%, 55%);
/* Adjust saturation for dark mode */
--color-primary: hsl(220, 80%, 60%);
--color-success: hsl(142, 70%, 45%);
--color-error: hsl(0, 80%, 65%);
/* Shadows in dark mode need adjustment */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
Principes du mode sombre : - Réduisez la saturation des grandes surfaces - Augmentez la luminosité des couleurs d’accentuation - Renforcez les ombres (elles nécessitent davantage de contraste) - Concevez délibérément le mode sombre, sans le traiter après coup
Processus d’extraction depuis Figma
La transformation de fichiers de conception en code de production nécessite une extraction systématique des tokens de design : couleurs, typographie, espacements et effets qui définissent votre langage visuel.
Exportation des variables Figma
La fonctionnalité Variables native de Figma offre le processus d’extraction le plus direct :
Étapes d’exportation :
1. Ouvrez le fichier Figma → panneau Local Variables
2. Cliquez sur le menu de la collection → « Export to JSON »
3. Enregistrez sous figma-variables.json
Structure des tokens JSON :
{
"colors": {
"primitive": {
"blue-500": { "value": "#3b82f6", "type": "color" },
"blue-600": { "value": "#2563eb", "type": "color" }
},
"semantic": {
"primary": { "value": "{colors.primitive.blue-500}", "type": "color" },
"primary-hover": { "value": "{colors.primitive.blue-600}", "type": "color" }
}
},
"spacing": {
"1": { "value": "4px", "type": "spacing" },
"2": { "value": "8px", "type": "spacing" },
"4": { "value": "16px", "type": "spacing" }
}
}
Transformation des tokens en CSS
Propriétés personnalisées CSS :
:root {
/* Primitive colors (direct values) */
--color-blue-50: #eff6ff;
--color-blue-100: #dbeafe;
--color-blue-500: #3b82f6;
--color-blue-600: #2563eb;
--color-blue-900: #1e3a8a;
/* Semantic colors (reference primitives) */
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
--color-background: var(--color-white);
--color-surface: var(--color-gray-50);
/* Spacing (8px grid) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
/* Effects */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
}
Tokens du mode sombre :
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--color-gray-900);
--color-surface: var(--color-gray-800);
--color-text: var(--color-gray-100);
--color-text-secondary: var(--color-gray-400);
/* Adjusted shadows for dark mode */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
Transformation des tokens en SwiftUI
Extension Color :
import SwiftUI
extension Color {
// MARK: - Primitive Colors
static let blue50 = Color(hex: "eff6ff")
static let blue500 = Color(hex: "3b82f6")
static let blue600 = Color(hex: "2563eb")
// MARK: - Semantic Colors
static let brandPrimary = Color.blue500
static let brandPrimaryHover = Color.blue600
// MARK: - Surface Colors
static let surfaceBackground = Color(light: .white, dark: Color(hex: "0f172a"))
static let surfaceElevated = Color(light: Color(hex: "f8fafc"), dark: Color(hex: "1e293b"))
}
extension Color {
init(hex: String) {
// Standard hex parsing implementation
}
init(light: Color, dark: Color) {
self.init(UIColor { traits in
traits.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
})
}
}
Constantes d’espacement :
enum Spacing {
static let xs: CGFloat = 4 // --space-1
static let sm: CGFloat = 8 // --space-2
static let md: CGFloat = 16 // --space-4
static let lg: CGFloat = 24 // --space-6
static let xl: CGFloat = 32 // --space-8
}
// Usage
VStack(spacing: Spacing.md) {
// ...
}
.padding(Spacing.lg)
Liste de contrôle pour la transmission par les designers
Éléments que les designers doivent exporter :
| Type de ressource | Format | Remarques |
|---|---|---|
| Couleurs | Variables JSON | Inclure les modes clair et sombre |
| Typographie | Exportation des styles | Police, taille, graisse, hauteur de ligne |
| Espacements | Variables JSON | Unité de base documentée |
| Icônes | SVG | Contours, couleur unique |
| Images | PNG @2x/@3x ou WebP | Avec compression |
| Composants | Liens Figma | Pour référence pendant l’implémentation |
Critères de validation de la qualité :
- [ ] Toutes les couleurs sont définies comme variables (aucune valeur hexadécimale codée en dur)
- [ ] La typographie utilise les styles de texte définis
- [ ] Les espacements suivent le système de grille (base de 8px)
- [ ] Les variantes du mode sombre sont fournies
- [ ] Les états interactifs sont documentés (survol, actif, désactivé)
- [ ] Les points de rupture responsives sont annotés
- [ ] Les exigences d’accessibilité sont indiquées (rapports de contraste)
Éléments reçus par le développeur :
- Fichiers de tokens (JSON/CSS/Swift selon la plateforme)
- Spécifications des composants avec leurs dimensions
- Ressources exportées dans les formats requis
- Documentation des interactions (états, animations)
- Annotations relatives à l’accessibilité
Tableaux de référence rapide
Principes de Gestalt
| Principe | Règle | Utilisation |
|---|---|---|
| Proximité | Éléments liés = proches | Formulaires, sections |
| Similarité | Même apparence = même fonction | Boutons, cartes |
| Figure-fond | Séparation claire des plans | Fenêtres modales, cartes |
| Continuité | Suivre les lignes | Chronologies, alignement |
| Clôture | Le cerveau complète les formes | Icônes, indications de défilement |
Typographie
| Élément | Taille | Graisse | Hauteur de ligne |
|---|---|---|---|
| Corps de texte | 16px | 400 | 1.5-1.7 |
| Titres | 24-48px | 600-700 | 1.1-1.2 |
| Libellés UI | 12-14px | 500 | 1.3-1.4 |
| Légendes | 12px | 400 | 1.4 |
Rôles des couleurs
| Rôle | Mode clair | Mode sombre |
|---|---|---|
| Arrière-plan | #ffffff | #0f172a |
| Surface | #f4f5f7 | #1e293b |
| Bordure | #e4e6ea | #334155 |
| Texte | #1a1a2e | #f1f5f9 |
| Texte atténué | #6b7280 | #94a3b8 |
| Principale | #3b82f6 | #60a5fa |
| Succès | #22c55e | #4ade80 |
| Erreur | #ef4444 | #f87171 |
Échelle d’espacement
| Token | Valeur | Utilisation |
|---|---|---|
| –space-1 | 4px | Espacement entre les icônes |
| –space-2 | 8px | Éléments en ligne |
| –space-4 | 16px | Espacement par défaut |
| –space-6 | 24px | Marge intérieure des cartes |
| –space-8 | 32px | Espacement entre les sections |
| –space-16 | 64px | Sections de page |
Liste de contrôle du design
Avant de livrer une interface, vérifiez les points suivants :
Gestalt
- [ ] Les éléments liés sont plus proches les uns des autres que des éléments sans rapport (Proximité)
- [ ] Les fonctions similaires présentent des styles similaires (Similarité)
- [ ] Le premier plan et l’arrière-plan sont clairement séparés (Figure-fond)
- [ ] Le regard parcourt naturellement la mise en page (Continuité)
Typographie
- [ ] La taille de police de base est d’au moins 16px
- [ ] La hauteur de ligne du corps de texte est d’au moins 1.5
- [ ] La longueur des lignes ne dépasse pas 75 caractères
- [ ] La hiérarchie est claire (3 niveaux distincts)
- [ ] Une échelle cohérente est utilisée partout
Couleur
- [ ] Tous les textes respectent un rapport de contraste de 4.5:1 (WCAG AA)
- [ ] La couleur n’est pas le seul indicateur (des icônes ou libellés sont également présents)
- [ ] Le mode sombre est conçu délibérément
- [ ] La répartition 60-30-10 est respectée
Hiérarchie visuelle
- [ ] L’élément le plus important peut être identifié
- [ ] Le regard suit l’ordre prévu
- [ ] Chaque section comporte un CTA clair
- [ ] L’échelle typographique est cohérente
Espacement
- [ ] Tous les espacements utilisent l’échelle définie (aucune valeur arbitraire)
- [ ] Les cartes et composants présentent des marges intérieures cohérentes
- [ ] Les espacements sur mobile sont confortables
- [ ] L’alignement sur la grille est cohérent (base de 8px)
Interaction
- [ ] Les utilisateurs peuvent-ils atteindre leurs objectifs sans avoir à réfléchir à l’outil ?
- [ ] L’UI s’adapte-t-elle au contexte actuel ?
- [ ] Les outils sont-ils visibles uniquement lorsqu’ils sont pertinents ?
- [ ] L’utilisation répétée permet-elle d’apprendre des méthodes plus rapides ?
Interfaces d’IA
- [ ] Chaque affirmation factuelle dispose d’une source traçable
- [ ] La diffusion en continu présente les phases du processus, et pas seulement un indicateur de chargement
- [ ] Les états d’erreur sont transparents, et non masqués
- [ ] Les résultats peu fiables sont différenciés visuellement
Vérification selon Dieter Rams
- [ ] Est-il possible de supprimer un élément ?
- [ ] Chaque élément remplit-il une fonction ?
- [ ] Cette interface paraîtrait-elle dépassée dans 5 ans ?
- [ ] Ai-je conçu chaque état ?
Ressources
Livres : - As Little Design as Possible de Sophie Lovell (Dieter Rams) - The Elements of Typographic Style de Robert Bringhurst
Outils : - Vérificateur de contraste WebAIM - Générateur d’échelle typographique - Figma Tokens Studio — Gestion des tokens de design
Systèmes de design : - Apple HIG - Material Design 3 - Radix UI - shadcn/ui
Études de design
Analyses approfondies de 48 produits d’exception, qui recensent les modèles et principes dont vous pouvez vous inspirer.
Outils de développement et IA
| Produit | Contribution majeure |
|---|---|
| Figma | Présence collaborative, panneaux adaptés au contexte |
| Warp | Terminal structuré en blocs, passerelle CLI-GUI |
| Framer | Design responsive visuel, contrôle des propriétés |
| Vercel | Excellence du mode sombre, état indiqué par l’ambiance |
| Linear | Interface optimiste (« Optimistic UI »), flux de travail axé sur le clavier |
| Raycast | Système d’extensions, actions rapides |
| Stripe | Documentation exemplaire, design API |
| Perplexity | IA axée sur les citations, phases de diffusion en continu |
| Obsidian | Composabilité privilégiant le stockage local, interfaces de graphes de connaissances |
Outils natifs Apple et outils créatifs
| Produit | Contribution majeure |
|---|---|
| Flighty | 15 états intelligents, Live Activities, visualisation de données |
| Halide | Activation intelligente, commandes gestuelles |
| Bear | Priorité à la typographie, étiquetage intégré |
| Craft | Approche native sur plusieurs plateformes, pages imbriquées |
| Things | Dates différées, saisie rapide |
| Darkroom | UI sombre immersive, retouche centrée sur la photo |
| Procreate | Outils créatifs axés sur les gestes |
| Overcast | Ingénierie audio invisible au service du design d’interface |
| Camo | UI professionnelle de production vidéo |
| Ivory | Maîtrise du fil chronologique, précision ludique |
| Anybox | Transparence native de la plateforme |
| Drafts | Clarté d’une capture centrée sur le texte |
| Notion Calendar | Précision calendaire, intégration à l’espace de travail |
Productivité, connaissances et finance
| Produit | Contribution majeure |
|---|---|
| Superhuman | Règle des 100 ms, apprentissage de la palette de commandes, prise en main par la pratique |
| Notion | Système de blocs, commandes avec barre oblique |
| Arc | Espaces, vue fractionnée, barre de commandes |
| Todoist | Minimalisme chaleureux, retenue maximale |
| Amie | Productivité joyeuse, minimalisme chaleureux |
| Loom | Professionnalisme convivial de la vidéo asynchrone |
| Pitch | Langage visuel audacieux pour les présentations |
| Readwise Reader | Outils de lecture approfondie, identité cosmique |
| Copilot Money | Visualisation cinématographique des données financières |
| 1Password | Une sécurité sans friction |
| Mercury | Sophistication cinématographique des services bancaires |
Produits grand public, réseaux sociaux et confiance
| Produit | Contribution majeure |
|---|---|
| Spotify | Couleur, émotion et échelle |
| Duolingo | La ludification comme langage visuel |
| Signal | La sécurité par la simplicité |
| Airbnb | La confiance à l’échelle d’une place de marché |
| Bluesky | Transparence algorithmique |
| Letterboxd | Le cinéma comme objet social |
| Strava | Les données GPS comme monnaie sociale |
| Apple Music | Voix éditoriale, audio spatial |
| Headspace | Le calme comme stratégie d’interface |
| Zomato | UX culinaire portée par la personnalité |
Objets physiques, jeux et accessibilité
| Produit | Contribution majeure |
|---|---|
| Balatro | Boucles de rétroaction, systèmes de sensations de jeu |
| Rivian | Photographie d’aventure et typographie monumentale |
| Teenage Engineering | Les contraintes comme identité esthétique |
| OKO | Accessibilité audio-haptique |
| CARROT Weather | La personnalité pour différencier une application utilitaire |
Ce guide s’enrichit par la pratique. Les principes de design sont intemporels, mais leur application évolue avec la technologie et notre compréhension.