7 pontos por GN⁺ 2025-04-05 | 1 comentários | Compartilhar no WhatsApp
  • Um link âncora tem, em essência, uma estrutura simples: clicar em um botão → rolar até um título, mas na implementação real surgem problemas
  • Títulos localizados na parte inferior não rolam com precisão até o topo da viewport, o que prejudica a UX
  • Para resolver isso, foram testadas várias abordagens, que evoluíram gradualmente para formas mais sofisticadas e complexas

Solução simples: adicionar padding

  • Um método que adiciona espaço para que títulos na parte inferior possam ser alcançados pela rolagem
  • Dá para resolver calculando o delta e adicionando padding
  • Mas a equipe de design pode não gostar de espaços em branco desnecessários

Solução prática: mover a linha de disparo

  • Ajusta a linha de disparo para mais perto da parte inferior da viewport, permitindo que os títulos inferiores a alcancem
  • O problema é que o título acaba ficando no extremo inferior da viewport, o que prejudica a legibilidade

Melhoria: criar um ponto de disparo virtual

  • Mantém a posição real do título como está, e cria apenas uma posição virtual deslocada para cima onde o disparo ocorre
  • Garante flexibilidade para aplicar ajustes diferentes a cada título
  • Mas o primeiro título é deslocado demais para cima, gerando um novo problema → é necessário ajuste individual

Uma forma melhor: deslocamento proporcional da posição de disparo

  • Em vez de mover todos os disparos igualmente, o primeiro título permanece como está e o último recebe o deslocamento máximo
  • Os títulos intermediários são deslocados proporcionalmente de acordo com sua posição
  • Atende às condições de preservar a ordem dos títulos e garantir que a rolagem possa alcançá-los
  • Essa abordagem é simples e prática e funciona bem na maioria dos casos

Abordagem avançada: otimização com função de mapeamento personalizada

  • Como a posição de disparo foi colocada arbitrariamente em 25%, a posição virtual pode acabar se afastando demais da posição original
  • Para resolver isso, foi introduzida uma abordagem de otimização usando MSE (Mean Squared Error)

Composição da função de perda

  • Anchor Penalty: o quanto a posição virtual do título se afasta da posição original
  • Section Penalty: o quanto mudam as distâncias entre seções (comprimento de rolagem)
  • Ajustando os pesos desses dois valores, é possível encontrar a posição de disparo ideal

Restrições

  • Permanecer dentro dos limites da página
  • O primeiro título não deve ser movido para cima
  • Preservar a ordem dos títulos

Insight: os limites do deslocamento proporcional simples

  • Em páginas muito longas (ex.: a Bíblia inteira), surge a ineficiência de aplicar pequenos deslocamentos acumulados ao longo de toda a página
  • Quanto maior a página, maior pode ser o erro, com possível impacto negativo na UX

Solução final: função de mapeamento variável baseada em smoothstep

  • A posição de cada título é normalizada para um valor entre 0 e 1 e, com base nisso, calcula-se a taxa de ajuste
  • A função Smoothstep (S(x) = 3x² - 2x³) é usada para criar uma transição suave
  • Define-se a posição inicial de ajuste a, de modo que até certo ponto não haja deslocamento e, depois disso, ele aumente suavemente
    • Ex.: se a = 0.4, os 40% superiores dos títulos não se movem, e os 60% inferiores recebem ajuste gradual
  • Como resultado, os títulos do topo mantêm a posição original, enquanto os do fim recebem o ajuste máximo → oferecendo uma UX natural

Validação e encerramento

  • A implementação final é uma solução que equilibra sofisticação de projeto e praticidade
  • Claro, o feedback do designer pode muito bem ser algo como: “...desde que simplesmente funcione”
  • Mas, pelo menos, este post de blog ficará para sempre como um registro de engenharia meticulosa

1 comentários

 
GN⁺ 2025-04-05
Opiniões no Hacker News
  • Como desenvolvedor backend, às vezes fico surpreso com a complexidade ao olhar trabalhos de frontend

    • É um ótimo artigo e o trabalho foi bem feito, mas fico em dúvida se é mesmo necessário introduzir tanta complexidade para um simples scroll
  • Pergunta sobre o objetivo de UX da indicação de "âncora ativa" na navegação lateral

    • Quando o leitor está no meio de uma seção longa, isso pode servir para lembrar qual é a seção atual no lugar de um título que não está visível na tela
    • Isso significa que funciona com base na seção visível na tela, e não no título pelo qual se passou ao rolar
    • Se uma seção pequena não ocupar a maior parte da tela, a indicação ativa pode não ser útil
  • A função de UX mais importante dos links âncora é poder enviá-los para outras pessoas e salvá-los nos favoritos

    • Poder favoritar uma seção específica é muito mais prático do que começar do topo da página e rolar ou clicar em links âncora
    • Este site não oferece isso porque não usa URLs com #anchor-name
  • Cliquei por irritação com âncoras/permalinks do Jira, mas isso é parecido e ao mesmo tempo diferente

    • Não é possível navegar até a âncora pelo teclado
    • Pergunta ao autor: por que usar um listener de evento em JS num elemento não interativo em vez de um elemento HTML ``
  • O ideal seria adicionar padding abaixo do conteúdo da página principal

    • Isso resolve o problema de a parte final do conteúdo ficar presa na parte inferior da viewport
    • No mobile, uma margem de 90vh parece adequada; em telas maiores, 50vh
    • No desktop, uma margem de 90vh pode parecer estranha
  • Em navegadores modernos, é possível usar fragmentos de texto para destacar uma parte específica da página

    • No Chrome, basta selecionar o texto, clicar com o botão direito e escolher "Copiar link"
    • Uso isso todos os dias para destacar trechos específicos de texto em vez de âncoras
  • Também é possível permitir vários estados "ativos"

    • Se o conteúdo for longo, os cabeçalhos de duas seções podem ficar ambos "ativos"
    • Em conteúdo curto, partes demais podem acabar destacadas
  • É divertido ler os outros comentários

    • No mobile, o design do site é interessante e a solução do problema é comunicada com clareza
    • É refrescante ler um blog técnico sem pop-ups
  • No Firefox para desktop, a "beautiful solution" destaca a "middle section"

    • A conclusão fica totalmente visível mesmo antes de se chegar ao fim da página
    • Destacar todas as âncoras visíveis na tela é a resposta
  • O artigo está limpo, e o design do blog é ainda mais interessante

    • Não gosto do alinhamento à direita, mas a ativação inline no pop-up à esquerda é muito legal