JSFiddle - React, Tailwind, and code Playground

by Nikita Polevoy

HTML

<script src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<h3>PhotoShop</h3>
<div class="skillbar" data-percent="79%">
  <div class="skillbar-container">
    <div class="skillbar-bar"></div>
  </div>
  <div class="skillbar-percent"></div>
</div>
<h3>Html/Css</h3>
<div class="skillbar" data-percent="90%">
  <div class="skillbar-container">
    <div class="skillbar-bar"></div>
  </div>
  <div class="skillbar-percent"></div>
</div>
<h3>JavaScript</h3>
<div class="skillbar" data-percent="69%">
  <div class="skillbar-container">
    <div class="skillbar-bar"></div>
  </div>
  <div class="skillbar-percent"></div>
</div>
<h3>Wordpress</h3>
<div class="skillbar" data-percent="92%">
  <div class="skillbar-container">
    <div class="skillbar-bar"></div>
  </div>
  <div class="skillbar-percent"></div>
</div>
<h3>Wordpress</h3>
<div class="skillbar" data-percent="100%">
  <div class="skillbar-container">
    <div class="skillbar-bar"></div>
  </div>
  <div class="skillbar-percent"></div>
</div>

SCSS

.skillbar {
  position: relative;
  display: block;
  margin-bottom: 38px;
  width: 100%;
  border: 1px solid #dddddd;
  height: 9px;
  background: #fff;
  &.active .skillbar-container {
    width: 100%;
  }
  &-bar {
    background: #009dda;
    position: relative;
    height: 100%;
    box-sizing: border-box;
  }
  &-container {
    height: 9px;
    position: relative;
    padding: 0px;
    box-sizing: border-box;
    width: 0;
    transition: width 1.5s ease;
  }
  &-percent {
    position: absolute;
    right: -1px;
    top: -46px;
    font-size: 13px;
    height: 35px;
    line-height: 35px;
    color: #000;
    font-weight: bold;
  }
}

JavaScript

jQuery.fn.extend({
  onAppearanceApply: function( f ) {
    var $window = $( window ),
        window_height = $window.height(),
        array_of_$elements = [];
    this.each(function(i,el) {
      array_of_$elements.push($( el ));
    })
    scrollHandler();
		if (array_of_$elements.length) {
      $window.on('resize', resizeHandler).on('resize', scrollHandler).on('scroll', scrollHandler);
    }
    function resizeHandler() {
      window_height = $window.height();
    }
    function watchProcessedElements(array_of_indexes) {
    	var l, i;
      for (l = array_of_indexes.length, i = l - 1; i > -1; --i) {
        array_of_$elements.splice(array_of_indexes[i], 1);
      }
      if (!array_of_$elements.length) {
        $window.off('resize', resizeHandler).off('scroll', scrollHandler).off('resize', scrollHandler);
      }
    }
    function scrollHandler() {
      var i, l, processed = [];
      for ( l = array_of_$elements.length, i = 0; i < l; ++i ) {
        if ($window.scrollTop() + window_height > array_of_$elements[i].offset().top) {
          f.call( array_of_$elements[i] );
          processed.push(i); 
        }
      }
      if (processed.length) {
        watchProcessedElements(processed);
      }
    }
    return this;
  }
})

var color_options = { 
	luminosity: 'bright'
};

$('.skillbar').onAppearanceApply( animate );


function animate() {
	var percent = parseInt( this.data('percent') ),
  		transition_element = this.find('.skillbar-container'),
  		span = this.find('.skillbar-percent');

  this.find('.skillbar-bar').css({
  	width: percent + '%',
    'background-color': randomColor(color_options)
  });
  $({ value: 0 }).animate({ value: percent }, {
  	duration: parseFloat( transition_element.css('transition-duration') ) * 1000,
    easing: transition_element.css('transition-easing'),
    step: function(val) {
    	span.text( ~~val + '%' );
    }
  })
	this.addClass('active');
}