React-responsive-carousel: Swipeable not working on mobile

Created on 17 Mar 2021  路  9Comments  路  Source: leandrowd/react-responsive-carousel

Hi,

I'm using version 3.2.12 with Gatsby. Unfortunately I could not make swipeable work on mobile. Rarely it works only on first slide, and does nothing on other slides. Tested on mobile Safari and Chrome on an iPhone. emulateTouch works on desktop.

Here is the component:

import React from "react";

// requires a loader
import { Carousel } from "react-responsive-carousel";

const settings = {
  showArrows: false,
  interval: 3500,
  dynamicHeight: false,
  stopOnHover: false,
  infiniteLoop: true,
  showStatus: false,
  transitionTime: 500,
  showThumbs: false,
  showIndicators: true,
  swipeable: true,
  emulateTouch: true,
  autoPlay: true,
};

const TestimonialsCarousel = ({ testimonials }, featured) => (
  <Carousel {...settings}>
    {testimonials
      .filter((item) => (item.featured || !featured) == true)
      .map((item) => (
        <div key={item.quote}>
          <div className="has-text-left has-text-white is-size-6 is-family-secondary px-xxs">
            <blockquote>{item.quote}</blockquote>
          </div>
          <div className="has-text-left has-text-white has-text-weight-medium testimonialauthor pt-small px-xxs">
            <p>鈥攞item.author}</p>
          </div>
        </div>
      ))}
  </Carousel>
);

export default TestimonialsCarousel;

Here is the link to test. Please try to swipe "Quotes" section where testimonials are shown.

I am stuck, and I don't prefer to switch back to react-slick which has its own problems. Any help is appreciated. Thanks.

Most helpful comment

I have the same issue and I've found the reason for your and my case. When the second slide is active, the ul.slider element (that listens to the touch events) stays on the left. The blue highlight on the screenshot below is that element:

Screen Shot 2021-06-28 at 19 29 31

iOS Safari handles touch events only on the element itself and not on its children. Therefore, when you touch a slide, nothing happens. In fact, you can swipe from the second slide if you start swiping from the very left of the screen.

In order to fix it, you need to make the ul.slider element always stay on the screen. A way to do it is creating a very long ::before block that stays under every slide:

/* Add this CSS to your website */
.slider {
  position: relative;
}
.slider::before {
  content: '';
  position: absolute;
  top: 0;
  left: 100%;
  width: 10000%;
  height: 100%;
}

For some reason Safari watches touch events on the ::before block and not on the child elements. Newertheless, it works.

A proper solution for the library author is attaching the touch event listeners to div.slider-wrapper instead of ul.slider.

All 9 comments

I just tested and It works on my phone. I guess we have a case of it didn't work on my machine, which is rare.

Thanks @Fox4148 . I am testing with iOS (14.4.1) on Safari and Chrome. It only works on 1st slide, can't swipe rest of them. :/

@abdullahe after looking at the inspector, I've noticed that there isn't any transform css, maybe you are not including the component css?

@Fox4148 I included the component's css. Not sure if it uses transform (css) or js.

I think it is weird that both carousels (quotes and recognition) is swipeable on only first slide.

Is there any way how to swipe any item of the carousel. I am currently using disposition of 3 items on the page with prop centerSlidePercentage={33.33} and the only middle item is swipeable, which resulting in quite confusing UX.

I have the same issue and I've found the reason for your and my case. When the second slide is active, the ul.slider element (that listens to the touch events) stays on the left. The blue highlight on the screenshot below is that element:

Screen Shot 2021-06-28 at 19 29 31

iOS Safari handles touch events only on the element itself and not on its children. Therefore, when you touch a slide, nothing happens. In fact, you can swipe from the second slide if you start swiping from the very left of the screen.

In order to fix it, you need to make the ul.slider element always stay on the screen. A way to do it is creating a very long ::before block that stays under every slide:

/* Add this CSS to your website */
.slider {
  position: relative;
}
.slider::before {
  content: '';
  position: absolute;
  top: 0;
  left: 100%;
  width: 10000%;
  height: 100%;
}

For some reason Safari watches touch events on the ::before block and not on the child elements. Newertheless, it works.

A proper solution for the library author is attaching the touch event listeners to div.slider-wrapper instead of ul.slider.

Thank you @Finesse

I will update as soon as I try your solution. Cheers.

@Finesse Thanks for the solution. It is working now!
If anyone is having the same issue, be sure to clear website data of Safari from iOS settings to load new css.

@Finesse very smart

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adomoshe picture adomoshe  路  5Comments

Jordanh1996 picture Jordanh1996  路  6Comments

LeopoldLerch picture LeopoldLerch  路  5Comments

ajmas picture ajmas  路  5Comments

sprlwrksAprilmintacpineda picture sprlwrksAprilmintacpineda  路  6Comments