Como evitamos que o texto se desloque quando os símbolos aparecem
Você já passou o cursor sobre um item de uma lista e viu o texto inteiro dar uma pequena sacudida para o lado? Isso acontece em quase todos os editores que ocultam e exibem símbolos.

Quando movi o cursor de texto para editar uma lista, o texto foi empurrado para o lado. Quando o cursor saiu, ele voltou ao lugar.
Embora apenas uma linha tivesse se movido, parecia que o parágrafo inteiro estava tremendo. Essa pequena diferença interrompia constantemente o fluxo da edição.
A causa era a largura do marcador.
Normalmente, um marcador redondo aparece na tela. Mas, no arquivo, ficam armazenados um hífen e um espaço. Quando o cursor de texto toca o marcador, é preciso mostrar o texto original para que ele possa ser editado diretamente.
O problema é que as duas formas ocupam larguras diferentes. O marcador fica em uma caixa de largura fixa, mas a largura do hífen e do espaço varia de acordo com a fonte. No mote, essa diferença era de 4,9 px. Sempre que o texto original aparecia, os caracteres seguintes eram empurrados por essa distância.
Movemos a linha pela diferença de largura
Não tornamos as duas larguras iguais. Em vez disso, compensamos a diferença.
No momento em que o marcador muda para o texto original, a linha inteira é movida na direção oposta pela diferença de largura. Mesmo que a forma do símbolo mude, a posição em que o texto começa permanece a mesma.
O arquivo não é alterado. O marcador é um elemento decorativo desenhado sobre o hífen, e a compensação muda apenas a posição em que a linha é desenhada na tela. Mesmo quando o cursor de texto entra e sai, o conteúdo salvo permanece igual.
Também unificamos o critério usado para calcular a largura. Antes, havia números separados no local que desenhava o marcador e no local que compensava a linha. A pequena diferença entre esses dois valores era justamente aqueles 4,9 px.
Agora, os dois lugares consultam a mesma função para obter a largura do marcador. Como há um único critério, não existe mais a possibilidade de divergência.
Porém, quando não há margem esquerda suficiente, a compensação não é aplicada. Isso ocorre porque, ao mover a linha, os caracteres poderiam ser cortados para fora da janela. O desaparecimento de caracteres é um problema maior do que a oscilação.
Deixamos títulos e citações serem empurrados
No início, aplicamos o mesmo método aos títulos e às citações.
Mas o # dos títulos e o > das citações ocupam uma largura de 0 na tela normalmente. Para manter o texto fixo, seria necessário enviar os símbolos para a margem esquerda.
Tecnicamente, funcionou bem. O texto não se movia. Mas a tela parecia estranha. Não era natural ver o símbolo flutuando isoladamente na margem.
Por isso, revertemos a mudança. Agora, quando os símbolos de títulos e citações aparecem, o texto é empurrado para a direita.

No fim, escolhemos uma resposta diferente para cada marcador.
Marcadores que têm uma caixa na tela, como os marcadores de lista e as caixas de seleção de tarefas, mantêm o texto fixo. Marcadores cuja largura normal é 0, como os de títulos e citações, empurram o texto.
Uma tela natural era mais importante do que uma única regra.
Mostramos os símbolos apenas quando são realmente necessários
A melhor maneira de reduzir a oscilação é diminuir a quantidade de momentos em que o símbolo muda.
Agora, o marcador de lista só aparece como texto original quando o cursor de texto está sobre o símbolo. Quando o cursor de texto passa pelo espaço e entra no corpo do texto, ele volta imediatamente a ser um marcador. Não é necessário continuar vendo o hífen enquanto se edita o conteúdo da lista.
O alinhamento também é mantido quando uma linha fica longa e passa para a linha seguinte. Mesmo enquanto o marcador aparece como texto original, a segunda linha começa abaixo do corpo do texto da primeira linha.
Também corrigimos o problema em que um clique era interpretado incorretamente como um arraste. Quando o ponteiro se movia um pouco no momento em que o marcador mudava, os caracteres acabavam sendo selecionados. Agora, o ponteiro precisa se mover mais de 8 px para que o gesto seja considerado um arraste.
Verificamos com números, não com os olhos
É difícil verificar diferenças como essa apenas com os olhos. À primeira vista, tudo pode parecer normal, mas, depois de algum tempo de uso, a interface começa a parecer inquieta.
Por isso, criamos um teste que executa o aplicativo real. Ele move o cursor de texto para dentro e para fora do marcador e compara diretamente as coordenadas x em que o corpo do texto começa. Os dois valores precisam ser iguais para que o teste seja aprovado.
Marcadores de lista, caixas de seleção de tarefas e listas aninhadas são verificados da mesma maneira.
Um desalinhamento de um único pixel dificilmente é relatado como um bug. Em vez de explicar o que se moveu, o usuário apenas sente que “há alguma coisa estranhamente inquieta”.
Por isso, esse tipo de movimento deve ser monitorado por números, não por pessoas.
Uma tela tranquila não é uma tela em que nada acontece. É uma tela em que as mudanças necessárias acontecem sem chamar a atenção.