React + MotionNavegación
Navbar que se encoge
Una barra de navegación flotante y esmerilada que se estrecha al hacer scroll y recupera su tamaño arriba del todo.
Ajustes
18px
Código
import { useEffect, useRef, useState } from "react";
import { motion } from "framer-motion";
import { Bell, Search } from "lucide-react";
const spring = { type: "spring" as const, stiffness: 300, damping: 30 };
interface ShrinkingNavbarProps {
threshold?: number;
/** true: caja de demo con scroll propio. false: navbar fijo arriba que escucha el scroll de la página. */
contained?: boolean;
}
export default function ShrinkingNavbar({
threshold = 18,
contained = true,
}: ShrinkingNavbarProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [small, setSmall] = useState(false);
// Escucha el scroll del contenedor propio si existe; si no, el de la ventana.
useEffect(() => {
const el = contained ? containerRef.current : null;
const read = () => setSmall((el ? el.scrollTop : window.scrollY) > threshold);
const target: HTMLElement | Window = el ?? window;
read();
target.addEventListener("scroll", read, { passive: true });
return () => target.removeEventListener("scroll", read);
}, [contained, threshold]);
const nav = (
<motion.nav
animate={{ maxWidth: small ? 250 : 340, height: small ? 44 : 58 }}
transition={spring}
style={{ width: "100%" }}
className="sticky top-0 z-10 flex shrink-0 items-center justify-between rounded-full bg-white/70 dark:bg-black/70 px-5 shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)] backdrop-blur-[20px]"
>
<b>AIMRAN</b>
<div className="flex gap-3">
<Search className="h-4 w-4" />
<Bell className="h-4 w-4" />
</div>
</motion.nav>
);
if (!contained) {
return <div className="sticky top-0 z-50 flex justify-center p-4 text-[#1d1d1f] dark:text-[#f5f5f7]">{nav}</div>;
}
return (
<div
ref={containerRef}
className="flex h-52 w-full flex-col items-center overflow-y-auto rounded-2xl bg-black/5 p-4 text-[#1d1d1f] dark:text-[#f5f5f7] dark:bg-white/10"
>
{nav}
{/* Contenido de relleno para poder hacer scroll; también da 340 px de ancho natural sin forzar un mínimo */}
<svg aria-hidden className="h-[326px] w-[340px] max-w-full shrink-0" />
</div>
);
}
Prompt para IA
Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.
Más en Navegación
Dónde usarlo
Una navbar que se encoge deja a mano el logo y el buscador y da más sitio al contenido. Le va a las páginas largas: un artículo de revista, la carta de un restaurante, una documentación o un caso de estudio. Si buscabas un header fijo que se reduce al hacer scroll, este lo hace con un muelle suave.
El umbral decide cuántos píxeles de scroll hacen falta antes de que se encoja; con un valor pequeño se siente ágil. En el estado compacto deja solo dos o tres elementos, porque al estrecharse hay menos espacio.