Search code examples
javascriptcssreactjscarousel

Fixing react-responsive-carousel display on mobile


I'm still a beginner with ReactJS and I need to create a Carousel that is responsive, the way I need to leave is like this:

I was able to create Carousel on both desktop and responsive using the react-responsive-carousel library.

The problem is that in the mobile format, when I pass the slides of each Carousel, the expected behavior is not happening. When I click to show the next slide, in Carousel it still shows the current slide, and just a piece of the next slide.

It is easier to explain by showing a short gif I made, notice what happens when I click to show the next slide.

When it is in the desktop format, Carousel works the right way, I also created a small gif to show it.

Can you tell me what you’re doing wrong so that Carousel is working that way?

import React from "react";
import PropTypes from "prop-types";
import "./carousel.scss";

import { Carousel as CarouselLib } from "react-responsive-carousel";

import { CAROUSEL_ITEMS } from "./Carousel.utils";

const Carousel = ({ subtitle, testID, title }) => {
  const items = React.useMemo(
    () =>
      CAROUSEL_ITEMS.map((item) => (
        <div key={item.id}>
          <div className="images">
            <img className="image" src={item.url} alt="" />
          </div>
          <div className="infos">
            <h3>{item.title}</h3>
            <span>{item.subtitle}</span>
          </div>
        </div>
      )),
    []
  );

  return (
    <div data-testid={`${testID}_Container`} className="carousel-container">
      <div className="carousel-header">
        <h5>{subtitle}</h5>
        <h3>{title}</h3>
      </div>
      <div className="carousel-content">
        <CarouselLib
          centerMode
          showStatus={false}
          dynamicHeight={false}
          emulateTouch
          swipeScrollTolerance={50}
          centerSlidePercentage={30}
          showThumbs={false}
          infiniteLoop
          showIndicators
          renderArrowPrev={(onClickHandler, hasPrev, label) =>
            hasPrev && <div />
          }
          renderArrowNext={(onClickHandler, hasNext, label) =>
            hasNext && (
              <button
                type="button"
                onClick={onClickHandler}
                className="custom-arrow"
                data-testid={`${testID}_Button_Next`}
              />
            )
          }
        >
          {items}
        </CarouselLib>
      </div>
    </div>
  );
};

Carousel.propTypes = {
  subtitle: PropTypes.string,
  testID: PropTypes.string.isRequired,
  title: PropTypes.string
};

Carousel.defaultProps = {
  testID: "Carousel",
  subtitle: "READ OUR CLIENT",
  title: "CASES"
};

export default Carousel;
.carousel {
  &-container {
    .images {
      background-color: #fff;
      width: 100%;
      max-width: 416px;
      height: 280px;

      .image {
        width: 100%;
        height: auto;
        background-position: center center;
        background-repeat: no-repeat;
      }

      @media (max-width: 600px) {
        max-width: 270px;
        height: auto;
      }
    }

    .infos {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: flex-start;

      h3 {
        font-family: Alliance2;
        color: #000;
        line-height: 0.76;
        font-size: 2.5rem;
        letter-spacing: normal;
        font-style: normal;
        font-weight: normal;
        font-stretch: normal;
        margin: 24px 0 20px 0;

        @media (max-width: 600px) {
          font-size: 1.5rem;
        }
      }

      span {
        font-family: Alliance2;
        color: #000;
        line-height: 0.76;
        font-size: 1rem;
        letter-spacing: normal;
        font-style: normal;
        font-weight: 500;
        font-stretch: normal;
        text-transform: uppercase;
        margin-bottom: 30px;

        @media (max-width: 600px) {
          font-size: 0.625rem;
        }
      }
    }

    .carousel {
      .slide {
        background-color: transparent !important;

        @media (max-width: 1024px) {
          min-width: 50% !important;
        }

        @media (max-width: 600px) {
          min-width: 90% !important;
        }
      }

      .control-dots {

        .dot {
          border-radius: 0 !important;
          background-color: #000 !important;
          width: 33px !important;
          height: 3px !important;
          box-shadow: none !important;
          opacity: 1 !important;

          &.selected {
            height: 7px !important;
          }

          &:focus {
            outline: none !important;
          }
        }
      }
    }
  }

  &-header {
    color: #000;
    font-family: 'Alliance2';
    font-weight: 300;
    margin: auto;
    max-width: 1300px;
    text-transform: uppercase;

    @media (max-width: 960px) {
      align-items: center;
      display: flex;
      flex-direction: column;
    }

    h5 {
      font-size: 1rem;
      font-weight: bold;
      margin: 0;
    }

    h3 {
      height: 80px;
      margin-top: 13px;
      margin-bottom: 44px;

      color: #000;
      font-size: 3.5rem;
      line-height: 1.04;
      letter-spacing: -1.1px;

      @media (max-width: 960px) {
        font-size: 1.87rem;
      }

      @media (max-width: 600px) {
        margin-bottom: 0;
      }
    }
  }

  &-content {
    margin: auto;
    max-width: 1440px;
    width: 100%;

    .custom-arrow {
      position: absolute;
      top: 7em;
      bottom: auto;
      right: 4.3em;
      background-color: transparent;
      border: none;
      border-left: 4px solid #000;
      border-bottom: 4px solid #000;
      width: 67px;
      height: 67px;
      transform: rotate(225deg);
      cursor: pointer;

      &:focus {
        outline: none !important;
      }
    }
  }
}

Thank you very much in advance for any help/tip.


Solution

  • I don't know react-responsive-carousel , I'm using react-slick (here) in my projects and I never had a problem with the responsive.