I have a problem with z-index. I have a navigation bar and when I hover over a text, a dropdown menu appears. Menu and everything works as expected. The problem is when the menu is created, it won't go "above" the hero section elements. You can see both rendered; dropdown menu AND the heroes section and the elements in it. Here is the code snippets for both navbar element and hero section respectively:
import React, { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { DownOutlined } from "@ant-design/icons";
import { Link } from "react-router-dom";
interface NavbarProps {
children: React.ReactNode;
href: string;
FlyoutContent?: React.FC;
};
const Example = () => {
return (
<div className="flex justify-center px-3 py-12 relative !z-50">
<FlyoutLink href="#" FlyoutContent={ProjectTypes}>
<Link to="/projects" className="font-semibold text-xl">Projects</Link>
<DownOutlined className="py-auto" />
</FlyoutLink>
</div>
);
};
const FlyoutLink: React.FC<NavbarProps> = ({ children, href, FlyoutContent }) => {
const [open, setOpen] = useState(true);
const showFlyout = FlyoutContent && open;
return (
<div
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
className="relative w-fit h-fit !z-50"
>
<a href={href} className="relative">
{children}
<span
style={{
transform: showFlyout ? "scaleX(1)" : "scaleX(0)",
}}
className="absolute -bottom-2 -left-2 -right-2 h-1 origin-left scale-x-0 rounded-full bg-indigo-300 transition-transform duration-300 ease-out"
/>
</a>
<AnimatePresence>
{showFlyout && (
<motion.div
initial={{ opacity: 0, y: 15 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 15 }}
transition={{ duration: 0.3, ease: "easeOut" }}
className="absolute left-1/2 top-12 !-translate-x-1/2 w-[calc(100vw-17px)] !z-50"
>
<div className="absolute -top-6 left-0 right-0 h-6 bg-transparent" />
<div className="absolute left-1/2 top-0 h-4 w-4 -translate-x-1/2 -translate-y-1/2 rotate-45" />
<FlyoutContent />
</motion.div>
)}
</AnimatePresence>
</div>
);
};
const ProjectTypes = () => {
return (
<div className="shadow-xl pb-8 relative !z-[100]">
<div className="menu-projects-wrapper grid grid-cols-2 grid-rows-2 gap-x-4">
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/01</h3>
<h1 className="text-2xl font-medium">GitHub Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
</div>
</div>
);
};
export default Example;
import { Button } from "antd";
import { Link } from "react-router-dom";
const HeroSection = () => {
return (
<div className="hero-container py-20 min-[480px]:pt-24 min-[480px]:pb-10 relative z-0">
<div className="main-container px-4 md:px-6">
<div className="title-wrap-hero flex flex-col items-center gap-y-6">
<hr className="w-24 h-3 m-auto bg-gradient-to-r from-white to-black rounded-e-lg" />
<div className="w-full max-w-[1008px]">
<h2 className="text-5xl font-bold text-center md:text-6xl lg:text-7xl 2xl:text-8xl">Hi! I'm Patrik Bajzík</h2>
</div>
<div className="w-full max-w-[600px]">
<p className="text-center font-normal lg:text-xl 2xl:text-2xl">I am a full stack programmer and software developer <br />
based in Trnava, Slovakia.</p>
</div>
<div className="mt-4 lg:w-60 2xl:w-72">
<Button
className="flex justify-center items-center px-6 py-2 min-w-[200px] w-full h-[52px] bg-black text-white font-medium lg:px-8 lg:py-4 lg:h-16 lg:text-xl lg:rounded-xl 2xl:px-10 2xl:py-6 2xl:h-20 2xl:rounded-2xl 2xl:text-2xl hover:!bg-black/80 hover:!text-white"
value="Go to Contact">
<Link to="/contact">Contact Me</Link>
</Button>
</div>
</div>
</div>
</div >
);
};
export default HeroSection;
Of course, these elements are going in App.tsx
right after like this:
<>
<Navbar />
<HeroSection />
</>
I tried several things, but this is what doesn't work at all:
!important
tag!important
tagThanks for reading this far and helping me out!
Seems like the dropdown is displaying over the hero component. Rather, it seems like the dropdown is lacking any background color so the hero showns through it. Consider adding some kind of background color to cover the hero when the dropdown shows, such as in FlyoutLink
:
{showFlyout && (
<motion.div
…
className="… bg-white"
>
const { useState } = React;
const { AnimatePresence, motion } = Motion;
const { DownOutlined } = icons;
const { Link } = ReactRouterDOM;
const Example = () => {
return (
<div className="flex justify-center px-3 py-12 relative !z-50">
<FlyoutLink href="#" FlyoutContent={ProjectTypes}>
<Link to="/projects" className="font-semibold text-xl">Projects</Link>
<DownOutlined className="py-auto" />
</FlyoutLink>
</div>
);
};
const FlyoutLink = ({ children, href, FlyoutContent }) => {
const [open, setOpen] = useState(true);
const showFlyout = FlyoutContent && open;
return (
<div
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
className="relative w-fit h-fit !z-50"
>
<a href={href} className="relative">
{children}
<span
style={{
transform: showFlyout ? "scaleX(1)" : "scaleX(0)",
}}
className="absolute -bottom-2 -left-2 -right-2 h-1 origin-left scale-x-0 rounded-full bg-indigo-300 transition-transform duration-300 ease-out"
/>
</a>
<AnimatePresence>
{showFlyout && (
<motion.div
initial={{ opacity: 0, y: 15 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 15 }}
transition={{ duration: 0.3, ease: "easeOut" }}
className="absolute left-1/2 top-12 !-translate-x-1/2 w-[calc(100vw-17px)] !z-50 bg-white"
>
<div className="absolute -top-6 left-0 right-0 h-6 bg-transparent" />
<div className="absolute left-1/2 top-0 h-4 w-4 -translate-x-1/2 -translate-y-1/2 rotate-45" />
<FlyoutContent />
</motion.div>
)}
</AnimatePresence>
</div>
);
};
const ProjectTypes = () => {
return (
<div className="shadow-xl pb-8 relative !z-[100]">
<div className="menu-projects-wrapper grid grid-cols-2 grid-rows-2 gap-x-4">
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/01</h3>
<h1 className="text-2xl font-medium">GitHub Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
<div className="subproject-container flex gap-x-2 border-b-2 border-b-black py-4">
<h3 className="text-black/50">/02</h3>
<h1 className="text-2xl font-medium">School Projects</h1>
<div className="arrow-container flex justify-center items-center w-8 h-8">
<img src="https://cdn.prod.website-files.com/66bf407255e2bbac50fde356/66bf9e7b27401f68266d92b9_Arrow%20-%20Right.svg" alt="Arrow"></img>
</div>
</div>
</div>
</div>
);
};
// === Hero
const { Button } = antd;
const HeroSection = () => {
return (
<div className="hero-container py-20 min-[480px]:pt-24 min-[480px]:pb-10 relative z-0">
<div className="main-container px-4 md:px-6">
<div className="title-wrap-hero flex flex-col items-center gap-y-6">
<hr className="w-24 h-3 m-auto bg-gradient-to-r from-white to-black rounded-e-lg" />
<div className="w-full max-w-[1008px]">
<h2 className="text-5xl font-bold text-center md:text-6xl lg:text-7xl 2xl:text-8xl">Hi! I'm Patrik Bajzík</h2>
</div>
<div className="w-full max-w-[600px]">
<p className="text-center font-normal lg:text-xl 2xl:text-2xl">I am a full stack programmer and software developer <br />
based in Trnava, Slovakia.</p>
</div>
<div className="mt-4 lg:w-60 2xl:w-72">
<Button
className="flex justify-center items-center px-6 py-2 min-w-[200px] w-full h-[52px] bg-black text-white font-medium lg:px-8 lg:py-4 lg:h-16 lg:text-xl lg:rounded-xl 2xl:px-10 2xl:py-6 2xl:h-20 2xl:rounded-2xl 2xl:text-2xl hover:!bg-black/80 hover:!text-white"
value="Go to Contact">
<Link to="/contact">Contact Me</Link>
</Button>
</div>
</div>
</div>
</div >
);
};
// === App.tsx
const { createBrowserRouter, RouterProvider } = ReactRouterDOM;
const router = createBrowserRouter([
{
path: "/js",
element: (
<React.Fragment>
<Example/>
<HeroSection/>
</React.Fragment>
),
},
]);
ReactDOM.createRoot(document.getElementById('app')).render(<RouterProvider router={router} />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/@remix-run/router@1.19.1/dist/router.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/6.26.1/react-router.production.min.js" integrity="sha512-XVRXtK0P9IJcEljRcNRX+9hLdPMfmejyjiDlfZXR1Nyi37TT7AyZUMAMrgeX0wryYvKLdPQ9AWPGjoW/SADNxA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/6.26.1/react-router-dom.production.min.js" integrity="sha512-P87f9ArfmLsiaaMLnQV/IReuwL8OxyZsVNP6mOMvYCBMeJXj8Ln4QHXxXDb5HER0zBb6R+jam87DkVq81eNYQQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.13/dayjs.min.js" integrity="sha512-FwNWaxyfy2XlEINoSnZh1JQ5TRRtGow0D6XcmAWmYCRgvqOUTnzCxPc9uF35u5ZEpirk1uhlPVA19tflhvnW1g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/5.20.3/antd.min.js" integrity="sha512-sU8OE4WdvFV5kA+AQbzA5qXq2+qLrdTFLwWknywd/zNOl3Md+KV5rLkeSlcFpAVU6Ap76rt0VipxVRbRglf/JQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/@ant-design/icons@5.4.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/framer-motion@11.3.30/dist/framer-motion.js"></script>
<script src="https://cdn.tailwindcss.com/3.4.5"></script>
<div id="app"></div>