CSS counter : Number increment dynamic effect

CSS counter: number increment dynamic effect

CSS counter : Number increment dynamic effect

CSS counters are variables maintained by CSS. These variables can be increased according to CSS rules to track the number of uses. We can use this feature to adjust the content performance according to the document location, such as displaying the list number.

Because the serial number here is just a decoration, the order is not emphasized. Compared to using real DOM elements to display serial numbers, CSS counters are more concise and flexible. In case the content sequence needs to be adjusted, the serial numbers will not be affected.

Sometimes we will see that some Dashboard interface has the effect of fast scrolling of numbers. How can this effect be achieved? This article will introduce several methods.

JavaScript solution

The easiest way is to use a  setIntervaltimer, just modify the DOM content regularly. However, in order to achieve a smoother animation effect, it is recommended to use  requestAnimationFrame:

function animateValue(obj, start, end, duration) {
  let startTimestamp = null;
  const step = (timestamp) => {
    if (!startTimestamp) startTimestamp = timestamp;
    const progress = Math.min((timestamp - startTimestamp) / duration, 1);
    obj.innerHTML = Math.floor(progress * (end - start) + start);
    if (progress < 1) {
      window.requestAnimationFrame(step);
    }
  };
  window.requestAnimationFrame(step);
}

const obj = document.getElementById("value");
animateValue(obj, 100, 0, 5000);
 


CSS @keyframes combined with margin

This idea is more interesting. The principle is to arrange the numbers in a row and move the element position through animation to display the numbers in different positions:

<div class="counter">
  <div class="numbers">
    <div>0</div>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
  </div>
</div>
 
.counter {
  width: 100px;
  overflow: hidden;
}
.numbers {
  width: auto;
  display: flex;
  animation: countNumber 4s infinite alternate;
  animation-timing-function: steps(10);
}
.numbers div {
  text-align: center;
  flex: 0 0 100px;
}

@keyframes countNumber {
  0% {
    margin-left: 0px;
  }
  100% {
    margin-left: -1000px;
  }
}
 


CSS Counter Starter Edition

CSS counters use the following properties:

  • counter-reset-Create or reset a counter

  • counter-increment-increment variable

  • content-insert the generated content

  • counter() or counters() function-add the value of the counter to the element

To use a CSS counter, you must first create it with counter-reset. Combining CSS animations  @keyframesand setting different increment values ​​at different stages of the animation can achieve this effect:

<div></div>
 
div::after {
  content: counter(count);
  animation: counter 3s linear infinite alternate;
  counter-reset: count 0;
}

@keyframes counter {
  0% {
    counter-increment: count 0;
  }
  10% {
    counter-increment: count 1;
  }
  20% {
    counter-increment: count 2;
  }
  30% {
    counter-increment: count 3;
  }
  40% {
    counter-increment: count 4;
  }
  50% {
    counter-increment: count 5;
  }
  60% {
    counter-increment: count 6;
  }
  70% {
    counter-increment: count 7;
  }
  80% {
    counter-increment: count 8;
  }
  90% {
    counter-increment: count 9;
  }
  100% {
    counter-increment: count 10;
  }
}
 

CSS counter high version

Furthermore, if you dare to use the latest features, there is actually a more beautiful operation, and that is to animate CSS variables. The core of this technique is to set the CSS custom property to an integer type, so that it can be used transitionin the same way as other CSS properties with integer values  .

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

div {
  transition: --num 1s;
  counter-reset: num var(--num);
}
div:hover {
  --num: 10000;
}
div::after {
  content: counter(num);
}
 

However, it should be noted that currently only Chrome (or Chromium-core browsers such as Edge and Opera) support  @propertysyntax, so compatibility is a problem. If your page is only for Chrome (such as the Electron app), you can use it with confidence. Otherwise, use the conservative plan above.

Decimals can also play animation

The variables mentioned above are all required to be integers. Can decimals also support this kind of animation? The answer is yes.

You can convert decimals to integers. The principle of the steps is:

  1. Register an integer CSS variable (ie --number) and specify the initial value initial-value.

  2. Round calcthe value with :--integer: calc(var(--number))

@property --integer {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}
--number: 1234.5678;
--integer: calc(var(--number)); /* 1235 */
 

If you only need to extract the integer part, you can do this:, you  don’t --integer: max(var(--number) - 0.5, 0)even calc()need it. A similar method can extract the decimal part.

/* @property --integer */
--number: 1234.5678;
--integer: max(var(--number) - 0.5, 0); /* 1234 */
 

Complete code:

<div></div>
 
@property --percent {
  syntax: "<number>";
  initial-value: 0;
  inherits: false;
}
@property --temp {
  syntax: "<number>";
  initial-value: 0;
  inherits: false;
}
@property --v1 {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}
@property --v2 {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

div {
  font: 800 40px monospace;
  padding: 2rem;
  transition: --percent 1s;
  --temp: calc(var(--percent) * 100);
  --v1: max(var(--temp) - 0.5, 0);
  --v2: max((var(--temp) - var(--v1)) * 100 - 0.5, 0);
  counter-reset: v1 var(--v1) v2 var(--v2);
}
div::before {
  content: counter(v1) "." counter(v2, decimal-leading-zero) "%";
}
 
const genNumber = () => {
  document.querySelector("div").style.setProperty("--percent", Math.random());
};

setInterval(genNumber, 2000);
setTimeout(genNumber);
 


What's Your Reaction?

like
2
dislike
1
love
3
funny
1
angry
0
sad
1
wow
2