7 puntos por GN⁺ 2025-04-05 | 1 comentarios | Compartir por WhatsApp
  • Los enlaces ancla tienen una estructura simple de clic en un botón → desplazarse hasta un encabezado, pero al implementarlos en la práctica surgen problemas
  • Los encabezados ubicados al final no se desplazan con precisión hasta la parte superior del viewport, lo que deteriora la UX
  • Para resolverlo, se prueban distintos enfoques que van evolucionando hacia métodos cada vez más refinados y complejos

Solución simple: agregar padding

  • Un enfoque consiste en agregar espacio para que los encabezados inferiores entren en el área de scroll
  • Se puede resolver calculando el delta y agregando padding
  • Pero al equipo de diseño puede no gustarle el espacio innecesario

Solución práctica: mover la línea de activación

  • Se ajusta la línea de activación hacia la parte inferior del viewport para que alcance los encabezados del final
  • El problema es que el encabezado termina ubicado al fondo del viewport, lo que reduce la legibilidad

Mejora propuesta: crear un punto de activación virtual

  • Se mantiene la posición real del encabezado, pero se crea una posición virtual desplazada hacia arriba solo para disparar la activación
  • Esto aporta flexibilidad para aplicar ajustes distintos a cada encabezado
  • Sin embargo, el primer encabezado se desplaza demasiado hacia arriba y aparece un nuevo problema → se requiere ajuste individual

Un mejor método: desplazamiento proporcional de la posición de activación

  • En lugar de mover todos los disparadores por igual, el primer encabezado se deja igual y el último se mueve al máximo
  • Los encabezados intermedios se desplazan proporcionalmente según su posición
  • Se cumplen las condiciones de mantener el orden de los encabezados y garantizar que el scroll pueda llegar a ellos
  • Este método es simple y práctico, y funciona bien en la mayoría de los casos

Enfoque avanzado: optimización con una función de mapeo personalizada

  • Como la posición de activación se fijó arbitrariamente en el 25%, la posición virtual puede alejarse demasiado de la original
  • Para resolverlo, se introduce un enfoque de optimización usando MSE (Mean Squared Error)

Composición de la función de pérdida

  • Anchor Penalty: cuánto se desvía la posición virtual del encabezado respecto de la original
  • Section Penalty: cuánto cambia la distancia entre secciones (longitud del scroll)
  • Ajustando el peso de ambos valores, se obtiene la posición de activación óptima

Restricciones

  • Mantenerse dentro del rango de la página
  • El primer encabezado no se mueve hacia arriba
  • Se conserva el orden de los encabezados

Insight: los límites del desplazamiento proporcional simple

  • En páginas muy largas (por ejemplo, la Biblia completa), aparece la ineficiencia de tener que aplicar pequeños desplazamientos acumulados a lo largo de todo el documento
  • Cuanto más larga es la página, mayor puede ser el error, con impacto negativo en la UX

Solución final: función de mapeo variable basada en smoothstep

  • La posición de cada encabezado se normaliza a un valor entre 0 y 1, y con base en eso se calcula la proporción de ajuste
  • Se usa la función Smoothstep (S(x) = 3x² - 2x³) para lograr una transición suave
  • Se define una posición inicial de ajuste a para que hasta cierto punto no haya desplazamiento y después aumente gradualmente
    • Ejemplo: si a = 0.4, el 40% superior de los encabezados no se mueve, y el 60% inferior se ajusta de forma progresiva
  • Como resultado, los encabezados superiores conservan su posición original y a los inferiores se les aplica el ajuste máximo → una UX natural

Validación y cierre

  • La implementación final es una solución que equilibra sofisticación de diseño y practicidad
  • Claro, el feedback del diseñador podría ser algo como: “...solo quiero que funcione bien”
  • Pero al menos esta entrada de blog quedará como un registro de ingeniería minuciosa digno de recordar para siempre

1 comentarios

 
GN⁺ 2025-04-05
Opiniones en Hacker News
  • Como desarrollador backend, a veces me sorprende la complejidad cuando veo trabajo de frontend

    • Es un gran artículo y el trabajo está muy bien hecho, pero me pregunto si hace falta introducir tanta complejidad para algo tan simple como el scroll
  • Pregunta sobre el propósito de UX del indicador de "ancla activa" en la navegación lateral

    • Cuando el lector está en medio de una sección larga, puede servir para recordarle la sección actual en lugar del encabezado que no se ve en pantalla
    • Esto significa que funciona según la sección visible en pantalla, no según el encabezado por el que se hizo scroll
    • Si una sección pequeña no ocupa la mayor parte de la pantalla, el indicador activo puede no ser útil
  • La función de UX más importante de los anchor links es que se puedan enviar a otras personas y guardar como marcador

    • Poder guardar una sección específica como marcador es mucho más conveniente que empezar desde la parte superior de la página y hacer scroll o hacer clic en un anchor link
    • Este sitio web no ofrece esa función porque no usa URLs con #anchor-name
  • Hice clic por frustración con los anchors/permalinks de Jira, pero resulta ser algo parecido aunque distinto

    • No se puede navegar a los anchors con el teclado
    • Pregunta para el autor: ¿por qué usar un event listener de JS en un elemento no interactivo en vez de un elemento HTML ``?
  • Lo ideal sería agregar padding debajo del contenido principal de la página

    • Esto resuelve el problema de que el final del contenido quede pegado a la parte inferior del viewport
    • En móvil, un margen de 90vh sería adecuado; en pantallas más grandes, 50vh
    • En desktop, un margen de 90vh puede verse raro
  • En los navegadores modernos, se pueden usar fragmentos de texto para resaltar una parte específica de una página

    • En Chrome, solo hay que resaltar el texto, hacer clic derecho y elegir "Copiar enlace"
    • Lo uso todos los días para resaltar partes específicas de texto en vez de anchors
  • También es posible permitir varios estados "activos"

    • Si el contenido es largo, los encabezados de dos secciones podrían estar ambos en estado "activo"
    • En contenido corto, podrían terminar resaltándose demasiadas partes
  • Es divertido leer los otros comentarios

    • En móvil, el diseño del sitio es interesante y la solución del problema se comunica con claridad
    • Se siente refrescante leer un blog técnico sin popups
  • En Firefox de escritorio, la "solución hermosa" resalta la "sección intermedia"

    • La conclusión se ve completa incluso cuando todavía no se ha llegado al final de la página
    • La respuesta es resaltar todos los anchors visibles en pantalla
  • El artículo es limpio y el diseño del blog es aún más interesante

    • No me gusta la alineación a la derecha, pero la activación inline del popup de la izquierda está muy buena