JSFiddle - React, Tailwind, and code Playground
Responsive progress meter
by Jennifer Perrin
HTML
<div class="inliner"></div>
<div class="inlined">
<div class="progress-meter">
<div class="track">
<span class="progress"></span>
</div>
<ol class="progress-points" data-current="4">
<li class="progress-point" data-point="1">
<span class="label">Lorem ipsum</span>
</li>
<li class="progress-point" data-point="2">
<span class="label">Aliquam tincidunt</span>
</li>
<li class="progress-point" data-point="3">
<span class="label">Vestibulum auctor</span>
</li>
<li class="progress-point" data-point="4">
<span class="label">Lorem ipsum</span></li>
<li class="progress-point" data-point="5">
<span class="label">Aliquam tincidunt</span>
</li>
</ol>
</div>
<div class="controls">
<button class="trigger">Toggle progress</button>
<p>Click any point to navigate to it directly</p>
</div>
</div>
CSS
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
font-size: 14px;
text-align: center;
}
.inliner {
height: 100%;
}
.inliner,
.inliner + .inlined {
display: inline-block;
vertical-align: middle;
}
.inlined {
width: 90%;
}
.progress-meter {
margin: 20px auto 40px;
padding: 40px;
}
.progress-meter {
counter-reset: point;
}
.progress-meter .progress-point:before {
-webkit-transition: all 1s;
-moz-transition: all 1s;
-o-transition: all 1s;
transition: all 1s;
-webkit-border-radius: 24px;
-moz-border-radius: 24px;
-ms-border-radius: 24px;
-o-border-radius: 24px;
border-radius: 24px;
-webkit-box-shadow: 0 0 0 2px white;
-moz-box-shadow: 0 0 0 2px white;
box-shadow: 0 0 0 2px white;
content: "\2713";
display: block;
width: 24px;
margin: 0 auto 12px;
border: 4px solid #aaaaaa;
text-align: center;
background-color: white;
color: white;
}
.progress-meter .track {
position: relative;
height: 4px;
background: #dddddd;
}
.progress-meter .progress {
-webkit-transition: width 1s;
-moz-transition: width 1s;
-o-transition: width 1s;
transition: width 1s;
display: block;
position: absolute;
left: 0;
top: 0;
width: 0;
height: 4px;
background: red;
}
.progress-meter .progress-points {
position: relative;
margin: -14px 0 0;
padding: 0;
list-style: none;
}
.progress-meter .progress-points [data-point='1'] {
left: 0%;
}
.progress-meter .progress-points [data-point='2'] {
left: 25%;
}
.progress-meter .progress-points [data-point='3'] {
left: 50%;
}
.progress-meter .progress-points [data-point='4'] {
left: 75%;
}
.progress-meter .progress-points [data-point='5'] {
left: 100%;
}
.progress-meter .progress-point {
-webkit-transition: color 1s;
-moz-transition: color 1s;
-o-transition: color 1s;
transition: color 1s;
position: absolute;
display: block;
width: 100px;
...
JavaScript
(function() {
var $point_arr, $points, $progress, $trigger, activate, active, max, tracker, val;
$trigger = $('.trigger').first();
$points = $('.progress-points').first();
$point_arr = $('[data-point]');
$progress = $('.progress').first();
val = parseInt($points.data('current')) - 1;
max = $point_arr.length - 1;
tracker = active = 0;
activate = function(index) {
if (index !== active) {
active = index;
$point_arr.removeClass('completed active');
$point_arr.slice(0, index).addClass('completed');
$point_arr.eq(active).addClass('active');
return $progress.css('width', (index / max * 100) + "%");
}
};
$points.on('click', 'li', function(event) {
var _index;
_index = $point_arr.index(this);
tracker = _index === 0 ? 1 : _index === val ? 0 : tracker;
return activate(_index);
});
$trigger.on('click', function() {
return activate(tracker++ % 2 === 0 ? 0 : val);
});
setTimeout((function() {
return activate(val);
}), 1000);
}).call(this);