Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Z-Index stacking issue in React/tailwind application

I am having an issue with z-index stacking on an app I’m building. The code is displayed below. It is a react application using tailwind.css.

For the app I have a hamburger menu in the header that appears fullscreen as a modal when the hamburger symbol is clicked. The functionality works fine except on the Details.jsx page which has images displayed in a carousel using React Slick Slider.

When I open the hamburger modal in this page, the modal appears below just the image in the slider in stacking order with z-10. If I change the z-index to -z-10, the modal is stacked above the Slider image but the slider no longer functions. There must be something obvious I’m doing wrong but I cannot seem to figure it out.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

App.jsx:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import ChatInput from "./components/ChatInput";
import Header from "./components/Header";
import Details from "./pages/Details";
import Home from "./pages/Home";
import Login from "./pages/Login";
import News from "./pages/News";
import Register from "./pages/Register";
import Saved from "./pages/Saved";

function App() {
  return (
    <>
      <Router>
        <section className="fixed bg-gray-100">
          <Header />
          <ChatInput />
        </section>
        <section className="pt-32">
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/login" element={<Login />} />
            <Route path="/register" element={<Register />} />
            <Route path="/saved" element={<Saved />} />
            <Route path="/news" element={<News />} />
            <Route path="/details" element={<Details />} />
          </Routes>
        </section>
      </Router>
    </>
  );
}

export default App;

Header.jsx:

import HamburgerMenu from "./HamburgerMenu";

function Header() {
  return (
    <header className="relative h-16 w-full">
      <HamburgerMenu />
    </header>
  );
}

export default Header;

HamburgerMenu.jsx:

import { useState } from "react";
import { Link } from "react-router-dom";

const HamburgerMenu = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const toggleModal = () => {
    setIsModalOpen(!isModalOpen);
  };

  const stopPropagation = (e) => {
    e.stopPropagation();
  };

  return (
    <div>
      <button
        onClick={toggleModal}
        className="fixed top-4 right-4 p-2 rounded-md focus:outline-none z-50"
      >
        <span
          className={`block w-6 h-0.5 bg-black transition-transform duration-300 ${
            isModalOpen ? "opacity-0" : ""
          }`}
        ></span>
        <span
          className={`block w-6 h-0.5 bg-black mt-1.5 transition-opacity duration-300 ${
            isModalOpen ? "transform rotate-45 translate-y-0.5 bg-white" : ""
          }`}
        ></span>
        <span
          className={`block w-6 h-0.5 bg-black mt-1.5 transition-transform duration-300 ${
            isModalOpen ? "transform -rotate-45 -translate-y-1.5 bg-white" : ""
          }`}
        ></span>
      </button>
      {isModalOpen && (
        <div
          onClick={toggleModal}
          className={`fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-40 ${
            isModalOpen
              ? "translate-y-0 opacity-100"
              : "translate-y-full opacity-0"
          }`}
        >
          <div
            onClick={stopPropagation}
            className="bg-black text-white w-full h-screen m-auto overflow-auto"
          >
            <div className="p-20 text-3xl">
              <Link to="/" className="block pb-4" onClick={toggleModal}>
                Home
              </Link>
              <Link to="/saved" className="block pb-4" onClick={toggleModal}>
                Saved
              </Link>
              <Link to="/news" className="block pb-4" onClick={toggleModal}>
                News
              </Link>
              <Link to="/login" className="block pb-4" onClick={toggleModal}>
                Login
              </Link>
              <Link to="/register" className="block pb-4" onClick={toggleModal}>
                Sign Up
              </Link>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default HamburgerMenu;

Details.jsx:

import { useState } from "react";
import { FaImage } from "react-icons/fa";
import Rating from "../components/Rating";
import Slider from "react-slick";
import clubs from "../clubs";

function Details() {
  const [activeDiv, setActiveDiv] = useState(0);
  const [showMoreDetails, setShowMoreDetails] = useState(false);
  const [showMoreAssessment, setShowMoreAssessment] = useState(false);

  const handleClick = (index) => {
    setActiveDiv(index);
  };
  console.log(clubs);

  let description = (
    <section aria-label="Description">
      <div className="my-2">Price: ${clubs.Prices.New} new</div>

      <div className="my-2">
        Details:{" "}
        {showMoreDetails
          ? clubs.description
          : `${clubs.description.substring(0, 250)}`}{" "}
        <span
          onClick={() => setShowMoreDetails(!showMoreDetails)}
          className="underline text-blue-500"
        >
          {showMoreDetails ? " less" : "...more"}
        </span>
      </div>
      <div className="my-2">
        Assessment:{" "}
        {showMoreAssessment
          ? clubs.assessment
          : `${clubs.assessment.substring(0, 250)}`}{" "}
        <span
          onClick={() => setShowMoreAssessment(!showMoreAssessment)}
          className="underline text-blue-500"
        >
          {showMoreAssessment ? " less" : "...more"}
        </span>
      </div>
    </section>
  );
  let reviews = (
    <section aria-label="Reviews">
      <Rating value={1.5} color={"#f8e825"} />
      <div className="text-sm">{clubs.reviews}</div>
      <Rating value={5} />
    </section>
  );
  let buyNow = (
    <section aria-label="Buy Now">
      <div className="flex flex-col">
        <button className="w-full p-2 bg-green-400 text-white my-2">
          Buy at 
        </button>
        <button className="w-full p-2 bg-green-400 text-white my-2">
          Buy at 
        </button>
      </div>
    </section>
  );

  const data = [description, reviews, buyNow];

  // Image data for the slider
  const images = [
    "/logo1.jpg",
    "/logo2.png",
    "/logo3.png",
  ];

  // Slider settings
  const sliderSettings = {
    dots: false,
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
    swipeToSlide: true,
  };

  return (
    <section className="py-2 px-8">
      <div className="text-xl font-bold mb-3">Club Name</div>
      <div className="w-full h-80">
        {images.length > 0 ? (
          <Slider {...sliderSettings} className="relative z-10">
            {images.map((image, index) => (
              <div key={index}>
                <img
                  src={image}
                  alt={`Slide ${index + 1}`}
                  className="w-full h-80 object-contain"
                />
              </div>
            ))}
          </Slider>
        ) : (
          <div className="flex justify-center items-center bg-gray-300 w-full h-80">
            <FaImage size={80} />
          </div>
        )}
      </div>
      
      //*** Rest of code ***//

    </section>
  );
}

export default Details;

>Solution :

Consider having the fixed <section> element in App.jsx that wraps the <Header> be stacked above the <Slider> by applying a z-index value higher than 10. For example, try adding the z-50 class to it:

<Router>
  <section className="fixed bg-gray-100 z-50">
    <Header />
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading