Is there a framework available to animate Pseudo CSS elements?

Recently, I was working on developing a bar chart that utilized pseudo CSS elements (::before, ::after).

While I successfully created bars that look visually appealing, I encountered a challenge when attempting to animate the height changes. Whenever I used the animate function, the pseudo elements would vanish and only reappear once the animation was complete. Does anyone have any suggestions or ideas on how I can achieve this smoothly? Perhaps there is another animation framework available that will render the pseudo elements seamlessly?

Feel free to check out the CodePen link: http://codepen.io/anon/pen/OyGamW

HTML:

<ul><li><div class="fill bar1">100%</div></li></ul>

CSS:

*{
  padding:0;
  margin: 0;
}
body {
    height: 100%;
    background-repeat: no-repeat;
    background-attachment: fixed;
  background:#cdcdcf;
  overflow: hidden;
}

ul {
  list-style-type:none;
  overflow:hidden;
  padding-left:10px;
  padding-top:40px;
}
li{
float:left;
height:800px;
margin-top: 30px;
}

.fill {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 90px;
  line-height: 90px;
  position: relative;
  height: 300px;
  top: 161px;
  padding: 0px 0px 0px 8px;
  left: 70px;
  border: none;
  font: normal normal bold 26px/normal Tahoma, Geneva, sans-serif;
  color: rgba(255,255,255,1);
  text-align: left;
  -o-text-overflow: clip;
  text-overflow: clip;
  background: -webkit-linear-gradient(0deg, rgba(255,43,43,1) 0, rgba(209,31,31,1) 100%);
  background: -moz-linear-gradient(90deg, rgba(255,43,43,1) 0, rgba(209,31,31,1) 100%);
  background: linear-gradient(90deg, rgba(255,43,43,1) 0, rgba(209,31,31,1) 100%);
  background-position: 50% 50%;
  -webkit-background-origin: padding-box;
  background-origin: padding-box;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  -webkit-background-size: auto auto;
  background-size: auto auto;
  -webkit-transform:  scaleX(1) scaleY(1) scaleZ(1)  skewY(-3deg);
  transform:  scaleX(1) scaleY(1) scaleZ(1)  skewY(-3deg);
  -webkit-transform-origin: 0 0 0;
  transform-origin: 0 0 0;
  -webkit-box-shadow: 0 11px 18px -5px #841313 inset;
  box-shadow: 0 11px 18px -5px #841313 inset;
}

.fill::before {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 50%;
  height: 100%;
  position: absolute;
  content: "";
  top: 0;
  left: 0;
  border: none;
  font: normal normal normal 16px/normal "Times New Roman", Times, serif;
  color: rgba(0, 0, 0, 0.901961);
  -o-text-overflow: clip;
  text-overflow: clip;
  background: -webkit-linear-gradient(-180deg, #c62121 0, rgba(132,19,19,1) 100%);
  background: -moz-linear-gradient(270deg, #c62121 0, rgba(132,19,19,1) 100%);
  background: linear-gradient(270deg, #c62121 0, rgba(132,19,19,1) 100%);
  background-position: 50% 50%;
  -webkit-background-origin: padding-box;
  background-origin: padding-box;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  -webkit-background-size: auto auto;
  background-size: auto auto;
  text-shadow: none;
  -webkit-transform:  scaleX(1) scaleY(1) scaleZ(1) translateX(-44px) skewY(20deg);
  transform:  scaleX(1) scaleY(1) scaleZ(1) translateX(-44px) skewY(20deg);
  -webkit-transform-origin: 100% 100% 0;
  transform-origin: 100% 100% 0;
  -webkit-box-shadow: 0 11px 18px -5px #841313 inset;
  box-shadow: 0 11px 18px -5px #841313 inset;
}

.fill::after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 100%;
  height: 16.1px;
  position: absolute;
  content: "";
  top: -1px;
  left: 0;
  border: none;
  font: normal normal normal 16px/normal "Times New Roman", Times, serif;
  color: rgba(0, 0, 0, 0.901961);
  -o-text-overflow: clip;
  text-overflow: clip;
  background: rgba(132,19,19,1);
  text-shadow: none;
  -webkit-transform:  scaleX(1) scaleY(1) scaleZ(1) translateX(-50%) translateY(-91%) skewX(70.5deg);
  transform:  scaleX(1) scaleY(1) scaleZ(1) translateX(-50%) translateY(-91%) skewX(70.5deg);
  -webkit-transform-origin: 0 0 0;
  transform-origin: 0 0 0;
}

JS:

$(document).ready(function() {
    setInterval(function() {
        doAnimation();
    },4000);
    doAnimation();
});
function doAnimation() {
  $('.fill').animate({ "height": "150px", "top": "311px"}, 1000);
  $('.fill').delay(1000).animate({ "height": "300px", "top": "161px"}, 1000);
}

If you have any insights or suggestions, please feel free to share. Thank you!

Answer №1

It's not entirely clear how GSAP's TweenMax differs from jQuery's .animate() method in this specific scenario, but substituting your animation with TweenMax resolves the issue.

JavaScript:

TweenMax.to('.fill', 1, {
  height: 150,
  top: 311,
  repeat: -1,
  yoyo: true,
  ease: Expo.easeInOut
});

On a side note, I highly recommend utilizing GSAP for all your JS animation requirements. Explore the documentation for available methods and properties.

Here is the link to your modified pen.

I hope this information proves helpful.

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

Determine the number of occurrences of specific values within a group of objects based on a

I have the following dataset: const data2 = [ { App: "testa.com", Name: "TEST A", Category: "HR", Employees: 7 }, { App: "testd.com", Name: "TEST D", Category: "DevOps", Employee ...

Issue encountered: NPM error, unable to find solution for resolving dependency and addressing conflicting peer dependency

I am facing difficulties deploying my project on netlify due to NPM errors. Below are the dependencies: "dependencies": { "@angular/animations": "~15.1.1", ... (list of dependencies continues) ...

Display a D3 Collapsible Tree visualization using information stored in a variable

I am currently working on an app that requires the display of a collapsible tree graph using D3. The data needed for this graph is not stored in a file, but rather within the database. It is retrieved through an Ajax call to a rest service and then passed ...

Using the methods res.render() and res.redirect() in Express.js

I'm facing a challenge with a route in my express app, where I need to achieve the following: Retrieve data from an external source (successful) Show an HTML page with socket.io listening for messages (successful) Conduct lengthy calculations Send a ...

Copy values of multiple input fields to clipboard on click

I have a collection of buttons in my Library, each with different text that I want to copy when clicked function copyTextToClipboard(id) { var textElement = document.getElementById(id); textElement.select(); navigator.clipboard.writeText(textElement. ...

Managing various encoding methods when retrieving the XML data feed

I'm attempting to access the feed from the following URL: http://www.chinanews.com/rss/scroll-news.xml using the request module. However, the content I receive appears garbled with characters like ʷ)(й)޹. Upon inspecting the XML, I noticed that ...

What causes an absolutely positioned element to be positioned by its sibling rather than at the top corner of the page?

Can someone explain to me why my absolutely positioned element is displaying after my child_static div? I'm under the impression that absolutely positioned elements are removed from the normal flow. So why isn't child_absolute covering the child_ ...

Do we really need to use redux reducer cases?

Is it really necessary to have reducers in every case, or can actions and effects (ngrx) handle everything instead? For instance, I only have a load and load-success action in my code. I use the 'load' action just for displaying a loading spinne ...

What steps can be taken to revert this Node.js module to a particular version and ensure it does not automatically update in

While using the Nodemailer module in node.js, I encountered a specific error that read as follows; [Error: Unsupported configuration, downgrade Nodemailer to v0.7.1 or see the migration guide https://github.com/andris9/Nodemailer#migration-guide] A ...

Instructions for converting a readonly text field into an editable one using JavaScript

I'm trying to make it so that when the button (with id name_button) is clicked, the text field (with id name_text_field) becomes enabled. However, my current code doesn't seem to be working. Here's a snippet of my HTML: <input type="tex ...

When utilizing a JQuery .animate function to transition a div from 0px to 450px in height, an unintended margin is produced during the process

I have been attempting to implement a collapsible footer using JQuery. While I have successfully integrated all the animation functions, there seems to be an issue with the animate function affecting the div (id=draw) by creating an unseen margin beneath i ...

What is the best way to retrieve a value in Ajax?

I'm trying to assign the result of an MVC controller method to a variable. function someFunction(){ var result; $.Ajax{ //??? } return result; } //Contrast with C++ int f() { //just! return result; } Post Script: Th ...

The fuse-sidebar elements are not being properly highlighted by Introjs

I have recently developed an angular project that utilizes the fuse-sidebar component. Additionally, I am incorporating introjs into the project. While introjs is functioning properly, it does not highlight elements contained within the fuse-sidebar. The ...

Can we pause and resume the progress bar using Javascript in conjunction with animationPlayState?

Looking for a way to control a progress bar script that runs for 180 seconds and then redirects the browser? Check out the code snippet below. I've added an onclick event to test pausing the progress bar. My goal is to pause, reset, and adjust the dur ...

Learn how to showcase a text file uploaded to a webpage with NODE js and HTML

<!DOCTYPE html> <html> <body> <form action = "/submit" method = "post"> Select a file: <input type="file" name="file"> <input type="submit"> </form> </bod ...

Why is the jQuery change event only firing when the page loads?

I am experiencing an issue with a .js file. The change event is only triggering when the page loads, rather than when the selection changes as expected. $(document).ready(function(){ $("#dropdown").on("change keyup", colorizeSelect()).change(); }); f ...

Validation for dates in Angular.Js input is important to ensure that only

Take a look at this form: <form name="user_submission" novalidate="novalidate" method="post"> <input type="date" name="date_of_birth" ng-focus="save_data()" ng-model-options="{timezone: 'UTC'}" ng-pattern="/^(19\d{2}|[2-9]& ...

What is the best way to instantiate objects, arrays, and object-arrays in an Angular service class?

How can I nest an object within another object and then include it in an array of objects inside an Angular service class? I need to enable two-way binding in my form, so I must pass a variable from the service class to the HTML template. trainer.service. ...

What is the best way to target all elements sharing a common class?

Currently, I have a Boolean variable stored in a hidden input field. When the user is signed in, it's set to false; otherwise, it's set to true. I have download buttons that should link to a file for download. My goal is to hide these buttons an ...

The average duration for each API request is consistently recorded at 21 seconds

It's taking 21 seconds per request for snippet.json and images, causing my widget to load in 42 seconds consistently. That just doesn't seem right. Check out this code snippet below: <script type="text/javascript"> function fetchJSONFil ...