October 23, 2024
Chicago 12, Melborne City, USA
CSS

How to Make Framer Motion Dropdown Slide Behind a Fixed Header?


I’m working on a React project where I have a Header component with a fixed position, and a NavMobile component that handles a dropdown menu for mobile navigation. I want the dropdown (motion.div) to slide down behind the header, making it look like the menu is starting from just below the header, but despite adjusting the z-index, the menu keeps appearing in front of the header.

Here’s what I’ve done so far:

  • The header is fixed at the top with z-index: 50.
  • The dropdown menu uses Framer Motion for animation and is intended to slide from just below the header.
  • I set the motion.div to a lower z-index (e.g., z-10), but it still appears in front of the header.

Despite trying different z-index values, I can’t seem to get the dropdown to slide behind the header.
Here’s a simplified version of my code:

export const Header = () => {
  return (
    <header className="fixed top-0 left-0 right-0 h-[10vh] bg-yellow-200 py-4 px-6  z-50">
      <div className="flex justify-between items-center h-full">
        <div className="flex items-center">
          <Logo />
        </div>
        <div className="flex items-center">
          <NavDesktop />
          <NavMobile />
        </div>
      </div>
    </header>
  );
};

export const NavMobile = () => {
  const [isOpen, setOpen] = useState(false);
  const ref = useRef(null);

  useClickAway(ref, () => setOpen(false));

  const menuVariants = {
    hidden: {
      y: '-100%',
      opacity: 1,
    },
    visible: {
      y: '0%',
      opacity: 1,
    },
    exit: {
      y: '-100%',
      opacity: 1,
    },
  };

  return (
    <div ref={ref} className="lg:hidden">
      <div className="relative z-50">
        <Hamburger toggled={isOpen} size={24} toggle={setOpen} />
      </div>

      <AnimatePresence>
        {isOpen && (
          <motion.div
            className="fixed left-0 w-screen bg-blue-300 z-10"
            style={{
              top: '10vh',
              height: '90vh',
            }}
            initial="hidden"
            animate="visible"
            exit="exit"
            variants={menuVariants}
            transition={{ duration: 0.5 }}
          >
            <div className="w-full h-full">
              <ul className="grid gap-2 p-4">
                {routes.map((route) => (
                  <li key={route.title} className="w-full p-[0.08rem]">
                    <div className="flex items-center justify-between w-full p-5">
                      <span onClick={() => setOpen(false)}>
                        <a href={route.href} className="text-lg cursor-pointer">
                          {route.title}
                        </a>
                      </span>
                    </div>
                  </li>
                ))}
              </ul>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
};



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video