dcochran
dcochran

Reputation: 1105

CSS3 animation firing just once in Firefox using Jquery add/remove class events

I've run across a number of posts here detailing problems with CSS3 animations not working properly in Firefox, even one where the animation fires just once:

Firefox only runs the CSS animation once

and

Documented bugs of Firefox/jQuery/CSS animations together?

but these fixes were not relevant for my issue. I've got these animations working in Safari/Chrome, and even have correct vendor prefixes for all the css (even though firefox shouldn't need them). I'm using Jquery add / remove class events to trigger the animations, and I can see in firebug that the classes are changing when I expect them to.

the only issue is the animation fires the first time, but never again, and just defaults to making the panel disappear and reappear

CSS:

/* CUSTOM SLIDING PANEL */
@-webkit-keyframes panelSlideLeft {
    from {
        opacity: $panelOpacityStart;
        -webkit-transform: translateX(0);
    }
    to {
        opacity: $panelOpacityEnd;
        -webkit-transform: translateX($panelWidth);
    }
}
@-moz-keyframes panelSlideLeft {
    from {
        opacity: $panelOpacityStart;
        -moz-transform: translateX(0);
    }
    to {
        opacity: $panelOpacityEnd;
        -moz-transform: translateX($panelWidth);
    }
}
@keyframes panelSlideLeft {
    from {
        opacity: $panelOpacityStart;
        transform: translateX(0);
    }
    to {
        opacity: $panelOpacityEnd;
        transform: translateX($panelWidth);
    }
}

.slide-panel-left-open {
    opacity: $panelOpacityEnd;
    -webkit-animation: panelSlideLeft $animationDuration linear;
    -moz-animation: panelSlideLeft $animationDuration linear;   
    animation: panelSlideLeft $animationDuration linear;            
    -webkit-transform: translateX($panelWidth);
    -moz-transform: translateX($panelWidth);
    transform: translateX($panelWidth);
}
.slide-panel-left-close {
    -webkit-animation: panelSlideLeft $animationDuration linear reverse;
    -moz-animation: panelSlideLeft $animationDuration linear reverse;   
    animation: panelSlideLeft $animationDuration linear reverse;            
} 

And in the javascript, I use a boolean to determine which classes to modify, and slidePanel.side is set on the Jquery object and is changing as expected to 'left' or 'right', even in Firefox (there is a right sliding panel that also uses this function).

JS:

slidePanel.bind('togglePanel', function() {
    if(slidePanel.open) {
        slidePanel.removeClass('slide-panel-' + slidePanel.side + '-open');
        slidePanel.addClass('slide-panel-' + slidePanel.side + '-close');
    } else {
        slidePanel.removeClass('slide-panel-' + slidePanel.side + '-close');
        slidePanel.addClass('slide-panel-' + slidePanel.side + '-open');
    }
    slidePanel.open = slidePanel.open ? false : true;   
});

Upvotes: 2

Views: 1742

Answers (1)

gooberverse
gooberverse

Reputation: 265

Regardless of whether this is an actual bug or not, I think a functional example is what is being requested.

I created a fiddle that implements an animation that toggles using classes when an object is clicked.

CSS Animation jsFiddle:

http://jsfiddle.net/aA5k7/9/

Please excuse the crudity of this example. The original question did not include HTML and the CSS referenced some variables such as #panelWidth, so I took some creative license and tried to create a working example that maintains the spirit of the original.

In the CSS (which supports Webkit and Mozilla, but does not include the non-prefix options for brevity), I specify the animation parameters individually using the longhand format.

The animation-fill-mode property is especially important to understand. You can read more here: http://www.w3schools.com/cssref/css3_pr_animation-fill-mode.asp

HTML:

<div id="slidePanel">Slide Panel</div>

CSS:

/* CUSTOM SLIDING PANEL */
@-moz-keyframes panelSlideLeft {
    from {
        opacity: 1.0;
        -moz-transform: translateX(200px);
    }
    to {
        opacity: 1.0;
        -moz-transform: translateX(0px);
    }
}
@-moz-keyframes panelSlideRight {
    from {
        opacity: 1.0;
        -moz-transform: translateX(0px);
    }
    to {
        opacity: 1.0;
        -moz-transform: translateX(200px);
    }
}

@-webkit-keyframes panelSlideLeft {
    from {
        opacity: 1.0;
        -webkit-transform: translateX(200px);
    }
    to {
        opacity: 1.0;
        -webkit-transform: translateX(0px);
    }
}
@-webkit-keyframes panelSlideRight {
    from {
        opacity: 1.0;
        -webkit-transform: translateX(0px);
    }
    to {
        opacity: 1.0;
        -webkit-transform: translateX(200px);
    }
}
.slide-panel-right {
    -moz-animation-name: panelSlideRight;
    -moz-animation-duration: 0.35s;
    -moz-transition-timing-function: ease-in;
    -moz-animation-iteration-count: 1;
    -moz-animation-fill-mode: both;
    -webkit-animation-name: panelSlideRight;
    -webkit-animation-duration: 0.35s;
    -webkit-transition-timing-function: ease-in;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: both;    
}
.slide-panel-left {
    -moz-animation-name: panelSlideLeft;
    -moz-animation-duration: 0.35s;
    -moz-transition-timing-function: ease-in;
    -moz-animation-iteration-count: 1;
    -moz-animation-fill-mode: none;
    -webkit-animation-name: panelSlideLeft;
    -webkit-animation-duration: 0.35s;
    -webkit-transition-timing-function: ease-in;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: none;    
} 
#slidePanel {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 80px;
    height: 80px;
    border: 1px solid green;
    padding: 8px;
}

JS:

var open = false;

$("#slidePanel").on('click', function() {
  if(open) {
    $(this).removeClass('slide-panel-right');
    $(this).addClass('slide-panel-left');
  } else {
    $(this).removeClass('slide-panel-left');
    $(this).addClass('slide-panel-right');
  }
  open  = open ? false : true;   
});

Similar results (with less code) can be accomplished using CSS transitions. Here is another jsFiddle to demonstrate:

CSS Transitions jsFiddle

http://jsfiddle.net/aA5k7/11/

Upvotes: 1

Related Questions