Coding a Responsive Mini vCard Webpage

The use of online portfolios has become a popular choice by many digital artists. The goal would be showcasing yourself and your skills to anyone curious, maybe hiring companies or potential clients. Another simpler way to accomplish this task is to create your own digital vCard page. It’s usually a single page containing a brief resume, your work experience, and some interesting tidbits about yourself.

In this tutorial I want to demonstrate how to build a simple tabbed webpage layout in the style of a simplistic portfolio. We can incorporate jQuery fade effects to switch between the tabs, sticking to a formal responsive design. Take a peek at my live sample demo to see what the final product looks like.

The Ultimate Designer Toolkit: 2 Million+ Assets

Envato Elements gives you unlimited access to 2 million+ pro design resources, themes, templates, photos, graphics and more. Everything you'll ever need in your design resource toolkit.

Explore Envato Elements

Live DemoDownload Source Code

Setting the Layout

Aside from the single index file I’m also creating a separate stylesheet named styles.css. We also need a copy of the jQuery library, either local or hosted externally.

The page itself is held within a wrapper fixed at the maximum width of 700px. Within this wrapper I’m using a secondary container div which adds the white background and natural page body effects.

 
<div id="w">
    <div id="content">
      <nav id="topnav">
        <ul class="clearfix">
          <li><a href="#profile" class="sel">Profile</a></li>
          <li><a href="#resume">Resume</a></li>
          <li><a href="#portfolio">Portfolio</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </nav><!-- @end #topnav -->
      
      <h1>Johnny Appleseed</h1>

You’ll notice each navigation HREF value points towards the ID of a page element. This could be updated to link towards separate pages, then overridden using jQuery to keep the dynamic effects. If you don’t care much about indexing separate pages, Google is still able to crawl through all your content with ease.

  <section id="profile">
    <div id="portrait"><img src="img/portrait.png" alt="vcard photo portrait"></div>
    <h2>Web Designer & Developer</h2>
    
    <h3>Bio:</h3>
    <p>Ever since I was young I have enjoyed creating. By high school...</p>

The inner portions are split into section elements with each using a specific ID value. The example HTML above is from the default profile view which loads immediately on the page. I want to go over the jQuery first because it’s quick and simple to understand. There is a bit for the navigation along with another small section to handle the non-functioning contact form.

Dynamic jQuery Effects

Down towards the very bottom of the page you’ll notice a script block. There isn’t anything overly complex but it is worth an explanation. I’ve copied the entire section of code below:

$(function(){
  $('#topnav ul li a').on('click', function(e){
    e.preventDefault();
    var current = $('#topnav ul li a.sel');
    var newpg   = $(this).attr('href');
    var oldpg   = current.attr('href');
    
    current.removeClass('sel');
    
    $(oldpg).fadeOut(300, function(){
      $(newpg).fadeIn(180);
    });
    
    $(this).addClass('sel');
  });
  $('#contactform').submit(function(e){
    e.preventDefault();
  });
});

Whenever a user clicks onto any of the navigation links I’m using event.preventDefault() to stop the action. This is how you can include links to external pages for Google which aren’t accessible to most users.

I also define 3 variables which are useful throughout the function. current represents the currently selected page link, and the .sel class needs to be removed from that link when switching to new content. The other two variables newpg and oldpg represent the new page we are switching onto, and the older page which needs to be hidden out of view. This is accomplished using the fadeOut()/fadeIn() methods along with removeClass()/addClass().

At the very bottom I’m targeting #contactform as a selector. When anyone submits the contact form I want to stop the submission because there isn’t any code in place to send out an e-mail. If you plan to implement a real contact form, be sure to remove those 3 lines of code.

Inner Content Designs

Not everything in this vCard layout is exciting, but there are some cool CSS features. Specifically I’d like to explain the design characteristics for the skillbars along with the basic responsive portfolio items.

When searching on CodePen I found these cool animated bars which had a very polished design. I chose to leave out the animation and simplify the design even more. These skills are located on the second tab for “Resume”.

  <section id="resume" class="hideme">
    <h2>My Skills & Experience</h2>
    <div class="skillbar clearfix">
      <div class="skillbar-title"><span>HTML/CSS (8 yrs)</span></div>
      <div class="skillbar-bar htmlcss"></div>
    </div>
    
    <div class="skillbar clearfix">
      <div class="skillbar-title"><span>SEO (6 yrs)</span></div>
      <div class="skillbar-bar seo"></div>
    </div>
    
    <div class="skillbar clearfix">
      <div class="skillbar-title"><span>jQuery (2 yrs)</span></div>
      <div class="skillbar-bar jquery"></div>
    </div>

Each .skillbar is a unique item with a full-length background behind another lengthened bar. One inner span element contains text labeling the skill, along with total years of experience. Colors and width values are applied in CSS by targeting special classes for each skill.

.skillbar {
  position: relative;
  display: block;
  width: 100%;
  height: 25px;
  background: #eee;
  margin-bottom: 10px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}

.skillbar-title {
  position: absolute;
  top: 0;
  left: 0;
  font-weight: bold;
  font-size: 12px;
  color: #fff;
  -webkit-border-top-left-radius: 3px;
  -webkit-border-bottom-left-radius: 4px;
  -moz-border-radius-topleft: 3px;
  -moz-border-radius-bottomleft: 3px;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
}
.skillbar-title span {
  display: block;
  height: 25px;
  line-height: 25px;
  padding-left: 15px;
  -webkit-border-top-left-radius: 3px;
  -webkit-border-bottom-left-radius: 3px;
  -moz-border-radius-topleft: 3px;
  -moz-border-radius-bottomleft: 3px;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
}

.skillbar-bar {
  height: 25px;
  border-radius: 3px;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
}
.skillbar-bar.htmlcss {
  width: 100%;
  background: #6ebb8b;
}
.skillbar-bar.seo {
  width: 90%;
  background: #c95c7b;
}
.skillbar-bar.jquery {
  width: 40%;
  background: #2c3e50;
}
.skillbar-bar.phpmysql {
  width: 50%;
  background: #b387c3;
}
.skillbar-bar.photoshop {
  width: 85%;
  background: #7793d2;
}
.skillbar-bar.illustrator {
  width: 65%;
  background: #d2c077;
}

By keeping all the widths fluid everything will wrap naturally based on device resolution. This is another reason I’ve avoided animation on the skill bars – although I did write a very similar tutorial about that technique.

/** portfolio styles **/
#portfoliolist {
  display: block;
  width: 100%;
  margin-bottom: 10px;
}

#portfoliolist li {
  display: block;
  float: left;
  width: 45%;
  height: auto;
  text-align: center;
  margin-bottom: 20px;
}
#portfoliolist li.alt {
  float: right;
}

#portfoliolist li a {
  display: block;
  opacity: 1.0;
}
#portfoliolist li a:hover {
  opacity: 0.75;
}

#portfoliolist li a img {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

The portfolio layout is a bit simplistic, although it does work out great for this demo. The images are linked to Dribbble shots using dimensions of 800×600. The images will be resized based on the container’s total width. Each list item is 45% the width of the page, and the secondary images float right to create the illusion of a middle margin.

Responsive Updates

At the bottom of my CSS file there are some media queries for handling responsive devices. I’m working at breakpoints of 550px and 450px. Hitting the first break at 550, each portfolio item breaks into full-length instead of stacking like thumbnails.

@media screen and (max-width: 550px) {
  #portfoliolist li, #portfoliolist li.alt { float: none; width: 100%; } 
}

@media screen and (max-width: 450px) {
  h1 { font-size: 2.0em; }
  h2 { font-size: 1.7em; }
  
  #topnav ul { display: block;  width: 100%; }
  #topnav ul li { display: block; float: none; margin-bottom: 6px; }
  #topnav ul li a { display: block; width: 100% !important; }
  
  #portrait { width: 100px; }
  
  #contactform .basic { width: 70%; }
  #contactform #usrmsg { width: 90%; }
}

By 450px I need to handle the navigation items which begin to fall apart onto new lines. The nav links adapt to 100% width. Also the h1/h2 headers are resized to appear more natural on smartphone screens. The homepage portrait image is also resized, and the contact form inputs are shortened in length.

Some of these examples are minor cosmetic touch-ups, while the navigation is a necessary feature. If you add more page elements the number of responsive styles could go up – along with the possibility of writing new breakpoints.

Live DemoDownload Source Code

Closing

From this basic template you should be able to rewrite content or even code your own page sections. There are plenty of ways to restyle this web application to your liking. Feel free to download a copy of my source codes and build on top of this foundation to see what else is possible.