Mathieu Ferraris
Mathieu Ferraris

Reputation: 97

Bug with Safari only

I made a React component that changes dynamically the background of 4 divs in an infinite loop, each time it changes the background, there's a css animation triggered with a toggle class.

To get all the images, I'm using the Webpack 'require.context' function paired to the url-loader to have an array of base64 data url to use them as the new source for the background.

The way I've done that works as expected in Chrome (69.0.3497.100), Opera (56.0.3051.43) and Firefox (62.0.3). But it doesn't work well in Safari (12.0), I can see some "glitches".

When I inspect the page, I can see that the animation is triggered correctly, but the images appear after it, and sometimes the image is not visible.

Another strange behavior, is that it affects fixed element that are above the section that contains the divs, they are blinking.

I recorded the problem so you can see what I mean: https://www.youtube.com/watch?v=EO-9Ks-FhOo

There's also a staging version of it here. http://ferrarism.at/today/staging

Here's my React component :

import React from "react"



function importAll(r) {
return r.keys().map(r);
}

const imageArray = importAll(require.context('../img/clients', true));



export default class ClientReel extends React.Component {
constructor(props){
    super(props);
    this.state = {
        images: imageArray
    }
}
render(){
    const {images} = this.state



    var count;
    const randomClient = [];

    for (count = 1; count <= 4; ++count) {
        var i = Math.floor((Math.random() * (images.length - count)) + 1);
        randomClient.push(images[i]);
        images[i] = images[images.length - count];
    }

    const ImagesToRender = randomClient.map((item, i) => {
            return (
                <div key={i} className="clientReel-item">
                    <div className="itemImage" style={{ background: `url(${item}) center center / 100% no-repeat` }}></div>
                </div>
            )
    })
    return(
        <React.Fragment>
            {ImagesToRender}
        </React.Fragment>
    )
}

componentDidMount(){
    const {images} = this.state
    const reelItemImage = document.querySelectorAll(".itemImage")
    const reelItems = document.querySelectorAll(".clientReel-item")
    var i = 0;
    var f = 0;

    var timing = 500;
    (function loop() {
        setTimeout(function () {
            reelItems[i].classList.toggle("reelFlip")
        }, timing - 100)
        if (f < (images.length - 1)) {
            f++;
            reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
        } else {
            f = 0;
            reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
        }
        if (i < (reelItems.length - 1)) {
            i++;
        } else {
            i = 0;
        }
        setTimeout(loop, timing);
    })();
}
}

Here's my component compiled css:

.section__client-reel .wrapper #clientReel .clientReel-item {
    flex-basis: 21.739%;
    height: 91px;
    margin: 18px 0;
    transform: rotateX(0deg);
    transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
    -webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1); 
}

.section__client-reel .wrapper #clientReel .clientReel-item .itemImage {
      width: 100%;
      height: 100%; 
}

.section__client-reel .wrapper #clientReel .reelFlip {
    transform: rotateX(-180deg);
    -webkit-transform: rotateX(-180deg);
    transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
    -webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
 }

.section__client-reel .wrapper #clientReel .reelFlip .itemImage {
      transform: rotateX(180deg);
      -webkit-transform: rotateX(180deg); 
}

It's been hours that I'm looking for a solution but I found nothing. If you have some idea, feel free !

Upvotes: 0

Views: 1911

Answers (2)

Mathieu Ferraris
Mathieu Ferraris

Reputation: 97

[FIX] Adding transform: translate3D(0,0,0) to the parent element solved the problem

Upvotes: 1

Mathieu Ferraris
Mathieu Ferraris

Reputation: 97

[EDIT] Just tried to do it with PHP, I encountered the exact same issue as with React, so now I'm almost sure that it's a css related problem.

It happens with this Css property:

transform: rotateX(-180deg)

If I use:

transform: rotateZ(-180deg)

instead of the rotateX there's no more "glitches" But I would like to have it on rotateX. Using TweenMax could be a valid option, right? (I already have GSAP as a dependency)

Upvotes: 0

Related Questions