How to Animate the Background of the Progress Bar

Solution with CSS properties

In this snippet, we’re going to animate the progress bar created with the HTML <progress> tag. In our example, we style Shadow DOM elements, but one thing that may cause difficulties is animating the background which is represented as a repeating linear-gradient.

To overcome this difficulty, you can add the animation on the main element and use a cascading inheritance, which can cross the shadow boundaries. But note that this won’t work with the background-color property, that’s why we use a gradient and animate the position, as well.

Here, to calculate the background-size and background-position, you’ll need to do some math. Let’s see the example.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      html {
        font-size: 62.5%;
        font-family: sans-serif;
      }
      body {
        font-size: 1.6rem;
      }
      progress[value] {
        display: block;
        width: 100%;
        min-height: 4rem;
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        border: none;
        border-radius: 8px;
        box-shadow: inset 4px 4px 4px rgba(84, 30, 8, 0.2);
        background-color: rgba(149, 250, 61, 0.1);
        border: 1px solid #ccc;
        animation: colorrush 4s infinite linear;
      }
      progress[value]::-webkit-progress-inner-element {
        border-radius: 8px;
        overflow: hidden;
        background-position: inherit;
      }
      progress[value]::-webkit-progress-bar {
        border-radius: 8px;
        background-color: transparent;
        background-position: inherit;
      }
      progress[value]::-webkit-progress-value {
        border-radius: 10px 0 0 10px / 10px 0 0 10px;
        box-shadow: inset 2px 2px 2px rgba(90, 90, 92, 0.2);
        background: repeating-linear-gradient(45deg, transparent 0 6px, rgba(0, 0, 0, 0.1) 6px 12px), linear-gradient(#4a54ba, #888ccf, #b8b9cc);
        background-size: calc(12px/0.707) 100%, /* 0.707 = cos(45deg)*/
        100% 800%;
        background-position: inherit;
      }
      progress[value]::-moz-progress-bar {
        border-radius: 10px 0 0 10px / 10px 0 0 10px;
        box-shadow: inset 2px 2px 2px rgba(90, 90, 92, 0.2);
        background: repeating-linear-gradient(45deg, transparent 0 6px, rgba(0, 0, 0, 0.1) 6px 12px), linear-gradient(#4a54ba, #888ccf, #b8b9cc);
        background-size: calc(12px/0.707) 100%, /* 0.707 = cos(45deg)*/
        100% 800%;
        background-position: inherit;
      }
      @keyframes colorrush {
        0% {
          background-position: 0 0;
        }
        100% {
          background-position: calc(10*(12px/0.707)) 100%;
        }
      }
    </style>
  </head>
  <body>
    <progress max="150" value="125">125 / 150</progress>
  </body>
</html>

Do you find this helpful?

Related articles