The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →The simplest way to add an animated number in WordPress is to use the counter tool that matches your editor: Elementor’s native Counter widget, the Counting Number Block in Gutenberg, or CountUp.js when you need custom data and behavior. Each route can retain a real static value for accessibility and search engines while animating only the visual change.
Choose the right implementation
| Route | Works with | Setup | Control | Best use |
|---|---|---|---|---|
| Elementor Counter widget | Elementor | Lowest | Standard number, prefix, suffix, separator, and duration controls | A quick counter on an Elementor page |
| Counting Number Block | Gutenberg (Block Editor) | Low; install a plugin | Count direction, viewport trigger, formatting, prefixes, and suffixes | A no-code counter in a block-based page |
| CountUp.js | Any theme or builder | Highest | Custom timing, easing, formatting, data sources, and visibility logic | A bespoke design or dynamically supplied values |
This is a feature-based recommendation, not a comparative performance benchmark. Elementor is quickest on Elementor sites, the block plugin is quickest in Gutenberg, and CountUp.js offers the most implementation control.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
WordPress 3.0 jQuery | $50.99 | Buy on Amazon |
Method 1: Add a counter with Elementor
Elementor describes its Counter widget as an element that displays a numeric value that can increase or decrease. Use it when the page is already built with Elementor.
- Open the page in Elementor.
- Search the widget panel for Counter and drag it into the section or container where the statistic should appear.
- In the widget’s content controls, enter the Starting Number and Ending Number.
- Add the counter’s title, then configure a Prefix (such as “$”) or Suffix (such as “%” or “+”).
- Choose the number separator and set the animation Duration. Elementor documents duration in milliseconds, so use a value such as
2000for two seconds. - Style the number and title, preview the page at desktop and mobile widths, and publish or update the page.
For several statistics, duplicate the widget inside a row or container and give each counter its own ending value, label, and formatting. Check the completed page with JavaScript disabled or delayed: the ending value should still be understandable rather than leaving an empty statistic.
#1 Best Overall
Method 2: Create a counter in Gutenberg without JavaScript
The WordPress.org Counting Number Block plugin provides a block-editor route. Its listing records version 1.1.0, released June 30, 2024.
- In WordPress administration, go to Plugins > Add New Plugin.
- Search for Counting Number Block, verify the plugin name and author shown in the directory, and select Install Now.
- Select Activate.
- Open a post or page in the Site Editor or Block Editor and insert the Counting Number Block.
- Set the starting and ending values, then choose whether the number counts up or down.
- Configure the prefix, suffix, decimal or grouping formatting, and whether the animation runs once or when the block enters the viewport.
- Save or publish, then test the block on the front end.
The block keeps the actual value available to screen readers, and its documented reduced-motion behavior suppresses the animated effect for users who request less motion. Confirm the static value, formatting, and final state in your chosen theme because typography and layout are theme-dependent.
Method 3: Use CountUp.js for custom control
CountUp.js is a dependency-free, MIT-licensed JavaScript class that animates a numerical value by counting to it. It is useful when the number comes from an API, custom fields, WooCommerce data, or another script, or when the design needs timing and easing that a widget does not expose.
1. Add a meaningful target element
Put the final value in the markup so it exists before JavaScript runs. The element’s text is also a sensible fallback if the script fails.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches<span class="stat-number" data-count="12500">12,500</span>
<span class="stat-label">customers served</span>
2. Load the library and initializer correctly
For a theme or plugin, load both files with wp_enqueue_script() from the wp_enqueue_scripts hook, declare dependencies, and use a defer strategy when appropriate. WordPress identifies enqueueing as the recommended way to link JavaScript to a generated page; do not hardcode script tags into theme templates.
A small, page-specific experiment can go in Elementor’s HTML widget, with CSS inside <style> tags and JavaScript inside <script> tags. Elementor Custom Code offers placement, priority, and display-condition controls, but it does not accept PHP.
3. Initialize the counter
document.addEventListener('DOMContentLoaded', function () {
const target = document.querySelector('.stat-number');
if (!target || typeof CountUp === 'undefined') return;
const endValue = Number(target.dataset.count);
const counter = new CountUp(target, endValue, {
duration: 2,
separator: ',',
decimalPlaces: 0,
enableScrollSpy: true,
scrollSpyOnce: true
});
if (!counter.error) counter.start();
});
CountUp.js supports duration, easing, decimal and grouping formats, and an auto-animation option based on IntersectionObserver, which starts the effect when the element becomes visible. Match the option names to the CountUp.js version you load, and check counter.error when diagnosing initialization failures.
Accessibility and reduced-motion requirements
Keep the real value in the HTML
Do not make the statistic depend entirely on rapidly changing text. A meaningful value in the original markup gives search engines and assistive technology a usable result before JavaScript loads. Avoid using the changing counter as an aria-live announcement; announcing every intermediate number can overwhelm screen-reader users.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteHonor the operating-system motion preference
WordPress accessibility guidance advises being mindful of vestibular disorders and placing animation and transition rules behind @media not (prefers-reduced-motion). For custom code, skip the animation when the preference is enabled:
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduceMotion) {
target.textContent = target.dataset.count;
} else {
counter.start();
}
The Counting Number Block documents disabling its animated effect in reduced-motion mode. With Elementor, provide a static, readable number and verify the widget’s behavior in your current version rather than assuming every animation setting is automatically accessible.
Test realistic content
- Use prefixes, suffixes, decimal points, and grouping separators together.
- Test short and very long numbers so the layout does not shift or overflow.
- Check the value before JavaScript loads, during the animation, and after it finishes.
- Use keyboard navigation and a screen reader to confirm that the statistic has a useful label.
- Test with reduced motion enabled and with JavaScript blocked or delayed.
WordPress script-loading pattern for a theme or plugin
Use an enqueue function instead of inserting a script tag directly into a template:
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'countup',
plugins_url('assets/countUp.umd.js', __FILE__),
array(),
'2.9.0',
array('strategy' => 'defer', 'in_footer' => true)
);
wp_enqueue_script(
'site-counters',
plugins_url('assets/counters.js', __FILE__),
array('countup'),
'1.0.0',
array('strategy' => 'defer', 'in_footer' => true)
);
});
Adjust the file paths and versions to the files actually installed in your project. Declaring CountUp as a dependency ensures the initializer runs after the library is available.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Troubleshoot a counter that does not work
The number is blank
- Inspect the front-end HTML and confirm that the target element contains a fallback value.
- Open the browser console and check for a missing library, selector mismatch, or JavaScript syntax error.
- Confirm that the initializer runs after the DOM exists and after CountUp.js has loaded.
The counter never starts on scroll
- Make sure the target is not hidden by a parent with
display: nonewhen the observer is created. - Check that the element enters the viewport and that the selected “once” or repeat behavior matches your intent.
- Test an ordinary start without viewport detection to isolate an observer or layout issue.
Formatting or layout is wrong
- Check whether the prefix or suffix is part of the value or a separate field.
- Verify decimal and grouping separators for the intended locale.
- Reserve enough width for the largest value to prevent nearby content from jumping.
Which approach should you use?
Use Elementor’s Counter widget when the page is built in Elementor and standard controls are sufficient. Use Counting Number Block when you work in Gutenberg and want a no-code block with documented viewport and reduced-motion behavior. Choose CountUp.js when values arrive from code or the animation needs custom easing, formatting, or visibility logic. In every case, publish a readable static value first and treat the animation as progressive enhancement.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

