Search code examples
javascriptcssreactjssafarianime.js

Flip Card Bug Safari


I develop a website custom card carousel with react.js and anime.js. I do a flip animation on the card in the center of the screen. It work fine with opera, firefox and chrome but I have an issue with safari. I test it with safari 13.0.4. And the animation is ok but just after the animation, the text go behind the card. And after the 3rd iteration it work fine.

front card

back card Opera, Chrome, Firefox and on Safari (after the 3rd flip for Safari)

back card Safari

back card Safari without color and with black text

Here my css:

.partner-card-focused--background__extern {
    transition: background-color 0.35s ease-in-out;
    border-bottom-right-radius: 5.5vh;
    height: 50vh;
    width: 35vh;
    margin-left: 2vw;
    margin-right: 2vw;
    margin-top: 3.8vh;
    padding: 1vh;
    box-shadow: 15px 15px 20px rgba(0, 0, 0, 0.50);
    position: relative;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -ms-transform-style: preserve-3d;
}

.front,
.back
{
    width: 100%;
    height: 100%;
    position: absolute;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    backface-visibility: hidden;
}

.front {
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
    -moz-transform: translateZ(0);
    -ms-transform: translateZ(0);
}

.back-hidden {
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    backface-visibility: hidden;
}

.back {
    top: 0;
    left: 0;
    transform: rotateY(180deg) translateZ(0);
    -webkit-transform: rotateY(180deg) translateZ(0);
    -moz-transform: rotateY(180deg) translateZ(0);
    -ms-transform: rotateY(180deg) translateZ(0);
}

.partner-card-focused--background__intern {
    border-bottom-right-radius: 4.5vh;
    height: 50vh;
    width: 35vh;
    overflow: hidden;
    position: relative;
    z-index: 2;
}

.partner-card-focused--image {
    position: relative;
    z-index: 1;
    width: 100%;
}

.partner-card-focused--description {
    position: fixed;
    margin: 1vh;
    font-size: 2vh;
    display: block;
}

Here my react render methode:

render() {
        let overClass = "";
        if (this.state.hover)
            overClass += " blue-color--back"
        else
            overClass += " black-color--back"
        return (
            <div>
                <div className="partner-card-focused--text--container">
                    <div className="partner-card-focused--square blue-color--back"/>
                    <Typing text={this.state.partner.name} startTime={450} spacetime={80} class="partner-card-focused--text black-color font-first" />
                </div>
                <div ref={this.targetContainer}>
                <div className={"partner-card-focused--background__extern button" + overClass} onClick={this.click} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover} ref={this.targetCard}>
                    <div className="front">
                        <h1 className="partner-card--text white-color font-first select-none back-hidden">{this.state.partner.name}</h1>
                        <div ref={this.targetBackgroundIntern} className="partner-card-focused--background__intern white-color--back back-hidden">
                            <img ref={this.targetImage} src={this.state.partner.image} className="partner-card-focused--image select-none back-hidden" alt="Focused partenaire poster"/>
                        </div>
                    </div>
                    <div className="back">
                        <p className="partner-card-focused--description white-color font-first back-hidden">{this.state.partner.description}</p>
                    </div>
                </div>
                </div>
            </div>
        )
    }

And the flip methode:

this.flipped = !this.flipped;
let callback = () => {this.playing = false;}
anime({
     targets: this.targetCard.current,
     scale: [{value: 0.90}, {value: 1.25}, {value: 1, delay: 250}],
     rotateY: {value: '+=180', delay: 200},
     easing: 'easeInOutSine',
     duration: 400,
     complete: function(){
          callback();
     }
});

Thanks in advance for any help.


Solution

  • As Safari doesn't manage correctly transform-style with preserve-3d, you should put 1px to translateZ() into .back class to avoid that glitch.