Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Hidden Shearch Widget

Table of contents

No titles in the blog post

Hidden Search (Barra de Búsqueda Oculta) en CSS/JS — Guía completa, demo y mejores prácticas

Aprende a implementar una barra de búsqueda oculta con animaciones fluidas, accesibilidad ARIA, rendimiento optimizado y consejos de seguridad. Incluimos una demo interactiva, variaciones avanzadas, comparativas, troubleshooting y comandos útiles para integrarla en tu proyecto.

Dos personas trabajando con código en una oficina
Imagen ilustrativa · Compagnons / Unsplash.
Consejo rápido: este patrón es ideal cuando quieres ofrecer búsqueda sin ocupar espacio permanente en la interfaz. Perfecto para headers minimalistas, dashboards o apps móviles web.

fkffkfkfkf

Demo interactiva: Hidden Search (tema naranja)

Haz clic en el icono de la lupa para desplegar la búsqueda. La animación y el foco se gestionan con JavaScript y CSS variables.

Cómo funciona el patrón Hidden Search
  • Estado visual: la clase .active en el contenedor .dock expande el input de 50px a 240px con transition.
  • Comportamiento: al hacer clic en el botón (lupa), se alterna .active y se hace focus() en el input.
  • Accesibilidad: role="search" y aria-label describen el propósito; el icono usa aria-hidden="true".
  • Diseño: colores y radios se gestionan con CSS variables para personalización rápida.
Mejora UX: añade atajos de teclado (por ejemplo, tecla "/" para enfocar la búsqueda) y aria-expanded en el botón para informar del estado.
Requisitos y compatibilidad
  • Navegadores: Soporte de CSS variables y CSS Grid (Chrome 49+, Firefox 31+, Edge 16+, Safari 9.1+).
  • Fuentes/íconos: CDN de Google Fonts y Font Awesome 5 (incluye SRI e crossorigin).
  • Accesibilidad: Navegación por teclado y soporte de lectores de pantalla (NVDA, VoiceOver, JAWS).
  • Rendimiento: No bloquea renderizado; JS mínimo y sin dependencias.
Implementación paso a paso (desde cero)
  1. Crea la estructura HTML:
    <div class="dock" role="search" aria-label="Búsqueda">
      <input id="search" type="text" class="input form-control" placeholder="Buscar..." aria-label="Campo de búsqueda" />
      <button class="btn btn-light position-absolute top-0 start-0" aria-controls="search" aria-expanded="false" aria-label="Mostrar/Ocultar búsqueda">
        <i class="fas fa-search" aria-hidden="true"></i>
      </button>
    </div>
  2. Aplica estilos esenciales:
    .dock { position: relative; height: 50px; }
    .dock .input { width: 50px; transition: width .3s ease; padding-left: 52px; }
    .dock.active .input { width: 280px; }
    .dock .btn { width: 50px; height: 50px; }
    .dock.active .btn { transform: translateX(230px); transition: transform .3s ease; }
  3. Comportamiento con JavaScript:
    const dock = document.querySelector(".dock");
    const btn  = dock.querySelector(".btn");
    const input = dock.querySelector(".input");
    
    function toggle() {
      const active = dock.classList.toggle("active");
      btn.setAttribute("aria-expanded", String(active));
      if (active) input.focus();
    }
    
    btn.addEventListener("click", toggle);
    // Atajo "/"
    window.addEventListener("keydown", e => {
      if (e.key === "/" && !e.defaultPrevented) {
        e.preventDefault();
        if (!dock.classList.contains("active")) toggle();
        input.focus();
      }
    });
Tip: en Bootstrap, puedes usar utilidades como position-absolute y form-control para integrarlo visualmente con tu tema.
Comandos útiles (dev/producción)
  • Inicializar proyecto con Vite:
    npm create vite@latest hidden-search -- --template vanilla
    cd hidden-search
    npm install
    npm run dev
    Arranca un servidor local con hot reload para iterar rápido.
  • Servidor estático rápido:
    npx serve .    # o
    npx http-server -p 5173
    Ideal para validar el iframe o la demo en una carpeta.
  • Empaquetar y minificar:
    npm run build  # genera assets optimizados para producción
Alternativa: usa Parcel (npx parcel index.html) si prefieres cero configuración.
Variaciones avanzadas y casos de uso
  • Sugerencias en vivo (autocomplete): integra Fuse.js para búsqueda difusa local o Algolia para indexado remoto.
  • Acciones rápidas: combina con un “Command Palette” (Ctrl/Cmd+K) para ejecutar comandos y búsquedas globales.
  • Persistencia: guarda términos recientes en localStorage y ofrece chips de búsqueda.
  • Microinteracciones: añade prefers-reduced-motion para respetar accesibilidad al animar.
  • Tematización: cambia --g1 y --g2 para adaptarlo a tu branding (modo oscuro incluido).
Comparativa rápida con otras soluciones
  • Hidden Search vs. Campo fijo en el navbar: el oculto ahorra espacio; el fijo ofrece discoverability constante.
  • Hidden Search vs. Modal de búsqueda: el modal centra la atención y permite resultados ricos; requiere más navegación.
  • Hidden Search vs. Offcanvas: offcanvas es útil para filtros complejos; la barra oculta es más ágil.
  • JS nativo vs. jQuery/Alpine.js/React:
    • Nativo: 0 dependencias, ideal para widgets simples.
    • Alpine.js: sintaxis declarativa ligera para estados.
    • React/Vue: recomendado si la búsqueda se integra en un estado global o resultados dinámicos complejos.
Buenas prácticas, seguridad y accesibilidad
  • Usa aria-expanded y aria-controls en el botón; proporciona etiquetas descriptivas.
  • Gestión de foco: al abrir, enfoca el input; al cerrar, devuelve el foco al botón para no “perder” al usuario.
  • Sanitiza entradas si las usas en consultas o rutas. Evita inyectar innerHTML con contenido del usuario.
  • CSP y SRI: aplica Content-Security-Policy y Subresource Integrity en recursos CDN (ya presente en Font Awesome).
  • Keybindings accesibles: implementa escape para cerrar y respeta prefers-reduced-motion.
  • Performance: limita repaints; usa transform y opacity para animaciones fluidas.
Seguridad: si la búsqueda consulta un backend, aplica rate limiting, validación server-side y protección frente a inyección (SQL/NoSQL), además de logs para auditoría.
Optimización y rendimiento
  • Carga diferida: añade loading="lazy" a iframes/imágenes y defer a scripts externos.
  • Minificación y bundling: combina CSS/JS y habilita HTTP/2 para multiplexar recursos.
  • Fonts: usa font-display: swap y precarga fuentes críticas si es necesario.
  • CSS variables: permiten theming sin duplicar CSS; define tokens en :root y sobrescribe por tema.
  • Medición: audita con Lighthouse (LCP, CLS, TBT) y Performance Panel en DevTools para detectar cuellos de botella.

Verifica la URL del CDN, la conectividad y la consola (404/403). Asegúrate de incluir la hoja de estilos de FA y que no haya bloqueos por CSP. Alternativa rápida: usa Bootstrap Icons o un SVG inline para eliminar dependencias externas.

Asegúrate de que el selector .dock existe antes de ejecutar el script y que no haya colisiones de clases. Comprueba que no existan estilos más específicos sobrescribiendo width y transition. Revisa la consola por errores JavaScript.

Si el entorno aplica políticas estrictas de contenido, el atributo srcdoc podría estar restringido. Prueba servir el HTML como archivo externo y usa src en lugar de srcdoc. Revisa referrerpolicy y cabeceras CSP como frame-src.

Asegura tab-order lógico y contraste suficiente. Implementa ESC para cerrar y devuelve el foco al botón. Prueba con lectores de pantalla y valida con herramientas como axe DevTools.
Alternativas tecnológicas
  • Local fuzzy search: Fuse.js (sin servidor, rápido para datasets pequeños/medianos).
  • Hosted search: Algolia o Meilisearch (sincronización de índices, tipado, facetado).
  • Command palette: bibliotecas como cmdk (React) o Implementación nativa con <dialog> y ARIA.
  • Sin icon fonts: reemplaza la lupa por SVG inline para reducir dependencias y mejorar nitidez.
Referencias y estándares
  • MDN Web Docs: CSS Variables, Transitions, Focus Management.
  • WAI-ARIA Authoring Practices: patrón de búsqueda y roles.
  • Google Web Fundamentals: Performance, animaciones y accesibilidad.
  • Lighthouse: métricas Core Web Vitals para evaluar impacto.
Siguiente paso: integra esta barra en tu navbar de Bootstrap. Coloca el contenedor .dock dentro de .navbar y usa utilidades como ms-auto para alinear. Recuerda ajustar el ancho expandido para pantallas XS usando breakpoints (por ejemplo, @media (max-width: 576px)).

¿Listo para llevarlo a producción? Añade métricas de uso (eventos de búsqueda), debounced input y fallback sin JS para máxima resiliencia.