Stats Counter when in Viewport

Trigger statistic numbers to start counting once they are in the browser viewport.

by Jon Fuller

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://rawgit.com/dirkgroenen/jQuery-viewport-checker/master/dist/jquery.viewportchecker.min.js"></script>
<section class="container-fluid pushdown">
	<div>
		Scroll down for the good stuff to happen&hellip;
	</div>
</section>

<section class="container-fluid viewport-counter">
	<div class="row">
		<div class="col-xs-12 col-sm-4 stat">
			<h2>$<span class="count">10</span>B</h2>
			<h4>Big Dollars</h4>
			<p>Protecting gobs worth of assets nationwide.</p>
		</div>
		<div class="col-xs-12 col-sm-4 stat">
			<h2><span class="count">46</span>%</h2>
			<h4>Title Here</h4>
			<p>Clients save about half on equipment and labor.</p>
		</div>
		<div class="col-xs-12 col-sm-4 stat">
			<h2><span class="count">2300</span></h2>
			<h4>An H4 Tag</h4>
			<p>Thousands of equipment inventory locations nationwide.</p>
		</div>
	</div>
</section>

<section class="container-fluid pushdown">
	<div>
		&hellip;it just happened.<br><br>
		<small>Did you see it? You need jQuery. You'll also need the jQuery-viewport-checker by Dirk Groenen. You can see the custom settings that are set in the JS... and how they work with the classes used in HTML. The CSS is purely cosmetic.</small>
	</div>
</section>

CSS

.pushdown {
	position: relative;
	height: 200vh;
	background: #49c3e7;
	color: white;
}

.pushdown > div {
	position: absolute;
	top: 25%;
	left: 50%;
	transform: translate(-50%, -25%);
	
}

.viewport-counter {
	background: white;
}

.stat {
	text-align: center;
	padding: 0px 20px;
	margin: 75px 0;
	border-left: 3px solid #f2fbff;
	border-right: 3px solid #f2fbff;
}

.stat:first-child,
.stat:last-child {
	border: 0;
}

.stat h2 {
	color: #1e355e;
	font-size: 4em;
	margin: 0 0 0.5em;
	white-space: nowrap;
}

.stat h4 {
	text-transform: uppercase;
	font-size: 1.5em;
	color: #49c3e7;
}

.stat p {
	max-width: 350px;
	margin: 0 auto;
}

@media (min-width: 768px) and (max-width: 1000px) {
	.stat h2 {
		font-size: 3em;
	}
}

@media (max-width: 767px) {
	.stat {
		border: 0;
		border-top: 3px solid #f2fbff;
		border-bottom: 3px solid #f2fbff;
		margin: 0;
		padding: 75px 20px;
	}
}

@media (max-width: 480px) {
	.stat {
		padding: 33px 20px;
	}
	.stat h2 {
		font-size: 3em;
		margin-bottom: 0.25em;
	}
}

JavaScript

/**
 * jQuery-viewport-checker - v1.8.7 - 2015-12-17
 * https://github.com/dirkgroenen/jQuery-viewport-checker
 *
 * Copyright (c) 2015 Dirk Groenen
 * Licensed MIT <https://github.com/dirkgroenen/jQuery-viewport-checker/blob/master/LICENSE>
 */

!function(a){a.fn.viewportChecker=function(b){var c={classToAdd:"visible",classToRemove:"invisible",classToAddForFullView:"full-visible",removeClassAfterAnimation:!1,offset:100,repeat:!1,invertBottomOffset:!0,callbackFunction:function(a,b){},scrollHorizontal:!1,scrollBox:window};a.extend(c,b);var d=this,e={height:a(c.scrollBox).height(),width:a(c.scrollBox).width()},f=-1!=navigator.userAgent.toLowerCase().indexOf("webkit")||-1!=navigator.userAgent.toLowerCase().indexOf("windows phone")?"body":"html";return this.checkElements=function(){var b,g;c.scrollHorizontal?(b=a(f).scrollLeft(),g=b+e.width):(b=a(f).scrollTop(),g=b+e.height),d.each(function(){var d=a(this),f={},h={};if(d.data("vp-add-class")&&(h.classToAdd=d.data("vp-add-class")),d.data("vp-remove-class")&&(h.classToRemove=d.data("vp-remove-class")),d.data("vp-add-class-full-view")&&(h.classToAddForFullView=d.data("vp-add-class-full-view")),d.data("vp-keep-add-class")&&(h.removeClassAfterAnimation=d.data("vp-remove-after-animation")),d.data("vp-offset")&&(h.offset=d.data("vp-offset")),d.data("vp-repeat")&&(h.repeat=d.data("vp-repeat")),d.data("vp-scrollHorizontal")&&(h.scrollHorizontal=d.data("vp-scrollHorizontal")),d.data("vp-invertBottomOffset")&&(h.scrollHorizontal=d.data("vp-invertBottomOffset")),a.extend(f,c),a.extend(f,h),!d.data("vp-animated")||f.repeat){String(f.offset).indexOf("%")>0&&(f.offset=parseInt(f.offset)/100*e.height);var...