javascripthtmlreactjstailwind-cssslideshow

React/Tailwind problem with slideshow height


I am new to web development and I'm learning to use React and Tailwind.

I am trying to do the "About us" section that should be made in the following way.
There are two components: a slideshow of images that automatically change every second and a paragraph with some text.

The two should be arranged like this:

  1. for large screens a row with the slideshow on the first column (left) and the paragraph on the second one (right).
  2. For smaller than large screens there should be 1 column and 2 rows with the slideshow on top and the paragraph on the bottom.

This is the code I have at the moment. It works but there is a problem: it seems like for case 2, it is not understanding correctly the height of the slideshow so the paragraph text is going on top of the slideshow images.

Is there any way to solve this? Thanks.

  const [currentSlide, setCurrentSlide] = useState(0);

  useEffect(() => {
    const interval2 = setInterval(() => {
      setCurrentSlide((prevSlide) =>
        prevSlide === images.length - 1 ? 0 : prevSlide + 1
      );
    }, 3000);

    return () => {
      clearInterval(interval2);
    };
  }, []);

<div className="grid grid-cols-1 grid-rows-2 lg:grid-rows-1 lg:grid-cols-2 w-full">
    {/* Images */}
    <div className="images lg:order-1" data-aos="fade-up">
        <div className="relative">
            {images.map((image, index) => (
                <div
                    key={image.id}
                    className={`absolute top-0 left-0 w-full h-full transition-opacity duration-1000 ${
                        index === currentSlide ? "opacity-100" : "opacity-0"
                    }`}
                >
                    <img src={image.img} className="rounded-md" alt="" />
                </div>
            ))}
        </div>
    </div>

    {/* About us */}
    <div className="lg:order-2 lg:mt-0 mx-auto space-y-4 lg:w-3/4 text-black" data-aos="fade-up">
        <h2 className="text-2xl font-semibold"> Title</h2>
        <p className="text-justify lg:text-start">
            About us 1.
        </p>
        <p className="text-justify lg:text-start">
           About us 2.
        </p>
        <p className="text-justify lg:text-start">
           About us 3.
        </p>
    </div>
</div>


Solution

  • The div.relative element has 0 height, since all elements inside have position: absolute. If all the images are the same size, you could consider not applying position: absolute to the first image. This then gives layout rectangle spacing, ensuring the text flows below the slider.

    const { useEffect, useState } = React;
    
    const images = [
      { img: 'https://picsum.photos/1920/1080' },
      { img: 'https://picsum.photos/1920/1080?' },
      { img: 'https://picsum.photos/1920/1080?0' },
    ];
    
    function App() {
      const [currentSlide, setCurrentSlide] = useState(0);
    
      useEffect(() => {
        const interval2 = setInterval(() => {
          setCurrentSlide((prevSlide) =>
            prevSlide === images.length - 1 ? 0 : prevSlide + 1,
          );
        }, 3000);
    
        return () => {
          clearInterval(interval2);
        };
      }, []);
    
      return (
        <div className="grid grid-cols-1 grid-rows-2 lg:grid-rows-1 lg:grid-cols-2 w-full">
          {/* Images */}
          <div className="images lg:order-1" data-aos="fade-up">
            <div className="relative">
              {images.map((image, index) => (
                <div
                  key={image.id}
                  className={`top-0 left-0 w-full h-full transition-opacity duration-1000 ${
                    index === currentSlide ? 'opacity-100' : 'opacity-0'
                  } ${index > 0 ? 'absolute' : ''}`}
                >
                  <img src={image.img} className="rounded-md" alt="" />
                </div>
              ))}
            </div>
          </div>
    
          {/* About us */}
          <div
            className="lg:order-2 lg:mt-0 mx-auto space-y-4 lg:w-3/4 text-black"
            data-aos="fade-up"
          >
            <h2 className="text-2xl font-semibold"> Title</h2>
            <p className="text-justify lg:text-start">About us 1.</p>
            <p className="text-justify lg:text-start">About us 2.</p>
            <p className="text-justify lg:text-start">About us 3.</p>
          </div>
        </div>
      );
    }
    
    ReactDOM.createRoot(document.getElementById('app')).render(<App />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdn.tailwindcss.com/3.4.3"></script>
    
    <div id="app"></div>