CSS animition interger counters

ghz 8months ago ⋅ 62 views

I am trying to get a banner placed on an html page that uses the CSS animation to run the counter up to a specific number, but having a bit of a problem when trying to get more than one working in the same banner, the numbers will be counting up to different amounts dependant on the div, first time trying to implement this and would appreciate any help.

html,
body {
  width: 100%;
  height: 100%;
}

* {
  box-sizing: border-box;
}

body {
  padding: 0;
  margin: 0;
  font-family: roboto, segoe ui, Verdena, Helvetica, Sans-Serif;
  font-size: 16px;
  /*text-transform: uppercase;
    color: #000; */
}

@property --num {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div span.years-number {
  animation: counter 5s forwards ease-in-out;
  counter-reset: num var(--num);
  font: 800 40px system-ui;
  padding: 2rem;
}

div span.years-number::after {
  content: counter(num);
}

@keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 20;
  }
}

div span.project-number::after {
  content: counter(num);
}

@keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 55;
  }
}

div span.employee-number::after {
  content: counter(num);
}

@keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 10;
  }
}

div span.customers-number::after {
  content: counter(num);
}

@keyframes counter {
  from {
    --num: 0;
  }
  to {
    --num: 115;
  }
}
<section style="position: relative; z-index: 1; text-align: center;">
  <div style="flex: 0 0 auto; width: 25%; scroll-behavior: inherit !important;">
    <div class="single-counter">
      <div class="counter-contents">
        <h2 style="color: #000000; font-size: 45px; font-weight: 700; margin-bottom: 5px; word-spacing: -10px;">
          <span class="years-number"></span>
          <span>+</span>
        </h2>
        <h3 style="color: #000; font-size: 20px; font-weight: 600;">Years of Experience</h3>
      </div>
    </div>
  </div>
  <div style="flex: 0 0 auto; width: 25%; scroll-behavior: inherit !important;">
    <div class="single-counter">
      <div class="counter-contents">
        <h2 style="color: #000; font-size: 45px; font-weight: 700; margin-bottom: 5px; word-spacing: -10px;">
          <span class="project-number"></span>
          <span>+</span>
        </h2>
        <h3 style="color: #000; font-size: 20px; font-weight: 600;">Complete Project</h3>
      </div>
    </div>
  </div>
  <div style="flex: 0 0 auto; width: 25%; scroll-behavior: inherit !important;">
    <div class="single-counter">
      <div class="counter-contents">
        <h2 style="color: #000; font-size: 45px; font-weight: 700; margin-bottom: 5px; word-spacing: -10px;">
          <span class="employee-number"></span>
          <span>+</span>
        </h2>
        <h3 style="color: #000; font-size: 20px; font-weight: 600;">Employees</h3>
      </div>
    </div>
  </div>
  <div style="flex: 0 0 auto; width: 25%; scroll-behavior: inherit !important;">
    <div class="single-counter">
      <div class="counter-contents">
        <h2 style="color: #000; font-size: 45px; font-weight: 700; margin-bottom: 5px; word-spacing: -10px;">
          <span class="customers-number"></span>
          <span>+</span>
        </h2>
        <h3 style="color: #000; font-size: 20px; font-weight: 600;">Customers</h3>
      </div>
    </div>
  </div>
</section>

Answers

To achieve multiple counters with different ending numbers using CSS animations, you need to define separate keyframes for each counter animation. Currently, your CSS is overwriting the counter keyframes multiple times, resulting in only the last one being applied to all counters.

Here's how you can modify your CSS to define separate keyframes for each counter:

@property --num-years {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div span.years-number {
  animation: counter-years 5s forwards ease-in-out;
  counter-reset: num var(--num-years);
  font: 800 40px system-ui;
  padding: 2rem;
}

div span.years-number::after {
  content: counter(num);
}

@keyframes counter-years {
  from {
    --num-years: 0;
  }
  to {
    --num-years: 20;
  }
}

@property --num-projects {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div span.project-number {
  animation: counter-projects 5s forwards ease-in-out;
  counter-reset: num var(--num-projects);
  font: 800 40px system-ui;
  padding: 2rem;
}

div span.project-number::after {
  content: counter(num);
}

@keyframes counter-projects {
  from {
    --num-projects: 0;
  }
  to {
    --num-projects: 55;
  }
}

@property --num-employees {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div span.employee-number {
  animation: counter-employees 5s forwards ease-in-out;
  counter-reset: num var(--num-employees);
  font: 800 40px system-ui;
  padding: 2rem;
}

div span.employee-number::after {
  content: counter(num);
}

@keyframes counter-employees {
  from {
    --num-employees: 0;
  }
  to {
    --num-employees: 10;
  }
}

@property --num-customers {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div span.customers-number {
  animation: counter-customers 5s forwards ease-in-out;
  counter-reset: num var(--num-customers);
  font: 800 40px system-ui;
  padding: 2rem;
}

div span.customers-number::after {
  content: counter(num);
}

@keyframes counter-customers {
  from {
    --num-customers: 0;
  }
  to {
    --num-customers: 115;
  }
}

With this setup, each counter has its own unique keyframes defined (counter-years, counter-projects, counter-employees, counter-customers), allowing you to animate them independently with different ending numbers.