Comment nous avons empêché le texte de bouger lorsque les symboles apparaissent
Vous est-il déjà arrivé de déplacer le curseur sur un élément de liste et de voir tout le texte se décaler brièvement sur le côté ? C’est un phénomène que connaissent presque tous les éditeurs qui masquent et affichent les symboles.

Lorsque je déplaçais le curseur pour modifier une liste, le texte se décalait sur le côté. Quand le curseur quittait la ligne, il revenait à sa place.
Une seule ligne bougeait, mais cela donnait l’impression que tout le paragraphe tremblait. Cette petite différence interrompait constamment le rythme de l’édition.
La cause était la largeur du marqueur.
À l’écran, une puce ronde est normalement affichée. Mais le fichier contient un tiret et une espace. Lorsque le curseur atteint le marqueur, il faut afficher le texte source afin de permettre sa modification directe.
Le problème, c’est que ces deux formes n’occupent pas la même largeur. La puce est une boîte de largeur fixe, tandis que la largeur du tiret et de l’espace varie selon la police. Dans mote, cette différence était de 4,9 px. Chaque fois que le texte source apparaissait, le texte qui suivait était décalé d’autant.
La ligne est déplacée d’une distance égale à la différence de largeur
Nous n’avons pas rendu les deux largeurs identiques. À la place, nous compensons leur différence.
Au moment où le marqueur est remplacé par le texte source, toute la ligne est déplacée dans la direction opposée d’une distance égale à la différence de largeur. La forme du symbole change, mais le texte commence toujours au même endroit.
Le fichier n’est pas modifié. La puce est un élément décoratif dessiné par-dessus le tiret, et la compensation ne change que la position à laquelle la ligne est dessinée à l’écran. Le contenu enregistré reste identique, que le curseur entre dans le marqueur ou en sorte.
Nous avons également unifié la référence utilisée pour calculer la largeur. Auparavant, la valeur utilisée pour dessiner le marqueur et celle utilisée pour compenser la ligne étaient définies séparément. La petite différence entre ces deux valeurs correspondait précisément à ces 4,9 px.
Désormais, les deux endroits demandent la largeur du marqueur à la même fonction. Comme il n’y a qu’une seule référence, les valeurs ne peuvent plus diverger.
Toutefois, la compensation n’est pas appliquée lorsque la marge de gauche est insuffisante. En déplaçant la ligne, le texte risquerait en effet d’être coupé en dehors de la fenêtre. La disparition du texte est un problème plus grave que son tremblement.
Nous avons laissé les titres et les citations se décaler
Au début, nous avions appliqué la même méthode aux titres et aux citations.
Mais le # des titres et le > des citations occupent normalement une largeur de 0 à l’écran. Pour maintenir le texte en place, il aurait fallu envoyer ces symboles dans la marge de gauche.
Techniquement, cela fonctionnait bien. Le texte ne bougeait pas. Mais le résultat à l’écran paraissait étrange. Voir les symboles flotter séparément dans la marge ne semblait pas naturel.
Nous sommes donc revenus en arrière. Désormais, lorsque les symboles des titres et des citations apparaissent, le texte est décalé vers la droite.

Au bout du compte, nous avons choisi une réponse différente pour chaque type de marqueur.
Pour les marqueurs qui possèdent une boîte à l’écran, comme les puces et les cases à cocher des tâches, le texte reste fixe. Pour les marqueurs dont la largeur habituelle est de 0, comme ceux des titres et des citations, le texte se décale.
Un affichage naturel était plus important qu’une règle unique.
Les symboles ne sont affichés que lorsqu’ils sont réellement nécessaires
La meilleure façon de réduire les tremblements consiste à réduire le nombre de moments où les symboles changent.
Désormais, le symbole de liste n’est affiché sous sa forme source que lorsque le curseur se trouve directement dessus. Dès que le curseur traverse l’espace et passe dans le texte, la puce réapparaît. Il n’est pas nécessaire de continuer à voir le tiret pendant la modification du contenu de la liste.
L’alignement est également conservé lorsqu’une ligne devient assez longue pour passer à la suivante. Même lorsque le marqueur est affiché sous sa forme source, la deuxième ligne commence sous le texte de la première.
Nous avons aussi corrigé un problème qui faisait parfois prendre un clic pour un glissement. Lorsque le pointeur tremblait légèrement au moment où le marqueur changeait, du texte pouvait être sélectionné. Désormais, le pointeur doit se déplacer de plus de 8 px pour que le geste soit considéré comme un glissement.
Nous vérifions avec des nombres plutôt qu’à l’œil nu
De telles différences sont difficiles à vérifier uniquement à l’œil nu. Tout peut sembler correct lorsqu’on regarde brièvement, mais devenir perturbant après une utilisation prolongée.
Nous avons donc créé un test qui lance l’application réelle. Il déplace le curseur à l’intérieur et à l’extérieur du marqueur, puis compare directement les coordonnées x auxquelles commence le texte. Les deux valeurs doivent être identiques pour que le test réussisse.
Les puces, les cases à cocher des tâches et les listes imbriquées sont toutes vérifiées de la même manière.
Un décalage d’un seul pixel est rarement signalé comme un bug. Au lieu d’expliquer précisément ce qui a bougé, l’utilisateur ressent simplement que « quelque chose est étrangement perturbant ».
C’est pourquoi ce genre de mouvement doit être surveillé par des nombres, et non par des personnes.
Une interface calme n’est pas une interface où rien ne se passe. C’est une interface où les changements nécessaires se produisent sans attirer désagréablement le regard.