Leveraging jQuery to define CSS Variable for Keyframe Animation - Does not work on Safari and Mobile Devices

My CSS keyframe animation uses a CSS variable as an animation property, which is defined in jQuery. The animation works perfectly in Chrome and Firefox, but on Safari and mobile browsers, only parts of the animation that do not involve the variable work correctly.

I've been troubleshooting this issue extensively...

  • I have tested on the latest browser versions.
  • Checking Developer tools in Safari confirms that the variable is correctly defined (e.g. 1200px).
  • If I hard-code the variable value in the CSS, the animation functions correctly.
  • However, if I hard-code the variable value in jQuery instead of calculating it, the animation fails.
  • Using the variable as a property in the element selector itself positions the element as expected.
  • I tried using "transform: translateY(...)" instead of "top:" with no change in results.
  • Occasionally, leaving the window open causes the animation to start working properly. However, I cannot replicate this consistently.

Based on all this, it seems like there's an issue with defining the variable in jQuery (which also did not work with plain JavaScript) and using it in the animation.

Any insights into what might be happening?

function refHeight() {
  if ($('#main-content').length != 0) {
    $(':root').css('--varheight', Math.round($('#main-content').outerHeight()) + 'px');
  }
}
window.addEventListener('load', refHeight);
window.addEventListener('resize', refHeight);
:root {
  --hardvarheight: 75vh;
}

#main-content {
  width: 100%;
  height: 75vh;
}

.item {
  width: 75px;
  height: 50px;
  font-size: 80%;
}

.one {
  animation: animOne 3s linear infinite alternate;
  position: absolute;
  background-color: pink;
}

.two {
  position: absolute;
  top: calc(var(--varheight) / 100 * 50);
  left: 50vw;
  background-color: lightblue;
}

.three {
  animation: animThree 3s linear infinite alternate;
  position: absolute;
  background-color: lightgreen;
}

@keyframes animOne {
  0% {top: calc(var(--varheight) / 100 * 10); left: 40vw;}
  50% {top: calc(var(--varheight) / 100 * 20); left: 50vw;}
  100% {top: calc(var(--varheight) / 100 * 10);left: 60vw;}
}

@keyframes animThree {
  0% {top: calc(var(--hardvarheight) / 100 * 80); left: 40vw;}
  50% {top: calc(var(--hardvarheight) / 100 * 90); left: 50vw;}
  100% {top: calc(var(--hardvarheight) / 100 * 80); left: 60vw;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main-content">
  <div class="item one">Animated Using jQuery Variable</div>
  <div class="item two">Positioned Using jQuery Variable</div>
  <div class="item three">Animated Using CSS Variable</div>
</div>

Answer №1

After some troubleshooting, I have finally cracked the code. It appears that Safari has a quirk where it does not like to recalculate CSS calc() values once they have been initially set.

To work around this issue, instead of directly attaching the animation property in CSS, I created a separate class and used addClass() to apply it to the element after the variable calculation. This seems to do the trick.

The last hurdle I need to overcome is finding a way to trigger the recalculation of the calc() value in the keyframe animation when the browser window is resized.

function updateHeight() {
  if ($('#main-content').length != 0) {
    $(':root').css('--varheight', Math.round($('#main-content').outerHeight()) + 'px');
    $('.one').addClass('animated');
  }
}
window.addEventListener('load', updateHeight);
window.addEventListener('resize', updateHeight);
:root {
  --hardvarheight: 75vh;
}

#main-content {
  width: 100%;
  height: 75vh;
}

.item {
  width: 75px;
  height: 50px;
  font-size: 80%;
}

.one {
  position: absolute;
  background-color: pink;
}

.two {
  position: absolute;
  top: calc(var(--varheight) / 100 * 50);
  left: 50vw;
  background-color: lightblue;
}

.three {
  animation: animThree 3s linear infinite alternate;
  position: absolute;
  background-color: lightgreen;
}
.animated {
  animation: animOne 3s linear infinite alternate
}
@keyframes animOne {
  0% {top: calc(var(--varheight) / 100 * 10); left: 40vw;}
  50% {top: calc(var(--varheight) / 100 * 20); left: 50vw;}
  100% {top: calc(var(--varheight) / 100 * 10);left: 60vw;}
}

@keyframes animThree {
  0% {top: calc(var(--hardvarheight) / 100 * 80); left: 40vw;}
  50% {top: calc(var(--hardvarheight) / 100 * 90); left: 50vw;}
  100% {top: calc(var(--hardvarheight) / 100 * 80); left: 60vw;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main-content">
  <div class="item one">Animated Using jQuery Variable</div>
  <div class="item two">Positioned Using jQuery Variable</div>
  <div class="item three">Animated Using CSS Variable</div>
</div>

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

jquery mobile listview extension not functioning as expected

My JQM menu is displayed as a listview, and I want it to be normal on every page except one where it should have 2 extra items. Despite searching online for solutions, nothing seems to work. Here are some of the things I've attempted: -location.reloa ...

Plugin for controlling volume with a reverse slider functionality

I have been customizing the range slider plugin found at to work vertically instead of horizontally for a volume control. I have successfully arranged it to position the fill and handle in the correct reverse order. For instance, if the value is set to 7 ...

Evaluating CSS Specificity

Is there a recommended approach for automatically testing css selectors? I am in the process of developing a SCSS framework and I want to integrate automated tests. Specifically, I aim to verify that the css selectors are functioning correctly. For examp ...

Chrome and Firefox failing to render background property in CSS

I encountered an issue with my HTML code that I tested on both Chrome and Firefox. The background color of the first div is not displaying correctly in either browser. .box-orange { // without any position declaration background: orange; heigh ...

The mobile view does not allow scrolling in the dropdown menu

I recently created a webpage using Bootstrap 4 beta with a dropdown menu in the navbar. While it displays perfectly on my laptop in fullscreen mode, there seems to be an issue when viewed on my iPhone. The dropdown menu only shows 7 out of the 9 links. Is ...

Utilizing CSS3Pie on a Wordpress website... Following all the best practices, yet still facing functionality issues

Seeking assistance with rounding the corners of navigation tabs in IE8 on my slider at csr.steelcase.com, including tabs like "Our Vision" and "Note from our CEO." Using WordPress for the site and have correctly installed CSS3PIE based on various articles ...

What are the steps to create a button with similar design using css3?

How can I create a button with the same lower part as shown in this picture? I've already achieved 50% of it with border-radius, but need help expanding the lower part to match. Any suggestions? https://i.sstatic.net/3ZJFS.jpg .list{ height: 280px; ...

Activate the jQuery UI datepicker with a trigger

Within my code, I have a span element that displays a date in the format mm/dd/yyyy. <span class="editableDateTxt">06/10/2014</span> My goal is to have an inline editable date popup or utilize jQuery UI's datepicker when this span elemen ...

Halting the execution of the jQuery script

Hidden away from the page, one part of a div is visible with CSS: div{ left: -100px; width: 150px; height: 50px; } To reveal the entire div, I utilized jQuery: $("div").hover(function(){ $("div").animate({left: '0px'}); },func ...

Tips on how to utilize JavaScript to display data on a page without the need for refreshing, updating every 2-5

Could you please assist me? I am working on a CRUD application and have created a function called loaddata();. My issue is that when another user adds data, it should be displayed in my table without the need to refresh. Is there a way to achieve this? fun ...

Unexpected blank space detected at the bottom of the page in Angular 13

Using the NGX-ADMIN template built on Angular 12 has been smooth sailing until an upgrade to Angular 13. With this simple version change, I am now faced with a perplexing issue that I can't seem to pinpoint or resolve. I can confidently say that shif ...

Troubleshooting issue with passing JSON information to ASP.NET WebMethod using jQuery

I have tried going through all the questions related to this problem but unfortunately, I couldn't find a solution... The Score class: public class Score { // default constructor public Score() { } public int TraitID { get; set; } ...

Error in jQuery and Canvas Image Crop: The index or size is invalid, exceeding the permissible limit

Recently, I downloaded and installed the Canvas Image Crop plugin from CodeCanyon but encountered a problem specifically on firefox. An error message kept popping up whenever I tried to upload certain images: "Index or size is negative or greater than the ...

Tips for adjusting the animation position in Off-Canvas Menu Effects

I am currently utilizing the wave menu effect from OffCanvasMenuEffects. You can view this menu in action below: ... // CSS code snippets here <link rel="stylesheet" type="text/css" href="https://tympanus.net/Development/OffCanvasMenuEffects/fonts/f ...

Looking for help with jQuery's mousemove event. How can I assist you

How's everyone doing? I'm just starting out with jQuery and I'm working on a project where I'm using the mousemove event on a parent element to fade in a div based on the cursor's position. However, I've run into an issue whe ...

Efficient jQuery code for switching images based on multiple class attributes

I have developed a short script that enables swapping big images by clicking on thumbnails. The script should work on each item individually, but currently, clicking on any thumbnail results in swapping all big images. Here is the code snippet that I am u ...

What is the best way to programmatically select a checkbox that was created dynamically using jQuery?

I've been scouring the internet trying to find information on what I'm attempting to accomplish, but so far I haven't come across anything helpful. The issue I'm facing is with a form that has a section dynamically added using JavaScri ...

Looking to position content at the vertical midpoint for a polished look?

Struggling to center the 'MAIN' content vertically in the middle of the page despite trying various methods. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfem ...

Hide jQuery dropdown when mouse moves away

I am working on designing a navigation bar with dropdown functionality. Is there a way to hide the dropdown menu when the mouse pointer leaves both the navbar menu and the dropdown itself? I have tried using hover, mouseenter, and mouseleave but due to my ...

Resolving JavaScript animation delays in background tabs with instantaneous correction

Currently, I have a fiddle showcasing two pulsing animations that run at different timings. http://jsfiddle.net/JuFxn/16/ The code snippet for the pulse effect can be found within the fiddle itself. function fadeItIn() { var child; child = 4; setTimeou ...