Open/Close Navigation

Custom Digg-Style Animated Voting Badge

Anyone that remembers Digg will also remember the site’s revolutionary voting system. Although it doesn’t seem like much now, their Ajax-based vote interface was truly impressive back in the time of its inception(mid-2000s).

Digg has long since been sold & shut down yet the mark it left behind still remains. In memory of Digg’s classic voting style I’d like to demonstrate how to build an animated Digg voting badge with JavaScript.

My code is based on a previous vote flipper that has since been taken down & lost to the Internet(although small bits remain). I’m hoping to fill the void and give developers a chance to work with Digg’s animated voting badge once again.

Check out my live demo below and feel free to use this code in any web project.

digg style voting badge preview

Live DemoDownload Source Code

Getting Started

For this tutorial I’ll be working with an index.html document and a styles.css stylesheet. I’ve also included the latest version of Normalize to make styling easier.

Since the animation requires jQuery I’ve added the newest version 1.12.0 from Google’s CDN. Although this should work with any version of jQuery.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
	<title>Digg-Style Voting Badge Demo</title>
  <link rel="shortcut icon" href="http://www.vandelaydesign.com/wp-content/themes/vd/assets/graphics/favicon.png">
  <link rel="icon" href="http://www.vandelaydesign.com/wp-content/themes/vd/assets/graphics/favicon.png">
  <link rel="stylesheet" type="text/css" media="all" href="normalize.css">
	<link rel="stylesheet" type="text/css" media="all" href="styles.css">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>

The page markup uses a single container named .wrapper which centers content on the page. The voting badge itself has its own container with the class .votebadge broken down into two areas: the counter and the voting link.

My demo uses a blank link for voting but a real-world application could set the HREF value to an Ajax script. This way when each user votes it can actually be stored in the database – although without a backend language I’m not able to demonstrate how that works.

But regardless here’s the code you’ll find in the page body:

<div class="wrapper">
  
  <h1><span>Digg-Style Voting Badge</span></h1>
  
  <div class="votebadge">
  
	  <div class="votecount">
		  <div><em><strong>182</strong><span>Votes</span></em></div>
	  </div><!-- @end .votecount -->
	  <a class="vote" href="#">Push It</a>
	  
	</div><!-- @end .votebadge -->
	
</div><!-- @end .wrapper -->

CSS Page Styles

Moving into my stylesheet we’ll see there isn’t a whole lot of code needed for this design. Each element uses pure CSS which is nice for modern development.

The .votebadge element contains everything and it’s fixed at 80px width to maintain a consistent design.

Inside this is the .votecount class which holds the actual counter. Digg used a yellow gradient background for their counter and I’ve followed suit. Except this time we can use CSS3 instead of a background sprite.

/** voting badge styles **/
.votebadge {
  display: block;
  width: 80px;
  margin: 0 auto;
  margin-bottom: 10px;
}

.votecount {
  width: 68px;
  padding: 7px 0;
  padding-bottom: 11px;
  margin-bottom: 6px;
  text-align: center;
  background: #fff095;
  background: -moz-linear-gradient(-45deg,  #fff095 0%, #fff9d8 100%);
  background: -webkit-linear-gradient(-45deg,  #fff095 0%,#fff9d8 100%);
  background: linear-gradient(135deg,  #fff095 0%,#fff9d8 100%);
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff095', endColorstr='#fff9d8',GradientType=1);
  border-top-left-radius: 8px;
  border-bottom-right-radius: 8px;
}

.votecount div {
	position: relative;
	overflow: hidden;
	width: 63px;
	height: 43px;
}

.votecount em {
	display: block;
	position: relative;
	width: 63px;
	height: 33px;
	padding: 6px 0 6px 0;
  color: #4b4b4b;
	font: normal 21px/24px "Helvetica Neue","Helvetica","Arial",Sans-serif;
}
.votecount strong {
	font-weight: bold;
}
.votecount span {
	font-size: 10px;
	line-height: 10px;
	display: block;
	color: #9a9a94;
}

Text inside the counter div is contained within elements like <strong> and <em>. Each item uses relative positioning to maneuver things easier without padding or margins.

Also notice that the .votecount div and the internal anchor link stay fixed around 68px wide. This is slightly smaller than the container just to leave extra padding if there were text located alongside the voting badge.

Lastly we should look at the vote link which holds the class .vote. It’s located outside the counter div and rests directly underneath it.

/** link voting style **/
a.vote {
	display: block;
	width: 65px;
	background: #fff;
	padding: 5px 0;
	font-family: Helvetica, Arial, sans-serif;
	font-size: 12px;
	font-weight: bold;
	text-decoration: none;
	text-align: center;
	color: #396ead;
	font-weight: bold;
	border: 1px solid #dde9f6;
	border-top-left-radius: 5px;
	border-bottom-right-radius: 5px;
}
a.vote:hover {
	outline: none;
	color: #494949;
	border-color: #acc9eb;
}
a.voted,a.voted:hover {
	outline: none;
	cursor: default;
	color: #8b8d88;
	border-color: #eee;
}

Nothing really out of the ordinary here, just a fixed width and some padding to recreate that same Digg-style vote link. I’m also using opposite rounded corners in the top-left and bottom-right as was customary in Digg’s v3 layout.

jQuery Vote Animation

JavaScript is where things can get a little confusing so be sure to Google functions that you don’t understand. JS is easy once you get the basics but it does take a logical mindset of understanding how one action affects another.

Here are the first few lines of the JS script:

$(document).ready(function() {
    $(".votecount em").clone().appendTo(".votecount div");
	
    var node = $(".votecount em:last strong")
    node.text(parseInt(node.text())+1);

First is the jQuery clone() method which copies an element into the DOM. This makes a copy of the actual vote number in HTML and places it just underneath the current number(hidden with CSS overflow property).

By targeting this element with the :last CSS pseudo-class we can manipulate the value to increment by 1.

jQuery has a text() method which pulls out the number as a string. Thankfully JavaScript has a method parseInt() which parses text as an integer so we can add 1 to the count.

Next we need to define our own method called flip() which performs the animation. Then finally we’ll bind that method to the voting link so it runs only when a user clicks the vote button.

    function flip(obj) {
        obj.prev().find("em").animate({
          top: '-=45'
        }, 200);
        obj.toggleClass("voted",true);
        obj.text('Pushed!');
    }
	
    $('.vote').bind({
        click: function(event) {
          event.preventDefault()
        },
        mouseup: function() {
          flip($(this));
          $(this).unbind('mouseup');
        }
    });
});

The flip method takes a variable parameter known as obj. This stands for our voting object which in this case is the voting link. Whenever a user clicks any vote link we pass $(this) into the flip method, so whichever link gets clicked will be used for that instance. My demo has only 1 vote badge but this script can work for many different badges on the same page.

jQuery’s prev() method moves from the anchor link to its sibling .votecount. Then jQuery find() is used to locate the first vote count number and animate it out of sight. As that number moves up the hidden incremented number moves in to fill the space.

At the end of this flip() method we also change the vote text from “push it” to “pushed” while greying out the letters and changing the link class to prevent another vote.

At the very bottom of my JS script you’ll see the bind() method. This is used to listen for any user events on the page – in this case the click and mouseup events.

We run the whole flip() method every time a user clicks, but only once they complete the click(ie. mouseup).

So the click event actually uses preventDefault to stop the HREF value from loading into the address bar. This is standard practice with Ajax links because they don’t behave like regular links, so we need to tell the browser how to handle them with code.

All of this JavaScript is easy to understand once you learn about the individual methods and how they operate. If you’re confused at any point check out jQuery’s docs to learn more about any function and the role it plays within this script.

digg style voting badge preview

Live DemoDownload Source Code

Wrap-Up

Digg was a pioneer of social news and their voting badge has left quite a legacy on those who remember it. I hope this tutorial offers Digg lovers a brief trip down memory lane, and offers developers a simple codebase to play with and utilize for user-powered voting widgets.

Looking for hosting? WPEngine offers secure managed WordPress hosting. You’ll get expert WordPress support, automatic backups, and caching for fast page loads.