Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                doctype html
html.no-js(lang='en')
  head
    meta(charset='UTF-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')
    meta(name='viewport', content='width=device-width, initial-scale=1.0')
    title Progress Button Styles
    meta(name='description', content='Progress Button Styles: Creative effects for loading buttons')
    meta(name='keywords', content='progress button, loading button, 3d, loading indicator, progress indicator')
    meta(name='author', content='Codrops')
    link(rel='shortcut icon', href='../favicon.ico')
  body
    .container
      .codrops-top.clearfix
      header
        h1
          | Progress Button Styles 
          span Creative effects for loading buttons
      .wrapper
        section
          h2 fill horizontal
          |  
          button.progress-button(data-style='fill', data-horizontal='') Submit
        section
          h2 fill vertical
          |  
          button.progress-button(data-style='fill', data-vertical='') Submit
        section
          h2 shrink horizontal
          |  
          button.progress-button(data-style='shrink', data-horizontal='') Submit
        section
          h2 shrink vertical
          |  
          button.progress-button(data-style='shrink', data-vertical='') Submit
      .wrapper
        section
          h2
            | rotate-angle-bottom
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-angle-bottom', data-perspective='', data-horizontal='') Submit
        section
          h2
            | rotate-angle-top
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-angle-top', data-perspective='', data-horizontal='') Submit
        section
          h2
            | rotate-angle-left
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-angle-left', data-perspective='', data-vertical='') Submit
        section
          h2
            | rotate-angle-right
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-angle-right', data-perspective='', data-vertical='') Submit
      .wrapper
        section
          h2
            | rotate-side-down
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-side-down', data-perspective='', data-horizontal='') Submit
        section
          h2
            | rotate-side-up
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-side-up', data-perspective='', data-horizontal='') Submit
        section
          h2
            | rotate-side-left
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-side-left', data-perspective='', data-vertical='') Submit
        section
          h2
            | rotate-side-right
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-side-right', data-perspective='', data-vertical='') Submit
      .wrapper
        section
          h2
            | rotate-back
            br
            | perspective
          |  
          button.progress-button(data-style='rotate-back', data-perspective='', data-horizontal='') Submit
        section
          h2
            | flip-open
            br
            | perspective
          |  
          button.progress-button(data-style='flip-open', data-perspective='', data-horizontal='') Submit
        section
          h2
            | slide-down
            br
            | horizontal
          |  
          button.progress-button(data-style='slide-down', data-horizontal='') Submit
        section
          h2
            | move-up
            br
            | horizontal
          |  
          button.progress-button(data-style='move-up', data-horizontal='') Submit
      .wrapper
        section
          h2
            | top-line
            br
            | horizontal
          |  
          button.progress-button(data-style='top-line', data-horizontal='') Submit
        section
          h2
            | lateral-lines
            br
            | vertical
          |  
          button.progress-button(data-style='lateral-lines', data-vertical='') Submit
        h1
          | Read more at 
          a omegakd.blogspot.com
              
            
!

CSS

              
                *
  -webkit-box-sizing: border-box
  -moz-box-sizing: border-box
  box-sizing: border-box
  &:after, &::before
    -webkit-box-sizing: border-box
    -moz-box-sizing: border-box
    box-sizing: border-box

@font-face
  font-weight: normal
  font-style: normal
  font-family: 'icomoon'
  src: url('../fonts/icomoon/icomoon.eot')
  src: url('../fonts/icomoon/icomoon.eot?#iefix') format("embedded-opentype"), url('../fonts/icomoon/icomoon.ttf') format("truetype"), url('../fonts/icomoon/icomoon.woff') format("woff"), url('../fonts/icomoon/icomoon.svg#icomoon') format("svg")

@font-face
  font-family: 'FontAwesome'
  font-display: fallback
  src: url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.eot?v=4.7.0')
  src: url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format("embedded-opentype"), url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0') format("woff2"), url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0') format("woff"), url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0') format("truetype"), url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format("svg")
  font-weight: normal
  font-style: normal

/* General styles for all types of buttons

.progress-button
  position: relative
  display: inline-block
  padding: 0 60px
  outline: none
  border: none
  background: #1d9650
  color: #fff
  text-transform: uppercase
  letter-spacing: 1px
  font-size: 1em
  line-height: 4
  &[disabled]
    cursor: default
    &.state-loading
      cursor: default
  .content
    position: relative
    display: block
    &::before, &::after
      position: absolute
      right: 20px
      color: #0e7138
      font-family: "FontAwesome"
      opacity: 0
      -webkit-transition: opacity 0.3s 0.3s
      transition: opacity 0.3s 0.3s
    &::before
      content: "\f00c"
      /* Checkmark for success
    &::after
      content: "\f071"
      /* Cross for error
  &.state-success .content::before, &.state-error .content::after
    opacity: 1

.notransition
  -webkit-transition: none !important
  transition: none !important

.progress-button
  .progress
    background: #148544
  .progress-inner
    position: absolute
    left: 0
    background: #0e7138
  &[data-horizontal] .progress-inner
    top: 0
    width: 0
    height: 100%
    -webkit-transition: width 0.3s, opacity 0.3s
    transition: width 0.3s, opacity 0.3s
  &[data-vertical] .progress-inner
    bottom: 0
    width: 100%
    height: 0
    -webkit-transition: height 0.3s, opacity 0.3s
    transition: height 0.3s, opacity 0.3s
  &[data-perspective]
    position: relative
    display: inline-block
    padding: 0
    background: transparent
    -webkit-perspective: 900px
    perspective: 900px
    .content
      padding: 0 60px
      background: #1d9650
    .progress-wrap
      display: block
      -webkit-transition: -webkit-transform 0.2s
      transition: transform 0.2s
      -webkit-transform-style: preserve-3d
      transform-style: preserve-3d
    .content, .progress
      outline: 1px solid rgba(0, 0, 0, 0)
      /* Smoothen jagged edges in FF
  &[data-style="fill"]
    &[data-horizontal]
      overflow: hidden
      .content
        z-index: 10
        -webkit-transition: -webkit-transform 0.3s
        transition: transform 0.3s
        &::before, &::after
          top: 100%
          right: auto
          left: 50%
          -webkit-transition: opacity 0.3s
          transition: opacity 0.3s
          -webkit-transform: translateX(-50%)
          transform: translateX(-50%)
      &.state-success .content, &.state-error .content
        -webkit-transform: translateY(-100%)
        transform: translateY(-100%)
    &[data-vertical]
      overflow: hidden
      .content
        z-index: 10
        -webkit-transition: -webkit-transform 0.3s
        transition: transform 0.3s
        &::before, &::after
          top: 100%
          right: auto
          left: 50%
          -webkit-transition: opacity 0.3s
          transition: opacity 0.3s
          -webkit-transform: translateX(-50%)
          transform: translateX(-50%)
      &.state-success .content, &.state-error .content
        -webkit-transform: translateY(-100%)
        transform: translateY(-100%)
  &[data-style="shrink"]
    /* common for horizontal and vertical
    overflow: hidden
    -webkit-transition: -webkit-transform 0.2s
    transition: transform 0.2s
    &[data-horizontal]
      .content
        -webkit-transition: opacity 0.3s, -webkit-transform 0.3s
        transition: opacity 0.3s, transform 0.3s
        &::before, &::after
          top: 100%
          right: auto
          left: 50%
          -webkit-transition: opacity 0.3s
          transition: opacity 0.3s
          -webkit-transform: translateX(-50%)
          transform: translateX(-50%)
      &.state-loading
        -webkit-transform: scaleY(0.3)
        transform: scaleY(0.3)
        .content
          opacity: 0
      &.state-success .content, &.state-error .content
        -webkit-transform: translateY(-100%)
        transform: translateY(-100%)
    &[data-vertical]
      .content
        -webkit-transition: opacity 0.3s, -webkit-transform 0.3s
        transition: opacity 0.3s, transform 0.3s
        &::before, &::after
          top: 100%
          right: auto
          left: 50%
          -webkit-transition: opacity 0.3s
          transition: opacity 0.3s
          -webkit-transform: translateX(-50%)
          transform: translateX(-50%)
      &.state-loading
        -webkit-transform: scaleX(0.1)
        transform: scaleX(0.1)
        .content
          opacity: 0
      &.state-success .content, &.state-error .content
        -webkit-transform: translateY(-100%)
        transform: translateY(-100%)
  &[data-style="rotate-angle-bottom"]
    .progress
      position: absolute
      top: 100%
      left: 0
      width: 100%
      height: 20px
      box-shadow: 0 -1px 0 #148544
      /* fix the blurriness that causes a gap
      -webkit-transform: rotateX(-90deg)
      transform: rotateX(-90deg)
      -webkit-transform-origin: 50% 0%
      transform-origin: 50% 0%
    &.state-loading .progress-wrap
      -webkit-transform: rotateX(45deg)
      transform: rotateX(45deg)
  &[data-style="rotate-angle-top"]
    .progress
      position: absolute
      bottom: 100%
      left: 0
      width: 100%
      height: 20px
      box-shadow: 0 1px 0 #148544
      /* fix the blurriness that causes a gap
      -webkit-transform: rotateX(90deg)
      transform: rotateX(90deg)
      -webkit-transform-origin: 50% 100%
      transform-origin: 50% 100%
    &.state-loading .progress-wrap
      -webkit-transform: rotateX(-45deg)
      transform: rotateX(-45deg)
  &[data-style="rotate-angle-left"]
    .progress
      position: absolute
      top: 0
      right: 100%
      width: 20px
      height: 100%
      box-shadow: 1px 0 0 #148544
      /* fix the blurriness that causes a gap
      -webkit-transform: rotateY(-90deg)
      transform: rotateY(-90deg)
      -webkit-transform-origin: 100% 50%
      transform-origin: 100% 50%
    &.state-loading .progress-wrap
      -webkit-transform: rotateY(45deg)
      transform: rotateY(45deg)
  &[data-style="rotate-angle-right"]
    .progress
      position: absolute
      top: 0
      left: 100%
      width: 20px
      height: 100%
      box-shadow: -1px 0 0 #148544
      /* fix the blurriness that causes a gap
      -webkit-transform: rotateY(90deg)
      transform: rotateY(90deg)
      -webkit-transform-origin: 0% 50%
      transform-origin: 0% 50%
    &.state-loading .progress-wrap
      -webkit-transform: rotateY(-45deg)
      transform: rotateY(-45deg)
  &[data-style="rotate-side-down"]
    .progress
      position: absolute
      top: 100%
      left: 0
      width: 100%
      height: 20px
      -webkit-transform: rotateX(-90deg)
      transform: rotateX(-90deg)
      -webkit-transform-origin: 50% 0%
      transform-origin: 50% 0%
      -webkit-backface-visibility: hidden
      backface-visibility: hidden
    &.state-loading .progress-wrap
      -webkit-transform: rotateX(90deg) translateZ(10px)
      transform: rotateX(90deg) translateZ(10px)
  &[data-style="rotate-side-up"]
    .progress
      position: absolute
      bottom: 100%
      left: 0
      width: 100%
      height: 20px
      -webkit-transform: rotateX(90deg)
      transform: rotateX(90deg)
      -webkit-transform-origin: 50% 100%
      transform-origin: 50% 100%
      -webkit-backface-visibility: hidden
      backface-visibility: hidden
    &.state-loading .progress-wrap
      -webkit-transform: rotateX(-90deg) translateZ(10px)
      transform: rotateX(-90deg) translateZ(10px)
  &[data-style="rotate-side-left"]
    .progress-wrap
      -webkit-transform-origin: 0 50%
      transform-origin: 0 50%
    .progress
      position: absolute
      top: 0
      left: 0
      width: 20px
      height: 100%
      -webkit-transform: rotateY(90deg)
      transform: rotateY(90deg)
      -webkit-transform-origin: 0 50%
      transform-origin: 0 50%
    &.state-loading .progress-wrap
      -webkit-transform: translateX(50%) rotateY(90deg) translateZ(10px)
      transform: translateX(50%) rotateY(90deg) translateZ(10px)
  &[data-style="rotate-side-right"]
    .progress-wrap
      -webkit-transform-origin: 100% 50%
      transform-origin: 100% 50%
    .progress
      position: absolute
      top: 0
      left: 100%
      width: 20px
      height: 100%
      -webkit-transform: rotateY(90deg)
      transform: rotateY(90deg)
      -webkit-transform-origin: 0 50%
      transform-origin: 0 50%
    &.state-loading .progress-wrap
      -webkit-transform: translateX(-50%) rotateY(-90deg) translateZ(10px)
      transform: translateX(-50%) rotateY(-90deg) translateZ(10px)
  &[data-style="rotate-back"]
    .progress-wrap
      -webkit-transition-timing-function: ease-out
      transition-timing-function: ease-out
    .content
      -webkit-backface-visibility: hidden
      backface-visibility: hidden
    .progress
      position: absolute
      top: 100%
      left: 0
      width: 100%
      height: 100%
      -webkit-transform: rotateX(-180deg)
      transform: rotateX(-180deg)
      -webkit-transform-origin: 50% 0%
      transform-origin: 50% 0%
      -webkit-backface-visibility: hidden
      backface-visibility: hidden
    &.state-loading .progress-wrap
      -webkit-transform: rotateX(180deg) scaleX(0.6) scaleY(0.3)
      transform: rotateX(180deg) scaleX(0.6) scaleY(0.3)
  &[data-style="flip-open"]
    .content
      z-index: 10
      -webkit-transition: -webkit-transform 0.2s
      transition: transform 0.2s
      -webkit-transform-origin: 50% 0
      transform-origin: 50% 0
    .progress
      position: absolute
      top: 0
      left: 0
      width: 100%
      height: 100%
    &.state-loading .content
      -webkit-transform: rotateX(45deg)
      transform: rotateX(45deg)
  &[data-style="slide-down"]
    padding: 0
    overflow: visible
    -webkit-backface-visibility: hidden
    backface-visibility: hidden
    .content
      z-index: 10
      padding: 0 60px
      background: #1d9650
    .progress
      position: absolute
      top: 0
      left: 0
      width: 100%
      height: 100%
      -webkit-transition: -webkit-transform 0.2s
      transition: transform 0.2s
    &.state-loading .progress
      -webkit-transform: translateY(10px)
      transform: translateY(10px)
  &[data-style="move-up"]
    padding: 0
    overflow: visible
    -webkit-backface-visibility: hidden
    backface-visibility: hidden
    .content
      z-index: 10
      padding: 0 60px
      background: #1d9650
      -webkit-transition: -webkit-transform 0.2s
      transition: transform 0.2s
    .progress
      position: absolute
      top: 0
      left: 0
      width: 100%
      height: 100%
    &.state-loading .content
      -webkit-transform: translateY(-10px)
      transform: translateY(-10px)
  &[data-style="top-line"]
    .progress-inner
      height: 3px
    .content
      &::before, &::after
        right: auto
        left: 100%
        margin-left: 25px
  &[data-style="lateral-lines"]
    .progress-inner
      width: 100%
      border-right: 3px solid #0e7138
      border-left: 3px solid #0e7138
      background: transparent
    .content
      &::before, &::after
        right: auto
        left: 100%
        margin-left: 25px

/* Necessary 3d styles for buttons with perspective

/* Individual styles
/* Choose the effect(s) you want, delete the rest

/* Fill horizontal
/* ======================

/* Fill vertical
/* ======================

/* Shrink horizontal
/* ======================

/* Shrink vertical
/* ======================

/* Rotate bottom 3d
/* ======================

/* Rotate top 3d
/* ======================

/* Rotate left 3d
/* ======================

/* Rotate right 3d
/* ======================

/* Rotate side down 3d
/* ======================

/* Rotate side up 3d
/* ======================

/* Rotate side left 3d
/* ======================

/* Rotate side right 3d
/* ======================

/* Rotate back 3d
/* ======================

/* flip open 3d
/* ======================

/* slide down
/* ======================

/* move-up
/* ======================

/* top-line
/* ======================

/* lateral-lines
/* ======================

/*************************************/

@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700)

@font-face
  font-family: 'codropsicons'
  src: url('../fonts/codropsicons/codropsicons.eot')
  src: url('../fonts/codropsicons/codropsicons.eot?#iefix') format("embedded-opentype"), url('../fonts/codropsicons/codropsicons.woff') format("woff"), url('../fonts/codropsicons/codropsicons.ttf') format("truetype"), url('../fonts/codropsicons/codropsicons.svg#codropsicons') format("svg")
  font-weight: normal
  font-style: normal


body
  background: #27ae60
  color: #fff
  font-family: 'Lato', Arial, sans-serif

.clearfix
  &:before
    content: ''
    display: table
  &:after
    content: ''
    display: table
    clear: both

a
  color: #148544
  text-decoration: none
  outline: none
  &:hover, &:focus
    color: #fff

.container > header
  margin: 0 auto 2em
  padding: 2em
  text-align: center
  background: rgba(0, 0, 0, 0.01)
  h1
    font-size: 3.5em
    line-height: 1.3
    margin: 0
    font-weight: 300
  span
    display: block
    font-size: 60%
    color: #148544
    padding: 0.3em 0 0.6em 0.1em

.note
  color: #85cd62

/* To Navigation Style

.codrops-top
  text-transform: uppercase
  width: 100%
  font-size: 0.69em
  line-height: 2.2
  font-weight: 700
  a
    text-decoration: none
    padding: 0 1em
    letter-spacing: 0.1em
    display: inline-block
  span.right
    float: right
    a
      float: left
      display: block

.codrops-icon:before
  font-family: 'codropsicons'
  margin: 0 4px
  speak: none
  font-style: normal
  font-weight: normal
  font-variant: normal
  text-transform: none
  line-height: 1
  -webkit-font-smoothing: antialiased

.codrops-icon-drop:before
  content: "\e001"

.codrops-icon-prev:before
  content: "\e004"

.wrapper
  text-align: center
  vertical-align: top

section
  position: relative
  text-align: center
  padding: 1em 1em 3em

.wrapper section
  display: inline-block
  width: 300px

section h2
  text-transform: uppercase
  letter-spacing: 1px
  color: #148544
  font-weight: 700
  padding: 1em
  font-size: 0.8em
  -webkit-backface-visibility: hidden

.related
  font-size: 2em
  font-weight: 300

@media screen and (max-width: 25em)
  .container > header
    font-size: 70%
  .related
    font-size: 120%
  .codrops-icon span
    display: none
              
            
!

JS

              
                /*!
 * classie - class helper functions
 * from bonzo https://github.com/ded/bonzo
 * 
 * classie.has( elem, 'my-class' ) -> true/false
 * classie.add( elem, 'my-new-class' )
 * classie.remove( elem, 'my-unwanted-class' )
 * classie.toggle( elem, 'my-class' )
 */

/*jshint browser: true, strict: true, undef: true */
/*global define: false */

( function( window ) {

'use strict';

// class helper functions from bonzo https://github.com/ded/bonzo

function classReg( className ) {
  return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}

// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;

if ( 'classList' in document.documentElement ) {
  hasClass = function( elem, c ) {
    return elem.classList.contains( c );
  };
  addClass = function( elem, c ) {
    elem.classList.add( c );
  };
  removeClass = function( elem, c ) {
    elem.classList.remove( c );
  };
}
else {
  hasClass = function( elem, c ) {
    return classReg( c ).test( elem.className );
  };
  addClass = function( elem, c ) {
    if ( !hasClass( elem, c ) ) {
      elem.className = elem.className + ' ' + c;
    }
  };
  removeClass = function( elem, c ) {
    elem.className = elem.className.replace( classReg( c ), ' ' );
  };
}

function toggleClass( elem, c ) {
  var fn = hasClass( elem, c ) ? removeClass : addClass;
  fn( elem, c );
}

var classie = {
  // full names
  hasClass: hasClass,
  addClass: addClass,
  removeClass: removeClass,
  toggleClass: toggleClass,
  // short names
  has: hasClass,
  add: addClass,
  remove: removeClass,
  toggle: toggleClass
};

// transport
if ( typeof define === 'function' && define.amd ) {
  // AMD
  define( classie );
} else {
  // browser global
  window.classie = classie;
}

})( window );


/****************************************/

/* script */
/**
 * progressButton.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * https://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
;( function( window ) {
	
	'use strict';

	// https://gist.github.com/edankwan/4389601
	Modernizr.addTest('csstransformspreserve3d', function () {
		var prop = Modernizr.prefixed('transformStyle');
		var val = 'preserve-3d';
		var computedStyle;
		if(!prop) return false;

		prop = prop.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');

		Modernizr.testStyles('#modernizr{' + prop + ':' + val + ';}', function (el, rule) {
			computedStyle = window.getComputedStyle ? getComputedStyle(el, null).getPropertyValue(prop) : '';
		});

		return (computedStyle === val);
	});

	function extend( a, b ) {
		for( var key in b ) { 
			if( b.hasOwnProperty( key ) ) {
				a[key] = b[key];
			}
		}
		return a;
	}

	// support
	var support = { transitions : Modernizr.csstransitions, transforms3d : Modernizr.csstransforms3d && Modernizr.csstransformspreserve3d },
		// transition end event name
		transEndEventNames = {
			'WebkitTransition': 'webkitTransitionEnd',
			'MozTransition': 'transitionend',
			'OTransition': 'oTransitionEnd',
			'msTransition': 'MSTransitionEnd',
			'transition': 'transitionend'
		},
		transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ];

	function ProgressButton( el, options ) {
		this.button = el;
		this.options = extend( {}, this.options );
  		extend( this.options, options );
  		this._init();
	}

	ProgressButton.prototype.options = {
		// time in ms that the status (success or error will be displayed)
		// during this time the button will be disabled
		statusTime : 1500
	};

	ProgressButton.prototype._init = function() {
		this._validate();
		// create structure
		this._create();
		// init events
		this._initEvents();
	};

	ProgressButton.prototype._validate = function() {
		// we will consider the fill/horizontal as default
		if( this.button.getAttribute( 'data-style' ) === null ) {
			this.button.setAttribute( 'data-style', 'fill' );
		}
		if( this.button.getAttribute( 'data-vertical' ) === null && this.button.getAttribute( 'data-horizontal' ) === null ) {
			this.button.setAttribute( 'data-horizontal', '' );
		}
		if( !support.transforms3d && this.button.getAttribute( 'data-perspective' ) !== null ) {
			this.button.removeAttribute( 'data-perspective' );
			this.button.setAttribute( 'data-style', 'fill' );
			this.button.removeAttribute( 'data-vertical' );
			this.button.setAttribute( 'data-horizontal', '' );
		}
	};

	ProgressButton.prototype._create = function() {
		var textEl = document.createElement( 'span' );
		textEl.className = 'content';
		textEl.innerHTML = this.button.innerHTML;
		var progressEl = document.createElement( 'span' );
		progressEl.className = 'progress';

		var progressInnerEl = document.createElement( 'span' );
		progressInnerEl.className = 'progress-inner';
		progressEl.appendChild( progressInnerEl );
		// clear content
		this.button.innerHTML = '';

		if( this.button.getAttribute( 'data-perspective' ) !== null ) {
			var progressWrapEl = document.createElement( 'span' );
			progressWrapEl.className = 'progress-wrap';
			progressWrapEl.appendChild( textEl );
			progressWrapEl.appendChild( progressEl );
			this.button.appendChild( progressWrapEl );
		}
		else {
			this.button.appendChild( textEl );
			this.button.appendChild( progressEl );
		}
		
		// the element that serves as the progress bar
		this.progress = progressInnerEl;

		// property to change on the progress element
		if( this.button.getAttribute( 'data-horizontal' ) !== null ) {
			this.progressProp = 'width';
		}
		else if( this.button.getAttribute( 'data-vertical' ) !== null ) {
			this.progressProp = 'height';
		}
		this._enable();
	};

	ProgressButton.prototype._setProgress = function( val ) {
		this.progress.style[ this.progressProp ] = 100 * val + '%';
	};

	ProgressButton.prototype._initEvents = function() {
		var self = this;
		this.button.addEventListener( 'click', function() {
			// disable the button
			self.button.setAttribute( 'disabled', '' );
			// add class state-loading to the button (applies a specific transform to the button depending which data-style is defined - defined in the stylesheets)
			classie.remove( self.progress, 'notransition' );
			classie.add( this, 'state-loading' );

			setTimeout( function() {
				if( typeof self.options.callback === 'function' ) {
					self.options.callback( self );
				}
				else {
					self._setProgress( 1 );
					var onEndTransFn = function( ev ) {
						if( support.transitions && ev.propertyName !== self.progressProp ) return;
						this.removeEventListener( transEndEventName, onEndTransFn );
						self._stop();
					};
					
					if( support.transitions ) {
						self.progress.addEventListener( transEndEventName, onEndTransFn );
					}
					else {
						onEndTransFn.call();
					}
					
				}
			}, 
			self.button.getAttribute( 'data-style' ) === 'fill' || 
			self.button.getAttribute( 'data-style' ) === 'top-line' ||
			self.button.getAttribute( 'data-style' ) === 'lateral-lines' ? 0 : 200 ); // TODO: change timeout to transitionend event callback
		} );
	};

	ProgressButton.prototype._stop = function( status ) {
		var self = this;

		setTimeout( function() {
			// fade out progress bar
			self.progress.style.opacity = 0;
			var onEndTransFn = function( ev ) {
				if( support.transitions && ev.propertyName !== 'opacity' ) return;
				this.removeEventListener( transEndEventName, onEndTransFn );
				classie.add( self.progress, 'notransition' );
				self.progress.style[ self.progressProp ] = '0%';
				self.progress.style.opacity = 1;
			};

			if( support.transitions ) {
				self.progress.addEventListener( transEndEventName, onEndTransFn );
			}
			else {
				onEndTransFn.call();
			}
			
			
			// add class state-success to the button
			if( typeof status === 'number' ) {
				var statusClass = status >= 0 ? 'state-success' : 'state-error';
				classie.add( self.button, statusClass );
				// after options.statusTime remove status
				setTimeout( function() {
					classie.remove( self.button, statusClass );
					self._enable();
				}, self.options.statusTime );
			}
			else {
				self._enable();
			}

			// remove class state-loading from the button
			classie.remove( self.button, 'state-loading' );
		}, 100 );
	};

	// enable button
	ProgressButton.prototype._enable = function() {
		this.button.removeAttribute( 'disabled' );
	}

	// add to global namespace
	window.ProgressButton = ProgressButton;

})( window );

/****************************************/
/*script initioalization */

[].slice.call( document.querySelectorAll( 'button.progress-button' ) ).forEach( function( bttn ) {
				new ProgressButton( bttn, {
					callback : function( instance ) {
						var progress = 0,
							interval = setInterval( function() {
								progress = Math.min( progress + Math.random() * 0.1, 1 );
								instance._setProgress( progress );

								if( progress === 1 ) {
									instance._stop(1);
									clearInterval( interval );
								}
							}, 200 );
					}
				} );
			} );

              
            
!
999px

Console