Introducción
Este tutorial muestra, paso a paso y con todo detalle, cómo añadir un subrayado animado al pasar el ratón por los menús en un sitio WordPress. Verás dos métodos principales:
- CSS puro (fácil y compatible): subrayado que aparece y anima bajo cada enlace.
- Slider animado con JavaScript: una barra que se desplaza entre elementos del menú con suavidad, manteniéndose en el ítem activo.
Consideraciones previas
Antes de tocar código, ten en cuenta:
- Usa un tema hijo si vas a modificar archivos del tema (para no perder cambios con actualizaciones).
- Prueba primero en un entorno de desarrollo o staging.
- Para añadir CSS puedes usar Personalizar gt CSS adicional o incluirlo en style.css del tema hijo.
- Si necesitas JavaScript, en WordPress lo ideal es encolar el script con wp_enqueue_script en functions.php del tema hijo.
Método 1 — CSS puro (pseudo-elemento)
Este método usa un pseudo-elemento (:after) en cada enlace del menú para crear el subrayado. Ventajas: sin JS, accesible y funciona incluso con navegadores reducidos.
Cómo funciona
- El pseudo-elemento se posiciona debajo del texto y se escala en el eje X para crear la animación.
- Se anima la propiedad transform: scaleX(0 → 1) con transform-origin para controlar el punto de inicio (izquierda, centro, derecha).
- Se gestiona el estado activo con la clase current-menu-item o aria-current que WordPress añade al enlace actual.
Ejemplo de CSS (selector genérico)
Adapta los selectores a la estructura de tu tema. Aquí se usa un selector genérico para un menu principal con enlaces: .main-navigation a
/ Subrayado animado básico /
.main-navigation a {
position: relative
display: inline-block / necesario para calcular ancho del pseudo-elemento con el texto /
text-decoration: none
color: #111
padding: 6px 4px / opcional: espacio para que el subrayado no choque con el texto /
}
.main-navigation a::after {
content:
position: absolute
left: 0
bottom: 0 / ajustar si el padding cambia /
height: 3px / grosor del subrayado /
width: 100%
background: var(--accent, #ff3b30) / color del subrayado /
transform: scaleX(0)
transform-origin: left center / aparece desde la izquierda /
transition: transform 250ms cubic-bezier(.2,.8,.2,1)
will-change: transform
}
/ Hover / focus (accesibilidad para teclado) /
.main-navigation a:hover::after,
.main-navigation a:focus::after,
.main-navigation a:focus-visible::after {
transform: scaleX(1)
}
/ Estado del elemento activo (WordPress añade current-menu-item o aria-current) /
.main-navigation .current-menu-item > a::after,
.main-navigation a[aria-current=page]::after {
transform: scaleX(1)
}
Variaciones útiles
- Subrayado centrado: usa transform-origin: center para que el efecto se expanda desde el centro.
- Ancho fijo (subrayado más corto que el texto): cambia width a un valor en px o % (ej. width: 60% left: 20% para centrarlo).
- Degradado: usa background: linear-gradient(…) en lugar de color sólido.
Método 2 — Slider animado que se desplaza entre ítems (JS CSS)
Este método crea un elemento extra (barra deslizante) que se posiciona bajo el enlace activo y se mueve con una transición suave al pasar el ratón por las opciones. Es el efecto típico de underline slider en muchas interfaces modernas.
Ventajas y consideraciones
- Resultado muy fluido y elegante.
- Requiere JavaScript para calcular posición y ancho en tiempo real.
- Debes encolarlo correctamente en WordPress (functions.php) o añadirlo al footer.
CSS para el slider
/ Contenedor del menú: asegúrate de que sea position: relative para anclar el slider /
.main-navigation {
position: relative
}
/ Enlaces del menú: inline-block para medir ancho /
.main-navigation a {
position: relative
display: inline-block
padding: 10px 12px
text-decoration: none
color: #111
}
/ Slider: elemento que se moverá. Se añadirá dinámicamente por JS o puede estar en el HTML /
.main-navigation .menu-slider {
position: absolute
bottom: 0
height: 3px / grosor /
background: linear-gradient(90deg, #ff7a18, #af002d) / color o degradado /
transition: transform 300ms cubic-bezier(.2,.8,.2,1), width 300ms cubic-bezier(.2,.8,.2,1), left 300ms cubic-bezier(.2,.8,.2,1)
will-change: transform, width, left
pointer-events: none / no interfiere con clicks /
border-radius: 2px
transform-origin: left center
}
JavaScript: lógica básica
El siguiente script:
- Busca los enlaces del menú.
- Crea o selecciona un .menu-slider dentro de .main-navigation.
- Al pasar el ratón (mouseenter) calcula left y width y mueve el slider.
- Al salir (mouseleave) vuelve al elemento activo actual o oculta el slider.
document.addEventListener(DOMContentLoaded, function () {
var nav = document.querySelector(.main-navigation)
if (!nav) return
var links = nav.querySelectorAll(a)
var slider = nav.querySelector(.menu-slider)
// Si no existe el slider, lo creamos
if (!slider) {
slider = document.createElement(div)
slider.className = menu-slider
nav.appendChild(slider)
}
function moveSliderToLink(link) {
var rect = link.getBoundingClientRect()
var navRect = nav.getBoundingClientRect()
var left = rect.left - navRect.left nav.scrollLeft
var width = rect.width
slider.style.left = left px
slider.style.width = width px
slider.style.opacity = 1
}
function hideSlider() {
// Si hay un elemento activo, volver a él
var active = nav.querySelector(.current-menu-item > a, a[aria-current=page])
if (active) {
moveSliderToLink(active)
} else {
slider.style.opacity = 0
slider.style.width = 0
}
}
links.forEach(function (link) {
link.addEventListener(mouseenter, function () {
moveSliderToLink(link)
})
// Mantener accesible para teclado: focus
link.addEventListener(focus, function () {
moveSliderToLink(link)
})
})
nav.addEventListener(mouseleave, hideSlider)
// Inicializar: posicionar en la opción actual si existe
var initActive = nav.querySelector(.current-menu-item > a, a[aria-current=page])
if (initActive) moveSliderToLink(initActive)
else slider.style.opacity = 0
})
Encolar el JavaScript en WordPress (functions.php)
Agrega este fragmento al functions.php de tu tema hijo para cargar el archivo JS de forma correcta. Asegúrate de que el archivo slider.js contenga el código anterior o de que el código esté en un archivo separado.
/ Enqueue para el slider del menú /
function mi_tema_enqueue_menu_slider() {
wp_enqueue_script(
menu-slider,
get_stylesheet_directory_uri() . /js/menu-slider.js, // ruta en el tema hijo
array(), // dependencias, p.ej. array(jquery) si usas jQuery
1.0.0,
true // en el footer
)
}
add_action(wp_enqueue_scripts, mi_tema_enqueue_menu_slider)
Detalles prácticos y personalización
Selección de selectores
Los selectores anteriores usan .main-navigation por ejemplo. Según tu tema los contenedores pueden ser nav#site-navigation, .primary-menu o estructuras más complejas. Inspecciona el código HTML del menú y ajusta selectores.
Ajustes recomendados
- Duración de la transición: 200–350ms suelen ser agradables.
- Easing: cubic-bezier(.2,.8,.2,1) o ease-out para un efecto suave.
- Grosor: 2–4px según tipografía y diseño.
- Compatibilidad móvil: en menús colapsados (hamburger) el slider puede no tener sentido añade una condición para ocultarlo en pantallas pequeñas con media queries.
Media query para ocultar el slider en móvil
@media (max-width: 768px) {
.main-navigation .menu-slider {
display: none
}
}
Accesibilidad y teclado
- Asegúrate de que el efecto también se active con :focus o focus-visible para usuarios que navegan con teclado.
- No elimines outlines sin ofrecer una alternativa visible. Si quitas outline, compensa con un estilo claro en el foco del enlace y en el subrayado.
- Si el slider se mueve al elemento activo, los lectores de pantalla siguen viendo el markup normal del menú el slider es solo presentación visual.
Solución de problemas comunes
- El subrayado no aparece: verifica que los selectores coincidan con la estructura HTML de tu menú y que el CSS no esté siendo sobrescrito. Usa herramientas de inspección del navegador.
- El slider se descoloca al hacer scroll: si el contenedor tiene transformaciones CSS o un posicionamiento inusual, getBoundingClientRect() cambia en esos casos calcula la posición relativa correctamente o usa offsets del contenedor.
- Transiciones entre elementos saltan: revisa que no haya cambios bruscos en padding/margin que afecten la posición añade will-change para suavizar.
Plantilla de ejemplo completa (resumen)
Resumen mínimo de los pasos a implementar en tu tema hijo:
- Agregar CSS para pseudo-elemento o slider en style.css o CSS adicional.
- Si usas slider, crear menu-slider con CSS y añadir script en js/menu-slider.js.
- Encolar el script mediante functions.php del tema hijo.
- Probar en distintos navegadores y en móvil ajustar media queries y estados de foco.
Recursos útiles
- WordPress Developer Resources — documentación oficial para encolar scripts y trabajar con temas.
Notas finales
Elige la solución que mejor se adapte a tu proyecto: si buscas simplicidad y máxima compatibilidad, usa el método CSS puro si deseas un efecto visual más llamativo y dinámico, implementa el slider con JavaScript. Adapta selectores y medidas a la tipografía y diseño de tu tema para obtener resultados profesionales.
Leave a Reply