12% off of LTD using this coupon: TWELVEPERCENTOFF. Promo ends on 2 Dec midnight UTC.
Published on Nov 29, 2021

Fixing Flickity’s issue with iOS15 Safari

David Browne

The latest iOS15 update brought with it an issue that has affected the way Flickity behaves in Safari. If you’re using the Flickity library on your site, here is a fix you can add inside of a code block to get the original smooth behavior back for that browser.

Note – for OxyExtras users this fix will be included for the carousel builder in the update coming this week.

The Problem

There were/are two problems;

The mobile Safari browser now retriggers the ‘resize’ event every time the user scrolls up or down, causing the address bar at the bottom of the browser to show/hide.

Some JS libraries like Flickity use this resize event to do calculations to work out the new positioning of elements when the viewport size is changed. This is a problem as it means if the user scrolls as the carousel is moving, the resize event will cause the carousel to keep trying to calculate the new postions. The result is that it will stop it from moving instantly and keep resetting it back to it’s original position.

The other issue is that the touchmove behavior was changed (they’ve made it harder to prevent scrolling the page). Usually, if the user is dragging the carousel with their finger, but isn’t quite moving 100% horizontally, the carousel would still move without issues and the page wouldn’t be scrolled. With the latest Safari, if the user is doing a slight diagonal movement, it would now scroll the page instead of moving the carousel.

The Solution

There have been some lively discussions on how to solve going around. After lots of testing, the most reliable way to solve, (without editing the Flickity library code directly), is by adding the following JS to a code block on the page where your Flickity carousel is.

This will both prevent the page from being scrolled if the user is dragging the carousel (even if diagonally) and also prevent Flickity from doing any resize calculations while the carousel is actually moving, so the result will always be smooth.

jQuery(document).ready(function($) {

    /* fix iOS touchmove issue */
    ;
    (function() {
        let touchingCarousel = false
        let startXCoordinate

        document.body.addEventListener('touchstart', e => {
            if (e.target.closest('.flickity-slider')) {
                touchingCarousel = true
            } else {
                touchingCarousel = false
                return
            }
            startXCoordinate = e.touches[0].pageX
        })

        document.body.addEventListener('touchmove', e => {
            if (
                !touchingCarousel ||
                !e.cancelable ||
                Math.abs(e.touches[0].pageX - startXCoordinate) < 8
            ) return
            e.preventDefault()
            e.stopPropagation()
        }, {
            passive: false
        })
    }())

    /* prevent resize in flickity if still animating */
    var resize = Flickity.prototype.resize;
    Flickity.prototype.resize = function() {
        if (!this.isAnimating) {
            resize.call(this);
        }
    };

});

If you have an iPhone with iOS15 and wanted to test, here is a page with this code already added.


https://demo.wplit.com/flickity-fix-ios15/fixed/

tagschevron-leftchevron-rightchainangle-rightangle-upangle-downfolder-omagnifiercrossmenuchevron-downarrow-right