Customization HTML5 progress element



Progressbar is an element that seems and is rarely found on sites (unlike selects, checkboxes, inputs, etc.), but still no ui-kit can do without it.

At the moment, HTML5 provides us with a native progress element, the basic functionality of which is supported by almost all modern browsers ( caniuse.com/#feat=progress ).

But on the basic styling capabilities presented by, say, IE11, to put it mildly, you will not go far. Nevertheless, I want the progress bars to be with animation, a gradient, a smooth change in the progress slider, and most importantly, with the percentage displayed.

In this article, I will try to show a way to customize the progress bar, based on two conditions:

  1. No JS. All styling is done exclusively through CSS;
  2. In subsequent work with a custom progress bar, we should work exclusively with it (change the value and not think about what you need to change the width of the slider or substitute the correct percentage).

That is, if we want to set the progress bar to 50%, we do something like this, and nothing more:

document.getElementById('progress').value = '50';

I must say right away that when layout I always try to use CSS tools to the maximum, as much as possible without resorting to JS. So this method may seem unnecessary to someone. The preprocessor will also be used in the example, since without it it takes a very long time to write the desired styles. I prefer LESS, but when writing an article, I never found a single sane sandbox with LESS support. So the example will be SCSS.

So, let's start with basic HTML markup:


We hide the native element :

.progress
{
  font: 12px Arial, Tahoma, sans-serif;
  position: relative;
  overflow: hidden;
}
.progress progress
{
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  left: -777px;
}
.progress-bar
{
  overflow: hidden;
  background: #ac92ec;
  width: 0;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
.progress-value
{
  color: #333;
  display: block;
  line-height: 21px;
  text-align: center;
}
.progress-bg
{
  background: #e6e9ed;
  position: relative;
  height: 8px;
  border-radius: 5px;
  overflow: hidden;
}

Next, we bring beauty :

.progress-bar:after
{
  background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
  background-image: -o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
  background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
  -webkit-background-size: 40px 40px;
  background-size: 40px 40px;
  position: absolute;
  content: '';
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Add animation :

@keyframes progress_bar {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: -40px 0;
  }
}
.progress-bar
{
  transition: width 1s linear;
}
.progress-bar:after
{
  animation: progress_bar 0.8s linear infinite;
}

And the most important point is putting down the width for the progress, and the numerical value in percent. Everything is simple here, the logic will be as follows:

.progress progress[value="1"] + .progress-value:before 
{
  content: "1%"; 
}
.progress progress[value="1"] ~ .progress-bg .progress-bar 
{
  width: 1%; 
}

It’s not difficult to guess, we need exactly 100 of these rules, for this we need preprocessors:

SCSS code:

@for $i from 0 through 100 {
  .progress progress[value="#{$i}"]
  {
    & + .progress-value:before { content : '#{$i}%' }
    & ~ .progress-bg .progress-bar { width: $i * 1% }
  }
}

Code on LESS:

.generate-progress(@n, @i: 0) when (@i =< @n) {
  .progress progress[value="@{i}"]
  {
	& + .progress-value:before { content : '@{i}%' }
	& ~ .progress-bg .progress-bar { width: @i * 1% }
  }
  .generate-progress(@n, (@i + 1));
}
.generate-progress(100);

The final example .

Of course there is a big minus - a lot of CSS in the output. But for me, the advantages of this method overlap huge CSS code.

Also popular now: