Introducción
Este tutorial explica paso a paso cómo diseñar una tabla de contenidos (TOC) fija en el lateral para entradas de WordPress usando CSS y pequeñas ayudas en PHP/JS para integrarla de forma profesional. El objetivo es lograr una TOC visible, accesible y responsive que mejore la navegación en artículos largos sin depender exclusivamente de plugins externos.
Requisitos previos
- Conocimientos básicos de edición de archivos del tema (functions.php, single.php o template-parts).
- Acceso a editar CSS del tema (archivo style.css) o añadir CSS personalizado desde el personalizador.
- Permiso para añadir pequeños fragmentos de PHP y JS al tema hijo (recomendado) o mediante un plugin de funciones.
Estructura HTML recomendada para la TOC
La TOC debe ser una lista de enlaces ancla que apunten a los id de los encabezados (h2, h3, etc.) dentro del contenido. Un bloque típico colocable en la plantilla sería algo como:
ltnav id=toc class=toc-fixed aria-label=Tabla de contenidosgt
lth3gtContenidolt/h3gt
ltulgt
ltligtlta href=#seccion-1gtSección 1lt/agtlt/ligt
ltligtlta href=#seccion-2gtSección 2lt/agtlt/ligt
ltligtlta href=#seccion-3gtSección 3lt/agtlt/ligt
lt/ulgt
lt/navgt
CSS para fijar la TOC en el lateral (básico y responsive)
El siguiente CSS posiciona la TOC de forma fija en la esquina derecha en pantallas grandes, la oculta en móviles y añade scroll interno si el contenido es largo.
/ Contenedor fijo de la TOC /
.toc-fixed {
position: fixed
top: 100px / ajustar según altura del header /
right: 30px / separación del borde derecho /
width: 280px / ancho deseado /
max-height: calc(100vh - 120px) / evitar que sobrepase la ventana /
overflow: auto / scroll interno si hay muchos items /
background: #fff
border: 1px solid #e1e1e1
padding: 16px
border-radius: 6px
box-shadow: 0 6px 18px rgba(0,0,0,0.06)
z-index: 999
font-size: 15px
line-height: 1.4
}
/ Estilos para la lista /
.toc-fixed h3 {
margin: 0 0 8px 0
font-size: 16px
}
.toc-fixed ul {
margin: 0
padding: 0
list-style: none
}
.toc-fixed li {
margin: 6px 0
}
.toc-fixed a {
color: #1e73be
text-decoration: none
}
.toc-fixed a:hover,
.toc-fixed a:focus,
.toc-fixed a.active {
text-decoration: underline
color: #0b5c9e
}
/ Ocultar en móviles y mostrar una versión compacta si se desea /
@media (max-width: 992px) {
.toc-fixed {
display: none
}
}
/ Variante: TOC dentro del flujo (sticky) para plantillas con barra lateral /
.toc-sticky {
position: sticky
top: 80px
}
Generar la TOC automáticamente en WordPress (PHP)
Para no crear la lista manualmente, puedes generar la TOC extrayendo los encabezados del contenido. A continuación un fragmento sencillo que añade un shortcode [toc] y que puedes pegar en functions.php de tu tema hijo.
/
Shortcode [toc] - genera tabla de contenidos a partir de h2/h3 en el contenido
/
function generar_toc_automatica( atts ) {
global post
if ( ! isset( post->post_content ) ) return
content = post->post_content
// Buscar h2 y h3
preg_match_all( /lt(h[2-3])[^gt]gt(.?)lt/1gt/i, content, matches, PREG_SET_ORDER )
if ( empty( matches ) ) return
toc = ltnav id=toc class=toc-fixed aria-label=Tabla de contenidosgt
toc .= lth3gtContenidolt/h3gtltulgt
foreach ( matches as m ) {
tag = m[1]
title = wp_strip_all_tags( m[2] )
// Generar id seguro
slug = sanitize_title( title )
id = toc- . slug
// Asegurarse de que el encabezado en el contenido tenga el id
// Si no existe, añadimos el id al contenido (para versiones simples)
pattern = /(lt . tag . [^gt]?)(?=gt)/i
replacement = 1 id= . id .
content = preg_replace( pattern, replacement, content, 1 )
toc .= ltligtlta href=# . id . gt . esc_html( title ) . lt/agtlt/ligt
}
toc .= lt/ulgtlt/navgt
// Reemplazar el contenido del post con la versión modificada que contiene ids
// Nota: esta técnica es simple para casos complejos usar DOMDocument o filtros más robustos
remove_filter( the_content, wpautop )
add_filter( the_content, function( c ) use ( content ) { return content } , 20 )
return toc
}
add_shortcode( toc, generar_toc_automatica )
Coloca el shortcode [toc] en la plantilla de tu single.php donde quieras que aparezca la TOC o inclúyelo directamente en el contenido mediante el editor.
Encolar CSS y JS correctamente en WordPress
Es recomendable cargar el CSS y la lógica JS desde functions.php para mantener buenas prácticas.
/ Encolar estilos y scripts del TOC /
function enqueue_toc_assets() {
wp_enqueue_style( mi-toc-style, get_stylesheet_directory_uri() . /css/mi-toc.css, array(), 1.0 )
wp_enqueue_script( mi-toc-script, get_stylesheet_directory_uri() . /js/mi-toc.js, array(jquery), 1.0, true )
}
add_action( wp_enqueue_scripts, enqueue_toc_assets )
Coloca el CSS del ejemplo anterior en el archivo css/mi-toc.css y el JS en js/mi-toc.js dentro de tu tema hijo.
Scrollspy ligero en JavaScript (marcar el enlace activo)
Este script detecta el encabezado más cercano al top de la ventana y marca el enlace correspondiente en la TOC. Pégalo en js/mi-toc.js.
document.addEventListener(DOMContentLoaded, function() {
var tocLinks = document.querySelectorAll(#toc a)
if (!tocLinks.length) return
var headings = []
tocLinks.forEach(function(link){
var id = decodeURIComponent(link.getAttribute(href).replace(#,))
var el = document.getElementById(id)
if (el) headings.push({ id: id, el: el, link: link })
})
function onScroll() {
var offset = 120 // mismo que top en CSS
var lastActive = null
for (var i = 0 i lt headings.length i ) {
var rect = headings[i].el.getBoundingClientRect()
if (rect.top - offset lt= 0) {
lastActive = headings[i]
}
}
// Remover clase active
tocLinks.forEach(function(a){ a.classList.remove(active) })
if (lastActive) {
lastActive.link.classList.add(active)
} else {
// marcar el primero si aún no se ha pasado ninguno
if (headings.length) headings[0].link.classList.add(active)
}
}
window.addEventListener(scroll, onScroll, { passive: true })
onScroll()
})
Accesibilidad y buenas prácticas
- Uso de roles y labels: añade aria-label en el nav (aria-label=Tabla de contenidos) para que lectores de pantalla entiendan el bloque.
- Contraste: asegúrate de suficiente contraste en enlaces y texto.
- Navegación por teclado: los enlaces deben ser navegables con tab y focus visible.
- Ocultar en móviles: en pantallas pequeñas es preferible ocultar la versión fija o proveer un botón colapsable para ahorrar espacio.
- SEO y enlaces internos: los anclas no afectan negativamente el SEO y mejoran la usabilidad.
Pruebas y ajustes
- Verifica que cada encabezado tenga un id único. Si no lo tiene, el PHP anterior intenta añadirlo.
- Comprueba en distintos tamaños de pantalla que la TOC no superponga elementos críticos (header, botones flotantes).
- Ajusta top/right/width en el CSS para que encaje con tu diseño.
- Si usas un header fijo (fixed), aumenta el top de la TOC para que no quede oculto tras el header.
- Probar con lectores de pantalla y navegar solo con teclado para comprobar accesibilidad.
Mejoras opcionales
- Animar el desplazamiento al hacer clic en la TOC (smooth scroll en CSS o JS).
- Agregar un botón para fijar/ocultar la TOC por parte del usuario.
- Limitar la generación automática a ciertos post types o a posts con longitud superior a X palabras.
- Usar un parser más robusto (DOMDocument) para manipular los encabezados cuando el contenido es complejo.
Conclusión
Con esta guía tienes todo lo necesario para implementar una tabla de contenidos fija en el lateral de tus entradas de WordPress: estructura HTML recomendada, CSS para posicionado y responsive, fragmentos PHP para generar la TOC automáticamente y un JavaScript ligero para indicar el enlace activo. Integra los fragmentos en tu tema hijo, ajusta estilos y pruebas de accesibilidad, y obtendrás una navegación mucho más usable en artículos largos.
Recursos recomendados: Documentación de WordPress y guías de accesibilidad web para asegurar buena experiencia a todos los usuarios.
Leave a Reply