JQuery is facing difficulty in animating a div following the completion of a "forwards" css animation

Check out this example: http://jsfiddle.net/nxsv5dgw/

A div appears on the stage and a CSS animation is applied to it. However, when attempting to use JQuery to animate the same properties that were animated by CSS, it seems to no longer work properly.

In the provided example, a CSS animation adjusts the width of a box. When clicking on the box, a JQuery animation is supposed to shrink both the width and height, but only the height changes. Here's the code snippet:

$(".a").click(function(e) {
  $(this).animate({
    width: "-=100px", // does not work after CSS animation
    height: "-=100px",
  }, 400); 
})

.a {
  background:red;
  position:absolute;
  height:500px;
  width:600px;
  animation: anim 0.4s forwards 1s;
}

@keyframes anim {
  0% {width:600px;}
  100% {width:500px;}
}

Is there a way to work around this issue? I would prefer to avoid performing all animations using JQuery if possible.

Answer №1

Tested and optimized for Firefox, I have made adjustments to your Fiddle by including the following code:

$(this).css({
    "width": $(this).width(),
    "animation": "none"
});

This code snippet sets the width to its actual value and disables the animation. However, I acknowledge that there might be a more elegant solution rather than this workaround.

Update - confirmed to also work on Safari and IE browsers.

Answer №2

After the animation finishes, you can specify a width of 500px for the DOM element so that it recognizes the DIV as having a width of 500px, and then remove the CSS animation from the Element.

$(".a").on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function () {
    $(this).width(500);
    $(this).css({
            "animation": "none"
        });
    $(".a").click(function (e) {
        $(this).animate({
            width: "-=100px",
            height: "-=100px",
        }, 400);
    });
});

Idea: To prevent conflicts between CSS animation and jQuery animation, it is best to trigger the jQuery animation only after the CSS animation has finished by using the

animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd
event. Also, make sure to revert any CSS animation rules and remove the animation from the element.

See Working Example Here

Answer №3

When it comes to animation, the use of forward is crucial.

Referencing the CSS Animations Working Draft

The CSS Animations have a significant impact on computed property values. Throughout an animation's execution, the computed value for a property is under the control of the animation itself. This takes precedence over the value specified in the regular styling system. While animations override standard rules, they can be overridden by !important rules.

Additionally, looking at Animation Duration

[…] An animation that fills forwards will maintain the value assigned at the 100% keyframe, even if the animation was immediate. In addition, animation events continue to be triggered.

By default, this cannot be overridden, with the exception of !important rules. Nevertheless, achieving this with jQuery.animate() is not feasible.

If possible, I would prefer to minimize the utilization of JQuery for all animations.

Unfortunately, it seems unavoidable.

A potential jQuery approach could be:

$(document).ready(function() {
  $('.a').delay(1000).animate({
    width: "-=100px"    
  }, 400);
  
});

$(".a").click(function(e) {
  $(this).animate({
    width: "-=100px", // doesn't work after CSS animation
    height: "-=100px",
  }, 400); 
})
.a {
  background:red;
  position:absolute;
  height:500px;
  width:600px;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a"></div>

Answer №4

It may not be the exact solution you're looking for, but consider this alternative approach.

The issue seems to stem from how animations take precedence over normal rules, unless overridden by !important rules ()

Animations override all normal rules, but are overriden by !important rules

One potential workaround is to animate the scale transform instead. This way, you avoid changing properties affected by the animation. Although jQuery does not directly support this, you can achieve it with a plugin like this one: https://github.com/rstacruz/jquery.transit.

This method also offers a significant performance improvement compared to animating width and height, as detailed here: http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

Keep in mind that scaling down the div will also shrink its contents, which might not be the desired outcome.

You can view a demo showcasing this technique here: http://jsfiddle.net/nxsv5dgw/13/

Here's the code snippet:

$(".a").click(function (e) {
    $(this).transition({
        scale: '-=0.1'
    }, 4000);
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Disabling an HTML attribute on a button prevents the ability to click on it

In my React application, I have a button component that looks like this: <button onClick={() =>alert('hi')} disabled={true}>test</button> When I removed the disabled attribute from the browser like so: <button disabled>test& ...

Display a dialogue box when encountering a Vuetify error. Only open the dialogue box under certain conditions

I am currently implementing vuetify into my project. The main issue I am facing is related to the dialog component, which I only want to open in case of an error. The scenario involves a button calling a backend service to save a product in the database, a ...

Ways to incorporate bold, unbold, and italic styles into a single heading text within the same line using Bootstrap 4

Is there a way to format a single line of text with certain words bolded and the rest regular? I have a specific example pictured here: Picture of my Issue Specifically, I'm looking to bold "Honors:" and "Capstone:", while keeping the surrounding tex ...

Create a personalized Command Line Interface for the installation of npm dependencies

I am looking to develop a Node CLI tool that can generate new projects utilizing Node, Typescript, Jest, Express, and TSLint. The goal is for this CLI to create a project folder, install dependencies, and execute the necessary commands such as npm i, tsc - ...

This code is only functional on JSFiddle platform

I encountered an issue with my code recently. It seems to only work properly when tested on jsfiddle, and I can't figure out why it's not functioning correctly on codepen or when run from local files. Why is this code specific to jsfiddle? When ...

Padding on a flex item nudges a neighboring flex item out of place

Encountering an issue - within a div container, I have 4 nested divs using the grid system. Oddly enough, the third div in the grid is not behaving as expected. When setting a margin-bottom for this div, instead of creating space at the bottom, it pushes ...

What is the best method for exporting a MapboxGL map?

I am currently utilizing mapboxGL to display maps on a website, and I am interested in exporting the map as an image with the GeoJSON data that has been plotted. I attempted to use the leaflet plugin for this purpose, but it was unable to render clusters ...

How can I make <p> elements change color when scrolling?

My Goal https://i.sstatic.net/JbdXR.gif I aim to bring attention to the <p> element as the user scrolls on the page. Initially, the opacity is set to 0.3, but I want it to change to 1 gradually as the user scrolls down. My Attempt window.o ...

Save the function as a local variable and preserve the reference to the current object

In the prototype of my Car object, I have a function that looks like this: Car.prototype.drive = function() { this.currentSpeed = this.speed; } I find myself needing to call this drive function frequently within another function of the Car prototype. ...

What is the best way to ensure my fetchMovieDescription function is executed only after the story state has been updated?

I am facing a challenge with the fetchMovieDescription function. It is being called simultaneously with fetchBotReply instead of after my story state is updated. As a result, it generates a random image rather than using the one from the story result. impo ...

The communication hub in a Vue.js application

I'm currently developing a Vue single-page project and I have implemented an empty Vue instance as a central event bus. However, I've encountered an issue when trying to fire an event. eventbus.js import vue from 'Vue' export default ...

A platform for creating ER and flow diagrams specifically tailored for web applications, utilizing open source software

Our team is currently working on creating a web application that enables users to create diagrams, such as flow or ER diagrams. We are looking for ways to convert these diagrams into XML or other formats for representation. Are there any open-source soft ...

How to troubleshoot an Ionic exception occurring during the execution of any Ionic command?

Whenever I attempt to run an ionic command, I keep encountering this error message: { Error at FatalException.Exception (C:\Users\crist\AppData\Roaming\npm\node_modules\ionic\node_modules\@ionic\cli-u ...

CSS styling for a background image in the header

Why isn't my background image showing up even though I've used a direct link to the image? What could be causing this issue? .header { background-image: url("https://www.africa.com/wp-content/uploads/2015/07/Kenya.jpg"); background-attac ...

Create your own unique Semantic UI themes using the Semantic UI theme builder, complete with support for Font Awesome classnames and the ability to preview them with the

My admiration for Semantic UI and Semantic UI React knows no bounds. Not only are they phenomenal libraries, but their documentation is truly a work of art. Yet, crafting and keeping up with themes for these components can be quite the challenge. The task ...

Encountering a problem with configuring webpack's CommonsChunkPlugin for multiple entry points

entry: { page1: '~/page1', page2: '~/page2', page3: '~/page3', lib: ['date-fns', 'lodash'], vendor: ['vue', 'vuex', 'vue-router'] }, new webpack.optimize.C ...

Checking the list box and radio button using JavaScript based on their respective IDs

Looking to validate the selection of a listbox and radio button using their respective IDs when a submit action occurs. When testing in the browser, no alert is being displayed. The goal is to trigger the script upon clicking the submit button to verify ...

Utilizing v-model dynamically to showcase the outcomes of a specific property within a v-for iteration

As I iterate over an array using v-for, the number of items in this array varies each time. Currently, I am able to input values into the fields and have them correctly update the data property associated with them. However, there are two issues that need ...

Navigating in AngularJS with various URL parameters

Within my application, I am in need of using routes that require multiple attributes from the URL to be passed into PHP. The current setup that is functioning correctly is as follows: .when('/jobs/:type', { templateUrl: function(attrs){ ...

Exploring MapQuest API: Unraveling the process of dissecting MapQuest

I am currently exploring MapQuest navigation and utilizing JavaScript code to retrieve the data. Although I am able to extract JSON content in my application, I am unsure of how to utilize this data for navigation. I have started a new project and execute ...