cssreactjsnext.jstailwind-css

z-index of BackButton being blocked by other component


in my NextJS project, i have created the BackButton component

This button is fixed so it follows the user on downscroll and should be placed further than any content on website so it won'be blocked by other components either.

for that i use z-index and fixed position obviously

The problem is there's a component that is further than BackButton by z-index no matter how high of a value i use.

here's the button, everything is simple, you can even see how far of z-index i use though it is still does not help:

import { ArrowLeftIcon } from "lucide-react";
import { useRouter } from "next/navigation";

const BackButton = () => {
  const router = useRouter();

  return (
    <button
      onClick={() => router.back()}
      className="fixed top-4 left-4 z-[990000] bg-black text-white hover:bg-gray-600 duration-200 rounded-full p-2"
    >
      <ArrowLeftIcon width={40} height={40} />
    </button>
  );
};

export default BackButton;

and here is example of component who is going further than BackButton:

 <div className="bg-slate-200 shadow-md rounded-lg p-4 mb-4 hover:-translate-y-1 duration-500 hover:shadow-xl relative">
   {CONTENT}
 </div>

yeah, there's the -translate-y-1 being used and when is hovered it is going further than button. But that is not the cause of the problem, as even if i remove this css property the BackButton will still be placed behind this component.

The way how i use this button is that i use it as a Layout component in layout.tsx, so it can be at any possible page of the website:

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <QueryProvider>
          <div className="ml-4 mt-4 fixed top-0 left-0">
            <BackButton />
          </div>

          <div className="mt-10">{children}</div>

          <ToastContainer />
        </QueryProvider>
      </body>
    </html>
  );
}

Solution

  • I think the issue is you have nested the BackButton inside another div. Both has fixed positioning which creates a compound positioning problem. The parent div might be establishing its own stacking context that limits how the z-index of the BackButton is interpreted.

    So I'd say, the simplest solution is to move your BackButton to the highest possible level of your DOM tree.

    export default function RootLayout({
      children,
    }: Readonly<{
      children: React.ReactNode;
    }>) {
      return (
        <html lang="en">
          <body
            className={`${geistSans.variable} ${geistMono.variable} antialiased`}
          >
            <QueryProvider>
              {/* BackButton directly in body, not nested */}
              <BackButton />
              
              <div className="mt-10">{children}</div>
    
              <ToastContainer />
            </QueryProvider>
          </body>
        </html>
      );
    }