<div class="wrapper"><div>
  <div class="progress">
<!--    <svg>
      <defs>
        <linearGradient id="progressGradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop stop-color="#376EA6" offset="0"/><stop stop-color="#8233A4" offset="0.5"/><stop stop-color="#B34646" offset="1"/>
        </linearGradient>

        <filter id="insetShadow" filterunits="userSpaceOnUse">
            <feFlood flood-color="#000" flood-opacity="1"></feFlood>
            <feComposite in2="SourceGraphic" operator="xor"></feComposite>
            <feGaussianBlur stdDeviation="3"></feGaussianBlur>
            <feOffset dx="0" dy="0" result="offsetblur"></feOffset>
            <feFlood flood-color="#aaa" flood-opacity="0.8"></feFlood>        <feComposite in2="offsetblur" operator="atop"></feComposite>
            <feComposite in2="SourceGraphic" operator="in"></feComposite>
            <feMerge>   
                <feMergeNode in="SourceGraphic"></feMergeNode>   
                <feMergeNode></feMergeNode>
            </feMerge>
        </filter>
      </defs>

      <path id="container" d="M10,0 L190,0 A1,1 0 1 1 190,20 L10,20 A1,1 0 1 1 10,0 z" 
            fill="#fff" filter="url(#insetShadow)"/>
      <path id="bar" d="M10,5 L50,5 A1,1 0 1 1 50,15 L10,15 A1,1 0 1 1 10,5 z"
            fill="url(#progressGradient)">

    </svg>-->
  </div>
  <div class="buttons">
      <button onclick="$('.progress').animate({progressBar: 0})">0%</button>
      <button onclick="$('.progress').animate({progressBar: 0.5})">50%</button>
      <button onclick="$('.progress').animate({progressBar: 1})">100%</button>
  </div>
</div></div>

html, body {
  margin: 0;
  background: #555;
  height: 100%;
}
.wrapper {
  display: table;
  max-width: 980px;
  width: 90%;
  margin: 0 auto;
  background: rgba(255,255,255,0.9);
  height: 100%;
  
  > div {
    display: table-cell;
    vertical-align: middle;
  }
}

.progress {
  width: 50%;
  margin: 0 auto;
  height: 40px;
  // border: 1px solid #999;
}
.progress svg {
  width: 100%;
  height: 100%;
}
.buttons {
  width: 50%;
  margin: 0 auto;
}

button {
  float: left;
  width: 25%;
  margin: 10px 25%*1/6;
  border: 1px solid #ccc;
  background: white;
  padding: 5px 10px;
  border-radius: 3px;
  
  &:hover, &:focus {
    border-color: #eaa;
    background: #fee;
  }
}
// SVG Based progress bar, example usage:

// $('.progress').progressBar({padding: 0, innerPadding: 5, progress: 0.5});
// $(window).resize(function() {
//   $('.progress').progressBar('refresh');
// });
// $('.progress').progressBar('set', 0.75);
// $('.progress').css({progressBar: 0.25});
// $('.progress').animate({progressBar: 0.75}, 1000);

// Customize the way the progress bar looks with SVG embedded below

var ProgressBar = {
  init: function(el, options) {
    this.options = $.extend({}, ProgressBar.defaults, options);
    this.$el = $(el);

    if(this.$el.attr('data-progress')) {
      this.options.progress = parseFloat(this.$el.attr('data-progress'));
    }

    this.$svg = this.$el.find('svg');
    if(!this.$svg.length) {
      this._createSvg();
    }
    this.$container = this.$svg.find('#container');
    this.$bar = this.$svg.find('#bar');

    this.options.supportSVGFilter = this.supportSVGFilter();
    if(!this.options.supportSVGFilter) {
      this.$container.attr('filter', null);
      this.$container.attr('stroke-width', '1');
    }

    this._draw();
  },
  set: function(progress) {
    this.options.progress = progress;
    this._draw();
  },
  refresh: function() {
    this._draw();
  },
  _createSvg: function() {
    this.$el.html(this.svgTemplate);
    this.$svg = this.$el.find('svg');
  },
  _draw: function() {
    var containerOptions = {
      pill: this.$container,
      paddingY: this.options.padding,
      paddingX: this.options.padding };
    
    var barOptions = {
      pill: this.$bar,
      paddingY: this.options.padding + this.options.innerPadding,
      paddingX: this.options.padding,
      width: this.options.progress };

    this._drawPill(containerOptions);
    this._drawPill(barOptions);
  },
  _drawPill: function(options) {
    var width = this.$svg.width();
    var height = this.$svg.height();
    var template = "M{LTP} {RTP} A1,1 0 1 1 {RBP} L{LBP} A1,1 0 1 1 {LTP} z";
    var topY = options.paddingY;
    var bottomY = height - options.paddingY;
    var leftX = options.paddingX + height/2;
    var barWidth = typeof options.width == "undefined" ?
        width :
        width * options.width;
    barWidth = Math.max(barWidth, height + options.paddingX*2);

    var rightX = barWidth - options.paddingX - height/2;
    var LTP = leftX + "," + topY;
    var RTP = rightX + "," + topY;
    var LBP = leftX + "," + bottomY;
    var RBP = rightX + "," + bottomY;
    var result = template.
      replace(/{LTP}/g, LTP).
      replace(/{RTP}/g, RTP).
      replace(/{LBP}/g, LBP).
      replace(/{RBP}/g, RBP);
    // console.log(result);
    options.pill.attr('d', result);
  }
}
$.fn.progressBar = function(options) {
  var originalArguments = arguments;
  this.each(function() {
    var progressBar = $.data(this, 'ProgressBar');
    if(!progressBar) {
      progressBar = Object.create(ProgressBar);
      progressBar.init(this, options);
      $.data(this, 'ProgressBar', progressBar);
      return;
    }
    if(!progressBar[options])
      return;
    
    progressBar[options](originalArguments[1]);
  });  
}
$.cssHooks.progressBar = {
  get: function(el) {
    var progressBar = $.data(el, 'ProgressBar');
    if(!progressBar) return 0;
    return progressBar.options.progress;
  },
  set: function(el, val) {
    val = parseFloat(val);
    var progressBar = $.data(el, 'ProgressBar');
    if(!progressBar) return;
    progressBar.set(val);
  }
}

ProgressBar.supportSVGFilter = function() {
  return typeof SVGFEColorMatrixElement !== "undefined" && SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE==2;
}

ProgressBar.defaults = {
  padding: 1,
  innerPadding: 4,
  progress: 0
}

// Since this is SVG, it won't work in IE8.
// IE9+ supports line continuation.
ProgressBar.svgTemplate = 
'<svg>\n\
  <defs>\n\
    <linearGradient id="progressGradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">\n\
      <stop stop-color="#376EA6" offset="0"/>\n\
      <stop stop-color="#8233A4" offset="0.5"/>\n\
      <stop stop-color="#B34646" offset="1"/>\n\
    </linearGradient>\n\
\n\
    <filter id="insetShadow" filterunits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">\n\
        <feFlood flood-color="#000" flood-opacity="1"></feFlood>\n\
        <feComposite in2="SourceGraphic" operator="xor"></feComposite>\n\
        <feGaussianBlur stdDeviation="2"></feGaussianBlur>\n\
        <feOffset dx="0" dy="0" result="offsetblur"></feOffset>\n\
        <feFlood flood-color="#000" flood-opacity="1"></feFlood>\n\
        <feComposite in2="offsetblur" operator="atop"></feComposite>\n\
        <feComposite in2="SourceGraphic" operator="in"></feComposite>\n\
        <feMerge>\n\
            <feMergeNode in="SourceGraphic"></feMergeNode>\n\
            <feMergeNode></feMergeNode>\n\
        </feMerge>\n\
    </filter>\n\
  </defs>\n\
\n\
  <path id="container"\n\
    d="M10,0 L190,0 A1,1 0 1 1 190,20 L10,20 A1,1 0 1 1 10,0 z"\n\
    fill="#fff" filter="url(#insetShadow)" stroke-width="0" stroke="#CCC" />\n\
  <path id="bar"\n\
    d="M10,5 L50,5 A1,1 0 1 1 50,15 L10,15 A1,1 0 1 1 10,5 z"\n\
    fill="url(#progressGradient)"/>\n\
</svg>';

$('.progress').progressBar({padding: 0, innerPadding: 5, progress: 0.5});
$(window).resize(function() {
  $('.progress').progressBar('refresh');
});
$('.progress').progressBar('set', 0.75);
$('.progress').css({progressBar: 0.25});
$('.progress').animate({progressBar: 0.75}, 1000);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js