Code an Awesome Hire Me Card With Your Gravatar

It’s been a while since we polished our HTML and CSS skills with a fun little demo, let’s end that streak with a project that’s both super attractive and super practical.

Today we’re going to build a card-style “Hire Me” widget that you can quickly drop onto any web page. Along the way we’ll learn a bunch of great stuff about CSS positioning and how to use pseudo elements to pull off some cool effects.

2 Million+ Digital Assets, With Unlimited Downloads

Get unlimited downloads of 2 million+ design resources, themes, templates, photos, graphics and more. Envato Elements starts at $16 per month, and is the best creative subscription we've ever seen.

Explore Digital Assets

What We’re Building

I was recently browsing through the awesome free PSD library at our sister site PixelsDaily and came across this gem from designer Marc Gonzales.

screenshot

I love both the idea here as well as the execution. Every portfolio should have a clear way to hire the designer and this provides an easy and attractive way to integrate that functionality.

Marc has done an awesome job here, but the file that he provides is a layered PSD. Today we’re going to use this as inspiration for our own similar widget built entirely out of CSS and HTML. We’ll change a few things along the way and take a few liberties, but ultimately the final piece will be very similar to what we see here.

Step 1. HTML Setup

The first thing that we’re going to do is set up some very basic HTML that will serve as the structure for our badge. We’ll use a two div structure: the outer div will hold the card as a whole and the inner div will be a nice and easy way to group all of our text objects together.

In the outer div, toss in an image that will serve as your avatar. In the inner div, include an h3 with your name, a paragraph with your job title and an anchor tag with the words “Hire Me.” Your code should look something like the following.

<div class="hireme">
  <img src="http://www.gravatar.com/avatar/fe57710fac9365df9ec8d3cda0857f13?s=80&d=identicon?" alt="avatar">

  <div class="hiretext">
    <h3>Josh Johnson</h3>
    <p>Web Designer</p>
    <a href="#">Hire Me</a>
  </div>

</div>

Gravatar

In the original PSD design, the avatar wasn’t quite square, it was a horizontal rectangle. However, it occurs to me that this is a perfect use for Gravatar, an awesome and extremely popular service that allows you to set up a global avatar that will work across the thousands of sites that use their system.

“My avatar image in this badge will continually update every time I decide to change my avatar on Gravatar.”

By utilizing this system, my avatar image in this badge will continually update every time I decide to change my avatar on Gravatar. Pretty cool! The question is, how do I grab my Gravatar? There’s an official guide for this, but transforming your Gravatar into a link is a little complicated, so I just used this handy tool to do it for me.

Once we have the link, we need to customize its size. Every Gravatar is a square to keep things simple and uniform, so you only need one value. Examine your link for this snippet:

s=48

For our project, we’ll want the image to be 80px by 80px, so we’ll change the “48” to “80”. Here’s the full snippet for mine:

  <img src="http://www.gravatar.com/avatar/fe57710fac9365df9ec8d3cda0857f13?s=80&d=identicon?" alt="avatar">

Step 1 Progress Check

At this point, you should have a pretty simple page containing only your avatar and a few unstyled pieces of text.

screenshot

Step 2. Basic Card CSS

We’ve got all of the markup we’ll need for this entire project, but it’ll look like a jumbled mess at this point, so it’s time to start prettying it up. The first thing we’ll do here is draw the basic shape of the card. Here’s the code:

/*Hire Me Card*/
.hireme {
  margin: 40px;
  height: 100px;
  width: 250px;
  background: #ccc;
  border-radius: 10px;
  position: relative;
}

As you can see, we gave it a height and a width, set the background color and applied a border radius to round off the corners. Take note of the relative positioning used here, this will become relevant later on, I’m just planning ahead.

Beyond rounded corners, the original card design has a couple more features that will take some hefty CSS3 code to accomplish. First off is box-shadow, which is easy enough and only requires one alternate browser prefix at this point. Adding a gradient though, is still a huge mess. I hate coding gradients by hand so I use this generator to create code for the linear gradient that we need.

Here’s the resulting code (I added a body color as well):

body {
  background: #222;
}

/*Hire Me Card*/
.hireme {
  margin: 40px;
  height: 100px;
  width: 250px;
  background: #ccc;
  border-radius: 10px;
  position: relative;
  
  -webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  box-shadow: 3px 3px 5px rgba(0,0,0,0.5);

  background-image: linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -o-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -ms-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, rgb(217,217,217)), color-stop(0.7, rgb(245,245,245)));
}

Step 2 Progress Check

After adding this code, we can clearly see the finished card shape. The problem now is that our content is busting outside of the card’s bounds, we’ll address this soon.

screenshot

Step 3. Style the Avatar

Before we dive into fixing the ugly text problem, let’s get our avatar styled and pushed into place.

.hireme img {
  margin: 10px 0 0 10px;
  border-radius: 10px;
  height: 80px;
  width: 80px;
}

All we’ve done here is nudge the image with margins, ensure that we’re getting the proper size no matter what image you’re using and added a border radius. Notice that this doesn’t require browser prefixes any more. Hooray!

Step 3 Progress Check

Slowly but surely, we’re making progress. Now our avatar is in place with the styling that we want. Next, we’ll tackle the text!

screenshot

Step 4. Style the Text

The way that the text is currently flowing is no good. We need to get it off to the right of the avatar rather than under it. We could float it, but I think that absolute positioning is going to give us more freedom and flexibility to push it exactly where we want it.

/*Hire Me Text*/
.hiretext {
  position: absolute;
  top: 8px;
  left: 105px;
  text-align: center;
}

As you can see, after applying absolute positioning, I nudged it down and left, then center-aligned all of the text. This is where our relative positioning that we applied earlier comes into play. Using this technique, the absolutely positioned inner div will consider the zero point to be the relatively positioned outer div instead of the top left point of the canvas.

screenshot

Style the Header and Paragraph

Now that we’ve got the text nudged into place, let’s style it up. We’ll start by focusing on the header and paragraph. All we really need is to apply some font styling and a color for each.

.hiretext h3 {
  font: 20px Helvetica, Verdana, sans-serif;
  color: #1b83a0;
}

.hiretext p {
  font: 12px Helvetica, Verdana, sans-serif;
  color: #494949;
}

With that little bit of code, we’re already looking much better. We just need to style that link into a button and we’ll be ready to dive into the pseudo elements.

screenshot

Style the Link

Most of the text is easy to style, but for the link we’ll need a much larger chunk of code. This is because the original design calls for a link that’s styled to look like a button. To do this, we’ll need to add some padding, border-radius and shadows.

.hiretext a {
  border-radius: 5px;
  border: 1px solid #00adef;
  color: #fff;
  background: #01bcf3;
  padding: 8px 20px;

  font: 15px/3.4 Helvetica, Verdana, sans-serif;
  text-decoration: none;
  
  -webkit-box-shadow: inset 0px 0px 4px rgba(255, 255, 255, 0.5), 1px 1px 2px rgba(0,0,0,0.2);
  box-shadow: inset 0px 0px 4px rgba(255, 255, 255, 0.5), 1px 1px 2px rgba(0,0,0,0.2);
}

.hiretext a:hover {
  background: #2ecefd;
}

There’s a few important things to take note of here. First, I stripped the default link styling by removing the text-decoration and setting a new color. Also, I added the tiniest of borders around the button edge to help it stand out a bit. Finally, I’ve placed two shadows on this element. The first is an inset shadow that’s really more of an inner glow and the second is a more typical drop shadow.

Step 4 Progress Check

With that, we’ve got a nice little “Hire Me” card. technically, you could stop here, but I’m going to press on and create the little stacked card effect from the original design.

screenshot

Step 5. Stack the Deck

In Marc’s original design, we see that he’s created the illusion of a stack of cards rather than simply displaying a single card floating in space. There are a number of ways that we could accomplish this with code, but ultimately we should keep in mind that it would be better to not clutter up our HTML markup with empty divs, a pure CSS solution would be greatly preferable.

Given this information, we can turn to the “:before” and “:after” pseudo elements for the solution, which we explain in impressive depth in our post, The Lowdown on :Before and :After in CSS.

We’ll begin with the :after pseudo element. To implement it, target the “hireme” class and use the single colon syntax (IE doesn’t like the double colon syntax). Set the content to blank, the position to absolute, the border-radius to 10px (same as the original card) and nudge it to the left by 4px (the top value should be at 0). I finished this up by setting the z-index to -1 to be sure it appears below the original card.

/*Hire Me Extra Cards*/
.hireme:after {
  content: "";
  height: 100px;
  width: 250px;
  position: absolute;
  border-radius: 10px;
  top: 0px;
  left: 4px;
  z-index: -1;
}

Basically, what we’re aiming for here is to rebuild the original card. We want the same dimensions, the same shadows, the same gradient, etc. The one major difference is that we’ll add in a rotation to offset this card from the original.

/*Hire Me Extra Cards*/
.hireme:after {
  content: "";
  height: 100px;
  width: 250px;
  position: absolute;
  border-radius: 10px;
  top: 0px;
  left: 4px;
  z-index: -1;
  
  /*Shadow*/
  -webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  
  /*Rotate*/
  -webkit-transform: rotate(4deg) ;
  -moz-transform: rotate(4deg) ;
  -o-transform: rotate(4deg) ;
  
  /*Gradient*/
  background-image: linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -o-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -ms-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, rgb(217,217,217)), color-stop(0.7, rgb(245,245,245)));
}

Now we repeat the same process with the “:before” pseudo element so that we end up with a stack of three cards. This go around, the z-index is set to -2 and the rotation has been doubled.

.hireme:before {
  content: "";
  height: 100px;
  width: 250px;
  position: absolute;
  border-radius: 10px;
  top: 0px; left: 10px;
  z-index: -2;
  
  -webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  
  -webkit-transform: rotate(8deg) ;
  -moz-transform: rotate(8deg) ;
  -o-transform: rotate(8deg) ;
  
  background-image: linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -o-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -ms-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, rgb(217,217,217)), color-stop(0.7, rgb(245,245,245)));
}

Clean This Mess Up!

It’s very important to always question your code and examine how you can make it better. As I look over the styles for the three different cards, I see a ton of repetition. This is a direct violation of the DRY (Don’t Repeat Yourself) principle of coding, which helps your CSS stay clean and efficient.

The same exact height, width, border-radius, shadow and gradient values are repeated no less than three times in our code. This is completely pointless and sloppy. It’s ok to code like this as you’re “sketching” and playing around to get things right, but once you’re finished, you should always clean up.

We can accomplish this by taking all of those repeated values and grouping them into a single declaration block that targets all three selectors. After this, we can dramatically reduce the code needed for each individual card.

.hireme, .hireme:before, .hireme:after {
  height: 100px;
  width: 250px;
  background: #ccc;
  border-radius: 10px;
  -webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
  box-shadow: 3px 3px 5px rgba(0,0,0,0.5);

  background-image: linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -o-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -ms-linear-gradient(bottom, rgb(217,217,217) 40%, rgb(245,245,245) 70%);
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, rgb(217,217,217)), color-stop(0.7, rgb(245,245,245)));
}

/*Hire Me Card*/
.hireme {
  margin: 40px;
  position: relative;
}

/*Hire Me Extra Cards*/
.hireme:after {
  content: "";
  position: absolute;
  top: 0px;
  left: 4px;
  z-index: -1;
  
  /*Rotate*/
  -webkit-transform: rotate(4deg) ;
  -moz-transform: rotate(4deg) ;
  -o-transform: rotate(4deg) ;
}

.hireme:before {
  content: "";
  position: absolute;
  top: 0px;
  left: 10px;
  z-index: -2;
  
  -webkit-transform: rotate(8deg) ;
  -moz-transform: rotate(8deg) ;
  -o-transform: rotate(8deg) ;
}

Check Out the Demo

Good news, we’re all finished! We now have an awesome little “Hire Me” badge that can be easily dropped onto any web page. I’ve embedded the CodePen demo below so you should be able to have a look at both the code and the final result. If that isn’t working for you, check it out here.

[/code]

What Do You Think?

I hope you've enjoyed this little project as much as I have. We learned a good deal about everything from stacking objects with z-index to organizing our code with DRY concepts. Leave a comment below and let me know what you think.

If you have any suggestions for improvement or changes, be sure to fork my CodePen demo and leave a link to your version below.