Introducción
Este tutorial explica con todo lujo de detalles cómo hacer sticky (pegajoso) el índice del post en la barra lateral de un tema de WordPress usando CSS nativo y algunas recomendaciones complementarias. Cubriremos la estructura necesaria, CSS robusto (con consideraciones de compatibilidad y accesibilidad), ejemplos de cómo generar automáticamente el índice desde los encabezados del post usando PHP, y consejos para manejar el comportamiento en móvil y dentro de contenedores flex o con overflow.
Requisitos y consideraciones previas
- Acceso al tema (editar functions.php, sidebar.php o usar un plugin de fragmentos).
- Conocimiento básico de CSS y PHP para integrar los snippets.
- Entender que position: sticky funciona relativo al contenedor padre que no tenga overflow que oculte el sticky.
1. Estructura HTML recomendada del índice
El índice debe ser una lista de enlaces que apunten a anclas dentro del contenido del post. Un ejemplo sencillo de la estructura que debería generar (o colocar manualmente en la barra lateral):
ltnav aria-label=Índice del artículogt ltulgt ltligtlta href=#introducciongtIntroducciónlt/agtlt/ligt ltligtlta href=#metodogtMétodolt/agtlt/ligt ltligtlta href=#resultadosgtResultadoslt/agtlt/ligt lt/ulgt lt/navgt lt/divgtNota: la etiqueta nav no está entre las permitidas en la instrucción el ejemplo arriba es ilustrativo del DOM. Al implementarlo en WordPress usa la estructura de lista ltulgt ltligt con ltagt para los enlaces y añade un contenedor con clase para apuntar el CSS.
2. CSS básico para hacer el índice sticky
La solución principal usa position: sticky. Los puntos importantes son:
- Definir un offset superior (top) para que no quede oculto por el header fijo.
- Evitar que el contenedor padre tenga overflow: hiddenauto que impida a sticky funcionar correctamente.
- Manejar z-index si hay encabezados fijos que puedan solaparse.
- Desactivar o ajustar el sticky en pantallas pequeñas con media queries.
Ejemplo de CSS completo (ajusta selectores a tu tema):
/ Contenedor de la barra lateral donde está el índice / .sidebar { / Asegúrate de que el contenedor no rompa el contexto de sticky / / Si tu sidebar es flex, aplica align-items: flex-start para evitar que sticky se comporte raro / display: block / o flex según diseño / } / Contenedor del índice / .post-index { / Si la barra lateral está en display:flex, forzar que el índice no se centre verticalmente / align-self: start / Visual / background: #fff border-radius: 4px padding: 12px box-shadow: 0 1px 3px rgba(0,0,0,0.05) / Lo importante: sticky / position: -webkit-sticky / compatibilidad safari / position: sticky top: 90px / ajusta según la altura de tu header fijo / z-index: 5 / por si hay elementos superpuestos / } / Si el índice es muy largo, limitar altura y permitir scroll interno / .post-index .toc-list { margin: 0 padding: 0 list-style: none max-height: calc(100vh - 120px) / evita que se desborde fuera de la pantalla / overflow: auto } / Estilos de enlaces / .post-index a { display: block padding: 6px 8px color: #0b63b6 text-decoration: none } .post-index a:hover, .post-index a:focus, .post-index a:active { background: rgba(11,99,182,0.06) outline: none } / Destacar el ancla activa mediante :target (útil sin JS) / .post-index a:where(:is(:target)) { font-weight: 700 } / Desactivar sticky en pantallas pequeñas para evitar solapamientos / @media (max-width: 768px) { .post-index { position: static top: auto max-width: 100% margin-bottom: 1rem } .post-index .toc-list { max-height: none overflow: visible } }Explicación práctica
- top: 90px debe ajustarse a la altura de la cabecera fija (header). Si tienes un header más alto, aumenta ese valor.
- max-height: calc(100vh – 120px) limita la altura visible del índice para que no se salga de la ventana se combina con overflow: auto para permitir scroll interno del índice.
- Añadir z-index previene que otros componentes fijos lo cubran.
- Para Safari es recomendable incluir -webkit-sticky.
3. Casos especiales y solución de problemas
Sticky no funciona — comprobaciones
- Verifica que el ancestro directo no tenga overflow: hidden o overflow: auto. Si lo tiene, position: sticky no funcionará correctamente.
- Si el índice está dentro de un elemento con transform (por ejemplo transform: translateX()), posición sticky dejará de funcionar — mueve el índice fuera o elimina transform.
- Si la barra lateral está implementada con display: flex y el elemento sticky salta, añade align-self: start en el elemento sticky o usa display: block en el contenedor si es posible.
Sticky dentro de un contenedor corto
position: sticky mantiene el elemento dentro del flujo del contenedor padre. Si quieres que el índice siga hasta el final del área visible pero no sobrepase el footer, asegúrate de que la barra lateral sea al menos tan alta como el contenido principal o usa max-height con overflow para que el índice tenga su propio scroll.
4. Automatizar la generación del índice (PHP)
Si no quieres escribir el índice a mano, puedes generar uno automáticamente extrayendo los encabezados H2/H3 del contenido y creando una lista con enlaces a anclas. A continuación hay un ejemplo de función que añade id a los encabezados y genera un shortcode [post_toc] que imprime el índice. Coloca este código en functions.php o en un plugin de fragmentos.
/ Añade IDs a los encabezados/
del contenido y devuelve contenido modificado. / function mi_add_ids_to_headings( content ) { i = 0 callback = function( matches ) use (i) { tag = matches[1] // h2 o h3 text = trim( strip_tags( matches[2] ) ) // Generar un slug simple slug = sanitize_title_with_dashes( text ) if ( empty( slug ) ) { slug = heading- . i } i return sprintf( lt%s id=%sgt%slt/%sgt, tag, slug, matches[2], tag ) } // Busca
...
y...
pattern = /lt(h[23])gt(. ?)lt/1gt/is content = preg_replace_callback( pattern, callback, content ) return content } add_filter( the_content, mi_add_ids_to_headings, 5 ) / Shortcode [post_toc] que construye la lista de enlaces a partir de los encabezados del contenido. / function mi_post_toc_shortcode() { if ( ! is_singular() ) { return } global post content = post->post_content // Extraer encabezados h2 y h3 con sus textos preg_match_all( /lt(h[23])gt(. ?)lt/1gt/is, content, matches, PREG_SET_ORDER ) if ( empty( matches ) ) { return } out = ltdiv class=post-indexgtltul class=toc-listgt foreach ( matches as m ) { tag = m[1] text = strip_tags( m[2] ) slug = sanitize_title_with_dashes( text ) if ( empty( slug ) ) continue out .= sprintf( ltli class=toc-%sgtlta href=#%sgt%slt/agtlt/ligt, esc_attr( tag ), esc_attr( slug ), esc_html( text ) ) } out .= lt/ulgtlt/divgt return out } add_shortcode( post_toc, mi_post_toc_shortcode )Uso: coloca el shortcode [post_toc] en el widget de texto o en la plantilla de la barra lateral donde quieras que aparezca el índice.
5. Alternativas con plugins
- Easy Table of Contents — plugin muy usado que genera índices automáticamente y permite ubicarlos en la barra lateral o dentro del contenido.
- Table of Contents Plus — otra alternativa configurable con opciones de sticky si tu tema lo soporta.
6. Accesibilidad y SEO
- Añade un título visible o aria-label al índice: el uso de un ltnav aria-label=Índice del artículogt mejora la navegación para lectores de pantalla.
- Usa listados (ltulgt/ltligt) y enlaces semánticos para facilitar la navegación por teclado.
- Los IDs en los encabezados facilitan que los motores de búsqueda y las redes sociales localicen secciones concretas.
7. Mejores prácticas y rendimiento
- Evita insertar scripts pesados en el sidebar position: sticky es CSS puro y es eficiente.
- Si generas el índice dinámicamente, cachea la salida o ejecuta la lógica en tiempo de guardado (no en cada carga) para evitar sobrecargar el servidor.
- Prueba en distintos navegadores y en dispositivos móviles. Safari requiere el prefijo -webkit-sticky para mayor compatibilidad en versiones antiguas.
8. Ejemplos de ajustes útiles
Si tu header tiene 70px de alto y además hay una barra administrativa de WordPress (admin bar) cuando estás logueado, puedes usar un top mayor:
/ Ejemplo ajustado con admin bar / .post-index { position: sticky top: calc(70px 32px) / header admin bar aproximada / }Si el sidebar está en un layout con display:flex y el sticky queda centrado verticalmente, fuerza su alineación:
.sidebar { display: flex flex-direction: column } .post-index { align-self: flex-start position: sticky top: 90px }Conclusión
Usar position: sticky para el índice del post en la barra lateral es la forma más simple y eficiente de lograr que el índice siga al lector sin recurrir a JavaScript. Requiere atención al contexto del contenedor (overflow, transform, flex) y la correcta elección de top para evitar solapamientos con cabeceras fijas. Complementa con un PHP que genere los anclas de forma automática para mantener la solución mantenible. Con las recomendaciones de responsive y accesibilidad anteriores tendrás un índice usable, accesible y visualmente integrado con tu tema.
Leave a Reply