Number Counting Animation Elementor
January 15, 2025 · AI Conversations
Start counting with the left number. Other numbers start counting with little delay between each number from left to right
### Step 1: Add HTML
1. **Add a new section** in your Elementor layout.
2. **Add an HTML widget** inside that section and insert the following HTML:
<div class="number-count">
<span class="count" data-count="10">0</span>
<span class="count" data-count="20">0</span>
<span class="count" data-count="30">0</span>
<span class="count" data-count="40">0</span>
</div>
### Step 2: Add CSS
1. **Go to the "Custom CSS" section** of the Elementor widget (if you have Elementor Pro) or add it in the site's customizer or in a CSS file:
.number-count {
display: flex;
justify-content: space-between;
}
.count {
font-size: 2em; /* Adjust size as needed */
margin: 0 10px; /* Space between numbers */
}
### Step 3: Add JavaScript
1. **Add a new HTML widget** below your number count or include this script in your theme’s footer or a custom JavaScript file:
<script>
document.addEventListener("DOMContentLoaded", function () {
const counts = document.querySelectorAll('.count');
counts.forEach((count, index) => {
const target = +count.getAttribute('data-count');
let start = 0;
const duration = 2000; // Duration for counting (in milliseconds)
const incrementTime = Math.floor(duration / target); // Time for each increment
const counter = setInterval(() => {
start += 1;
count.innerText = start;
if (start === target) {
clearInterval(counter);
}
}, incrementTime);
// Add a delay for subsequent numbers
setTimeout(() => {
clearInterval(counter);
const counterDelayed = setInterval(() => {
start += 1;
count.innerText = start;
if (start === target) {
clearInterval(counterDelayed);
}
}, incrementTime);
}, index * 500); // Delay between each number (in milliseconds)
});
});
</script>
### Explanation
– The **HTML** defines the numbers you want to count up to, with each number stored in a `data-count` attribute.
– The **CSS** styles the layout of the numbers.
– The **JavaScript**:
– Listens for the `DOMContentLoaded` event to ensure the script runs after the content is loaded.
– Counts up from 0 to the target number defined in the `data-count` attribute.
– Introduces a delay between the start of the counting for each number based on its position.
### Step 4: Adjust Timing
You can adjust the `duration` variable in the JavaScript to change how quickly the numbers count up, and you can modify the `index * 500` in the `setTimeout` function to change the delay between the start of each count.
This setup will give you a smooth counting effect with a delay between each number in Elementor.
### Step 1: Add the Counter Widgets
1. **Open your Elementor editor.**
2. **Add a new section** and insert multiple **Counter widgets** in a row. Set the values you want for each counter.
3. **Adjust the styling** as needed, ensuring they are aligned horizontally.
### Step 2: Custom CSS for Alignment (Optional)
If you want to ensure the counters are evenly spaced or look good in a row, you can add some custom CSS:
.elementor-counter {
display: inline-block; /* Ensures counters are in a row */
margin-right: 20px; /* Space between counters */
}
### Step 3: Add Custom JavaScript
1. **Navigate to the Elementor editor** and click on the **Settings icon** (the gear icon) at the bottom left corner.
2. Go to the **Advanced** tab and look for the **Custom CSS & JS** section (or you can use a custom JS plugin if you don't have this option).
3. Add the following JavaScript code:
<script>
jQuery(document).ready(function($) {
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = counter.find('.elementor-counter-number').data('to');
// Set the initial count to zero
counter.find('.elementor-counter-number').text(0);
// Start counting with a delay
setTimeout(function() {
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(Math.floor(this.countNum));
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum);
}
});
}, index * 500); // Delay between each counter
});
});
</script>
### Explanation
– The **jQuery** script targets each counter widget and retrieves the number it is set to count to using the `data-to` attribute.
– It sets the initial counter value to 0 and animates it to the target value over a specified duration.
– The `setTimeout` function introduces a delay based on the index of the counter, so each counter starts counting after the previous one.
### Step 4: Test and Adjust
1. **Preview your changes** to see the counting effect in action. Each counter should start counting from 0 to its specified value with a slight delay.
2. You can adjust the **duration** in the script to change how long it takes for each number to count up, and modify the **index * 500** value to increase or decrease the delay between counters.
This setup leverages Elementor's built-in counter widget while adding a dynamic counting effect with minimal customization.
### Step 1: Update JavaScript Code
1. **Use the following updated JavaScript code** to ensure the counters start from 0 and animate to their target values without showing the initial value:
<script>
jQuery(document).ready(function($) {
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseInt(counter.find('.elementor-counter-number').data('to')); // Get the target value
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(Math.floor(this.countNum));
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum); // Ensure it shows the final value
}
});
}, index * 500); // Delay between each counter
});
});
</script>
### Step 2: Hide the Initial Value in CSS
To ensure that the counter numbers don’t flash the target value when the page loads, you can use CSS to hide the numbers initially and then display them when they start counting:
1. **Add the following CSS** to your site's custom CSS section or in the **Custom CSS** area of your Elementor settings:
.elementor-counter-number {
visibility: hidden; /* Initially hide the counter number */
}
.elementor-counter-number.visible {
visibility: visible; /* Show the counter number when it's counting */
}
### Step 3: Update JavaScript to Add Visibility Class
Next, update the JavaScript to add a class that makes the number visible when counting begins:
<script>
jQuery(document).ready(function($) {
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseInt(counter.find('.elementor-counter-number').data('to')); // Get the target value
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').addClass('visible'); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(Math.floor(this.countNum));
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum); // Ensure it shows the final value
}
});
}, index * 500); // Delay between each counter
});
});
</script>
### Summary
– The **CSS** hides the counter numbers initially, preventing them from displaying their target values when the page loads.
– The **JavaScript** adds a `visible` class to each counter when it starts counting, allowing it to be shown only during the animation.
With this setup, the counters will start at 0 and count up to their target values without showing any initial values before the animation begins.
### Step 1: Hide the Default Counter Value
You can hide the default counter values using CSS. Add the following CSS to your Elementor custom CSS section or your site’s additional CSS:
.elementor-counter-number {
opacity: 0; /* Hide the default counter value */
}
### Step 2: Add Custom JavaScript
Now, you'll add custom JavaScript to implement your counting effect. Here's a code snippet that animates the counters from 0 to their target values:
1. **Add a new HTML widget** or use the Elementor settings to add custom JavaScript code in your footer or a custom JS file:
<script>
jQuery(document).ready(function($) {
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseInt(counter.find('.elementor-counter-number').data('to')); // Get the target value
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(Math.floor(this.countNum));
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum); // Ensure it shows the final value
}
});
}, index * 500); // Delay between each counter
});
});
</script>
### Explanation
– The **CSS** sets the opacity of the counter number to 0, effectively hiding it on the page.
– The **JavaScript**:
– Retrieves the target value from the `data-to` attribute.
– Sets the initial display value to 0.
– Implements a delayed counting effect for each counter.
– Changes the opacity to 1 when the counting starts, making the number visible.
### Step 3: Test Your Changes
1. **Preview your changes** to see the custom counting effect in action. The counters should start from 0 and animate up to their specified target values without showing the default values.
### Additional Tips
– You can adjust the **duration** of the counting effect and the **delay** between counters as needed by modifying the values in the JavaScript code.
– Ensure that jQuery is loaded on your page, as this code relies on it.
This setup will allow you to effectively disable the default counting behavior of the Elementor counter widget and replace it with your custom animation.
### Step 1: JavaScript Code with Intersection Observer
Replace your JavaScript with the following updated script. It uses the Intersection Observer API to trigger the counting effect only when the counter element comes into view:
<script>
document.addEventListener("DOMContentLoaded", function () {
const counters = document.querySelectorAll('.elementor-counter');
// Function to start counting
function startCounting(counter) {
const countTo = parseInt(counter.querySelector('.elementor-counter-number').dataset.to);
const counterNumber = counter.querySelector('.elementor-counter-number');
let start = 0;
// Ensure the counter starts at 0 and is visible
counterNumber.textContent = 0;
counterNumber.style.opacity = 1;
// Animate the counter
const duration = 2000; // Duration in milliseconds
const incrementTime = Math.floor(duration / countTo);
const interval = setInterval(() => {
start++;
counterNumber.textContent = start;
if (start >= countTo) {
clearInterval(interval);
}
}, incrementTime);
}
// Intersection Observer to detect when the counter is in view
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
startCounting(entry.target);
observer.unobserve(entry.target); // Stop observing after animation starts
}
});
},
{ threshold: 0.5 } // Trigger when 50% of the counter is visible
);
// Observe each counter element
counters.forEach(counter => {
observer.observe(counter);
});
});
</script>
### Step 2: Adjust CSS for Hidden Counters
Ensure the counters are hidden initially and only become visible when the counting starts. Add the following CSS:
.elementor-counter-number {
opacity: 0; /* Hidden by default */
transition: opacity 0.3s ease-in-out; /* Smooth fade-in effect */
}
### How It Works
1. **Intersection Observer API**:
– Monitors when the `.elementor-counter` elements enter the viewport.
– Starts the counting animation only when the counter is visible.
2. **startCounting Function**:
– Sets the initial value to `0`.
– Gradually increments the value to the target number (`data-to`) using `setInterval`.
3. **Efficiency**:
– The observer unobserves counters after the animation starts, preventing redundant checks.
4. **Customization**:
– You can adjust the `threshold` in the observer options for more precise visibility triggering (e.g., `0.5` means 50% visible).
### Step 3: Test in Elementor
1. Save and update the changes in Elementor.
2. Scroll through the page in the browser, and the counters will animate only when they become visible.
This approach ensures optimal performance and an engaging user experience.
$('.elementor-counter-number').css('opacity', 0);
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseInt(counter.find('.elementor-counter-number').data('to-value')); // Get the target value
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(Math.floor(this.countNum));
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum); // Ensure it shows the final value
}
});
}, index * 1500); // Delay between each counter
});
});
preserve decimal numbers in counter
### Updated Code with Decimal Support
jQuery(document).ready(function($) {
$('.elementor-counter-number').css('opacity', 0); // Hide numbers initially
$('.elementor-counter').each(function(index) {
var counter = $(this);
var countTo = parseFloat(counter.find('.elementor-counter-number').data('to-value')); // Get the target value as a float
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Start counting with a delay
setTimeout(function() {
counter.find('.elementor-counter-number').css('opacity', 1); // Make the number visible
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
// Display the number with decimals
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2));
},
complete: function() {
// Ensure it shows the final value with decimals
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2));
}
});
}, index * 1500); // Delay between each counter
});
});
### Key Changes
1. **Data Attribute as `Float`:**
– Changed `parseInt` to `parseFloat` to support decimal numbers.
2. **Preserve Decimals in `step`:**
– Added `.toFixed(2)` to the `step` function, ensuring two decimal places are shown during the animation.
3. **Final Value with Decimals:**
– Added `.toFixed(2)` in the `complete` function to ensure the counter displays the target value with two decimal places after the animation.
### Customization
– **Number of Decimal Places:**
– Change `toFixed(2)` to `toFixed(1)` or another value if you want fewer or more decimal places.
– **Animation Duration:**
– Adjust the `duration` value (e.g., `2000`) to control the speed of the animation.
This updated script will animate counters with decimal precision, ensuring a smooth and accurate visual effect.
### Final Code with Viewport Detection and Decimal Support
jQuery(document).ready(function($) {
$('.elementor-counter-number').css('opacity', 0); // Hide numbers initially
// Function to start counting
function startCounting(counter) {
var countTo = parseFloat(counter.find('.elementor-counter-number').data('to-value')); // Get the target value
counter.find('.elementor-counter-number').text(0); // Set the initial count to zero
// Animate the counter
$({ countNum: 0 }).animate({ countNum: countTo }, {
duration: 2000, // Duration for counting
easing: 'linear',
step: function() {
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2)); // Preserve decimals
},
complete: function() {
counter.find('.elementor-counter-number').text(this.countNum.toFixed(2)); // Ensure final value is precise
}
});
}
// Intersection Observer for viewport detection
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const counter = $(entry.target);
startCounting(counter); // Start counting when visible
observer.unobserve(entry.target); // Stop observing once counted
}
});
},
{ threshold: 0.5 } // Trigger when 50% of the element is visible
);
// Observe each counter
$('.elementor-counter').each(function() {
observer.observe(this);
});
});
### Key Features of the Code
1. **Viewport Detection:**
– The **Intersection Observer API** ensures the animation only starts when the counter element is visible in the viewport.
2. **Decimal Precision:**
– The `toFixed(2)` ensures the counter preserves two decimal places during the animation.
3. **One-Time Animation:**
– The `observer.unobserve(entry.target)` stops observing the element after the animation starts, improving performance.
4. **Customizable Threshold:**
– The `{ threshold: 0.5 }` option means the animation starts when 50% of the counter is visible. Adjust this value as needed.
### CSS for Smooth Visibility
Add the following CSS to handle the initial hiding of the counter and its smooth appearance:
.elementor-counter-number {
opacity: 0; /* Hidden initially */
transition: opacity 0.3s ease-in-out; /* Smooth fade-in */
}
### How It Works
1. **Hide Initially:**
– The counter numbers are hidden (`opacity: 0`) to prevent any flickering or unintended display.
2. **Viewport Detection:**
– When a counter enters the viewport, the animation starts, and the number becomes visible.
3. **Smooth Animation:**
– The counting animation runs smoothly from 0 to the target value with decimal precision.
### Testing and Customization
1. **Test Your Page:**
– Scroll through your page and observe the counters animating only when they become visible.
2. **Customize Decimal Places:**
– Change `.toFixed(2)` to `.toFixed(1)` or `.toFixed(3)` for different precision.
This setup is efficient, user-friendly, and works well for counters that require decimal precision and visibility-based triggering.