DesignM.ag » Tutorials http://designm.ag Articles and Resources for Web Designers Wed, 23 Apr 2014 04:09:32 +0000 en-US hourly 1 http://wordpress.org/?v=3.6 Coding a Toggle-Based FAQ Page with CSS3 and jQuery http://designm.ag/tutorials/question-answer-toggle-css3-jquery/ http://designm.ag/tutorials/question-answer-toggle-css3-jquery/#comments Wed, 23 Apr 2014 04:09:32 +0000 Jake Rocheleau http://designm.ag/?p=83886

Advertise here with BSA


Company websites often have Frequently Asked Questions for people who don't know much about the corporation or their services. Larger pages with Q&A listed together will often have a table of contents at the top. I don't like this method because the pages end up long and sometimes confusing to navigate.

This tutorial is based around a similar idea, but using toggle effects for each question. As the user clicks on a question the answer will slide down and toggle into view. Users can also click already-opened questions which toggles them closed again. This technique is perfect for saving room on the page while cramming together an assortment of helpful information.

css3 jquery faq toggle tutorial preview screen


Advertise here with BSA

]]>

Advertise here with BSA


Company websites often have Frequently Asked Questions for people who don’t know much about the corporation or their services. Larger pages with Q&A listed together will often have a table of contents at the top. I don’t like this method because the pages end up long and sometimes confusing to navigate.

This tutorial is based around a similar idea, but using toggle effects for each question. As the user clicks on a question the answer will slide down and toggle into view. Users can also click already-opened questions which toggles them closed again. This technique is perfect for saving room on the page while cramming together an assortment of helpful information.

css3 jquery faq toggle tutorial preview screen

Getting Started

To create the page I’m setting an HTML5 doctype along with an external CSS stylesheet. Also I’ve linked to an external copy of jQuery for the scripting. Inside the page body itself I’ve created a small heading section centered within a wrapper.

You’ll notice that each of the question/answer boxes are split into two columns. When we have them floating next to each other the expandable height values tend to push questions onto new rows. This looks awful and the quickest solution is to break them up into left and right columns.

<div id="questions" class="clearfix">
  <div class="qaleft">
    <div class="toggle">
      <h3>Is this a typical question from customers?</h3>
      <div class="toggle-info">
        <p>Yes! No strings attached.</p>
      </div>
    </div>
  </div> <!-- @end .qaleft -->

  <div class="qaright">
    <div class="toggle">
      <h3>Lorem ipsum dolor sit amet?</h3>
      <div class="toggle-info">
        <p>Cras id ullamcorper nunc. Morbi tempor risus venenatis risus pretium, ac mattis metus aliquet. Donec vestibulum congue ligula, eu malesuada nisi ultricies eget.</p>
        
        <p>Morbi at suscipit neque, porttitor feugiat mauris. Etiam auctor libero dolor, nec consequat felis convallis in.</p>
      </div>
    </div>

This code doesn’t include every question box, it simply demonstrates how to setup each of the columns. Everything in the left side will appear in a vertical row so it’s best to stagger questions from left to right making horizontal rows. Also you might consider breaking up questions into larger sections with sub-headings, divided by a horizontal rule or anther similar element.

Each of the containers .qaleft and .qaright are floated using a fixed width. The container uses a 100% width spanning the entirety of the page. So each internal .toggle element has the same formatted code. First we see an H3 which appears to the user as a clickable link.

Then as a sibling element I’ve created another div with the class .toggle-info. This allows us to branch out beyond simple paragraphs to answer a question. You might embed a video, image thumbnail, external links, or anything else convenient to visitors.

Page Styles

Most of my CSS resets are based on the source by Eric Meyer with a number of customizations. For this tutorial I’m using the Google Webfont Hammersmith One along with a custom tiled background.

/** page structure **/
#w {
  display: block;
  width: 800px;
  margin: 0 auto;
  padding: 15px;
  background: #fff;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
  -webkit-box-shadow: 1px 3px 2px rgba(0,0,0,0.3);
  -moz-box-shadow: 1px 3px 2px rgba(0,0,0,0.3);
  box-shadow: 1px 2px 3px rgba(0,0,0,0.3);
}

#title { text-align: center; }

#headline {
  display: block;
  position: relative;
  width: 100%;
  height: 220px;
  background: url('../img/featured-headline-bg.jpg') no-repeat;
  background-size: 100%;
}

#headline h2 {
  display: block;
  position: absolute;
  right: 50%;
  bottom: 0;
  padding: 10px 5px;
  margin-bottom: 10px;
  font-size: 2.2em;
  font-weight: bold;
  color: #616161;
  background: rgba(255,255,255,0.6);
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}

#questions {
  display: block;
  width: 100%;
}

I’ve created a centered page container with the #w wrapper ID. Also the larger headline container uses a background image fitted with background-size: 100%. The internal H2 element is fitted perfectly into the container with a white background using adjusted opacity. Large background headers are great for companies to showcase their office photo(s) so that visitors can build a deeper connection online.

/** toggle boxes **/
.qaleft {
  display: block;
  float: left;
  width: 370px;
}

.qaright {
  display: block;
  float: right;
  width: 370px;
}

.toggle {
  display: block;
  width: 100%;
  height: auto;
  margin-right: 10px;
  margin-bottom: 15px;
  -webkit-transition: all .15s ease-out;
  -moz-transition: all .15s ease-out;
  -o-transition: all .15s ease-out;
  transition: all .15s ease-out;
}

.toggle h3 {
  color: #576c7d;
  background: #e5eaee;
  display: block;
  font-size: 1.4em;
  line-height: 22px;
  text-align: center;
  padding: 10px 0;
  position: relative;
  cursor: pointer;
  font-weight: bold;
  text-shadow: 1px 1px 0 #fff;
  -moz-border-radius: 6px;
  -webkit-border-radius: 6px;
  border-radius: 6px;
  -webkit-transition: all .15s ease-out;
  -moz-transition: all .15s ease-out;
  -o-transition: all .15s ease-out;
  transition: all .15s ease-out;
}

All of the toggle containers should be self-explanatory. The H3 element for each toggle is made to appear like a hyperlink without a needless HREF. Using a bit of CSS I’ve forced the cursor to always appear as the hand pointer, and I’ve attached CSS3 transitions onto each toggle header.

.toggle p:last-of-type {
  margin-bottom: 0;
}

.toggle h3:hover, .toggle.open h3 { 
  background: #d2dbe2;
}

.toggle.open h3 {
  color: #46525c;
}

.toggle .toggle-info {
  display: none;
  padding: 7px 11px;
}

The rest is very simple but adds some extra value to the page. Since each toggle box uses a margin at the bottom, it’s unnecessary for the last paragraph to push down an extra 15px margin. This can be fixed using the :last-of-type pseudo selector on every internal paragraph. The last paragraph in the toggle container has no margin so each box is spaced properly.

Also whenever a user clicks to display an answer, the toggle box gets an extra class of .open. The heading background is darkened along with the text color. It’s just a minor effect but when quickly skimming over the page you tend to notice which questions are opened vs. which are not.

Toggling with jQuery

If you’re new to JavaScript or jQuery development this should be new and unique stuff. Any intermediate-to-advanced developer is likely familiar with toggling animation. But it doesn’t hurt to go over the process again in the context of this article.

$(function(){
  $('.toggle h3').on('click', function(e){
    var answer = $(this).next('.toggle-info');
    
    if(!$(answer).is(":visible")) {
      $(this).parent().addClass('open');
    } else {
      $(this).parent().removeClass('open');
    }
    $(answer).slideToggle(300);
  });
});

The jQuery selector is targeting every H3 element contained inside a .toggle div. Whenever one of these headings gets clicked we call a new function. The internal variable answer will change based on which question was clicked. We can use next() to pinpoint the sibling element with a class of .toggle-info.

A brief if/else logic block is used to determine the .open class. If the related .toggle-info div is not visible then we know the user clicked to display it. So for this case we need to add the class .open onto the toggle container using addClass(). Otherwise the class is removed and the heading goes back to its default state.

Finally at the end of this function I’m using the jQuery method .slideToggle() to display the answer. The 300 parameter sets the number of milliseconds for the animation to take place. This is known as duration and may be adjusted to whatever you need. There is an optional secondary parameter named complete which can be used for a callback function once the animation is complete. It doesn’t provide much use for this tutorial but you can see how this works in the code sample below:

$(answer).slideToggle(300, function() {
  // callback function code
});

css3 jquery faq toggle tutorial preview screen

Closing

This is a really simple yet optimal effect for any large-scale website. Q&A sections can be used with startups, ecommerce shops, media companies, anything that might be somewhat ambiguous to the general public. Since most visitors understand toggle-based interfaces this design style is perfect for any modern layout. Feel free to download a copy of my source code and try building this into your own website.


Advertise here with BSA

]]>
http://designm.ag/tutorials/question-answer-toggle-css3-jquery/feed/ 0
How To Code a Forrst API Webapp using JSON and jQuery http://designm.ag/tutorials/forrst-api-webapp-using-json-jquery/ http://designm.ag/tutorials/forrst-api-webapp-using-json-jquery/#comments Wed, 05 Mar 2014 13:40:16 +0000 Jake Rocheleau http://designm.ag/?p=83105

Advertise here with BSA


Modern development APIs work like agents for sharing information to other 3rd party websites. I've written many past tutorials about API development to help anyone new to this process. There are so many web-based services that it's tough picking something to grab people's attention.

In this tutorial I want to demonstrate how we can access the Forrst API using jQuery. Some API wrappers actually require server-side code like PHP or Ruby. But it's often easier to work with JSON objects instead. Then we can parse all the return data using client-side JavaScript. Take a look at my sample demo to see the final product.

forrst api tutorial howto preview screenshot


Advertise here with BSA

]]>

Advertise here with BSA


Modern development APIs work like agents for sharing information to other 3rd party websites. I’ve written many past tutorials about API development to help anyone new to this process. There are so many web-based services that it’s tough picking something to grab people’s attention.

In this tutorial I want to demonstrate how we can access the Forrst API using jQuery. Some API wrappers actually require server-side code like PHP or Ruby. But it’s often easier to work with JSON objects instead. Then we can parse all the return data using client-side JavaScript. Take a look at my sample demo to see the final product.

forrst api tutorial howto preview screenshot

Building the Page

My initial HTML page is actually quite small. I’ve downloaded a local copy of jQuery along with creating an extra file named forrst-json.js. This could have been embedded into the page but since there is a lot of code, it’s simpler to move this into a separate document.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Forrst Posts API Webapp - DesignM.ag Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designm.ag/favicon.ico">
  <link rel="icon" href="http://designm.ag/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
  <script type="text/javascript" src="js/forrst-json.js"></script>
</head>

There are 2 important sections within the page body. First is the navigation menu which behaves like a set of dynamic links. Forrst actually has four categorical post types – questions, codes, snaps, and links. I’ve ignored links for the sake of this demo but you still have access to all of this information via the API request.

  <div id="w">
    <h1>Recent Forrst Posts via Ajax</h1>
    
    <nav id="menu">
      <ul class="clearfix">
        <li><a href="#questions">Questions</a></li>
        <li><a href="#snaps">Snaps</a></li>
        <li><a href="#code">Code</a></li>
      </ul>
    </nav><!-- @end #menu -->
    
    <div id="content"></div>
  </div><!-- @end #w -->

When clicking any of the menu links it will trigger a jQuery function accessing the API. We can determine which type of data is needed based on the HREF value. Forrst will return a response in JSON formatting, which is parsed and embedded into the #content div.

CSS Styles

There isn’t anything new or complicated in my stylesheet. But I’ll cover how the layout works and how I’ve chosen to display information via the JSON response.

/** page structure **/
#w {
  display: block;
  width: 760px;
  margin: 0 auto;
  background: #fff;
  padding: 5px 9px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.25);
  -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25);
  box-shadow: 0 1px 2px rgba(0,0,0,0.25); 
}

#menu {
  display: block;
  margin-bottom: 7px;
}
#menu ul { list-style: none; }
#menu ul li { display: block; float: left; margin-right: 10px; }
#menu ul li a {
  display: block;
  float: left;
  background: #3b7140;
  color: #b1c6b3;
  font-size: 1.4em;
  padding: 7px 15px;
  text-decoration: none;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
}
#menu ul li a:hover, #menu ul li a.sel {
  background: #538558;
  color: #fff;
}




#content { /* no styles */ }
#content .post {
  display: block;
  margin-bottom: 55px;
}

#content .meta {
  display: block;
  font-size: 1.2em;
  line-height: 1.0em;
  margin-bottom: 2px;
  color: #6c6856;
}

.post h1 { 
  font-size: 1.65em;
}
.post ul {
  list-style-type: disc; 
  list-style-position: inside;
  margin-left: 25px;
  margin-bottom: 15px;
}
.post ol {
  list-style-type: decimal; 
  list-style-position: inside; 
  margin-left: 25px;
  margin-bottom: 15px;
}
.post ul li, .post ol li {
  display: list-item;
  margin-bottom: 11px;
  font-size: 1.3em;
}

.post .thumbshot {
  margin-right: 15px;
  margin-bottom: 12px;
}

The primary body is contained inside of a wrapper div. This stays centered on the page and holds the navigation menu, along with the content div. Each new item listed from the API is contained inside a div using the class .post.

Forrst allows users to post content with a text editor to include list items, code snippets, images, links, and other HTML content. If you plan to display this on your website it might take some extra styling to get it all functional. I’ve gone ahead to rewrite some of my ul/ol list rules and created a new class .thumbshot for each image snap.

Handling the API Request

The meat of this tutorial is really found inside forrst-json.js. The file doesn’t hold JSON code itself – we pull out the JSON information based on which link is clicked by the user.

$(function(){
  var $page   = $('#content');
  var baseapi = 'https://forrst.com/api/v2/posts/list'
  
  $('#menu ul li a').on('click', function(e){
    e.preventDefault();
    var requrl = $(this).attr('href');
    var apilink;
    
    if($(this).hasClass('sel')) return;
    else {
      $('#menu ul li a').removeClass('sel');
      $(this).addClass('sel');
    }
    
    if(requrl == '#questions') {
      apilink = baseapi + '?post_type=question';
    }
    if(requrl == '#snaps') {
      apilink = baseapi + '?post_type=snap';
    }
    if(requrl == '#code') {
      apilink = baseapi + '?post_type=code';
    }

This first section creates a variable holding the base API URI for requesting any post type. Whenever the user clicks a menu link it calls a new JS function to access the link’s HREF value. Through a series of if() logic statements the base URI is expanded with a query string(ex: ?post_type=question).

  $.ajax({
    type: 'get',
    url: apilink,
    cache: false,
    dataType: 'jsonp',
    contentType: 'application/javascript;charset=utf-8',
    beforeSend: function(xhr) {
      $page.html('<center><img src="css/loader.gif" alt="loading..."></center>');
    },
    error: function(err) { 
      console.log(err); // check console for errors
    },

When making the Ajax request we need to use JSONP as the response type. Issues with cross-domain scripting will cause problems using the JSON response type. You can read more from this SO post. I’ve written a whole long block of code so I’ll break down the first section followed by the success callback.

Since we’re using JSONP it’s better to set the content-type to application/javascript. There are a number of callback methods which fire during the Ajax process. beforeSend() creates a function that embeds a loading .gif into the page content. If there are any errors they get logged into the JavaScript console for review.

      success: function(data) {
        var list = data.resp.posts;
        var html = '';
        
        $.each(list, function(i){
          var title    = list[i].title;
          var desc     = list[i].formatted_description;
          var bcontent = list[i].content;
          var content  = list[i].formatted_content.replace('href="\/', 'href="http://forrst.com\/');
          var posturl  = list[i].post_url;
          var views    = list[i].view_count;
          var likes    = list[i].like_count;
          
          html += '<div class="post">';
          
          html += '<h2>'+title+'</h2>';
          html += '<span class="meta"><strong>Views</strong>: '+views+' - <strong>Likes</strong>: '+likes+' - <strong><a href="'+posturl+'" target="_blank">Post link</a></strong></span>';
          html += '<p>'+desc+'</p>';
          
          if(requrl != '#code' && bcontent != 0) html += '<p>'+content+'</p>';
          
          if(requrl == '#snaps') {
            // if post has pictures then we pull URLs
            var snaplist = list[i].multiposts;
            
            $.each(snaplist, function(pic){
              if(snaplist[pic].type == 'image') {
                var thumbimg = snaplist[pic].snaps.large_square_url;
                var fullimg  = snaplist[pic].snaps.original_url;
                
                html += '<a href="'+fullimg+'" target="_blank"><img src="'+thumbimg+'" width="150" height="150" class="thumbshot"></a>';
              }
            });
          }
          
          html += '</div>';
        });
        
        $page.html(html); // render new HTML onto the page
      }
    });
  });
});

This final success callback will only run after we’ve pulled some type of response from the API. It returns the most recent posts under any category along with the user information and metadata. This gets passed into the function as a single parameter. So to actually get into the object we need to access data.resp.posts and other Forrst API requests may appear similar.

Using this lone object it’s quite simple to iterate through content using jQuery $.each(). Each of the variables is targeted using the i parameter, which behaves as a numerical increment on each loop. All of the variables should be easily recognizable except for bcontent and content. The content variable has been formatted so the forward slashes are re-written(fixing the href:// links).

In various code snippets the user will include HTML right into the page. In this category it’s easier to use the plain bcontent or bare content, which is not formatted. Using a variable named html along with the JavaScript += operator I’ve combined a long string of posts after each loop.

You might find it interesting that on snap links I’ve taken the liberty of writing another $.each() loop. This runs through all the images and checks for a certain thumbnail size. These pics also get displayed into the HTML whenever browsing recent snaps. At the end of the final loop all this HTML code gets embedded into the page using jQuery’s .html() method.

forrst api tutorial howto preview screenshot

Closing

My example doesn’t utilize much of the API data for code samples. This requires a bit of string manipulation to rework the various HTML tags into entities. But keep in mind that you can access full information from any question, link, snap, or code snippet. You can also pull out API data for users and other endpoints from the website. Forrst is quite the unique online community and their API is a fantastic resource for web developers.


Advertise here with BSA

]]>
http://designm.ag/tutorials/forrst-api-webapp-using-json-jquery/feed/ 0
How To Code a Hidden Author Bio Display using jQuery http://designm.ag/tutorials/hidden-author-bio-display-using-jquery/ http://designm.ag/tutorials/hidden-author-bio-display-using-jquery/#comments Thu, 06 Feb 2014 15:58:46 +0000 Jake Rocheleau http://designm.ag/?p=82679

Advertise here with BSA


I was browsing through websites one day and came across one really interesting feature. Jennifer Perrin has a small blog on her website which uses a fixed top navbar. In the center you'll find a profile avatar photo which displays her full author bio(triggered by hover). This is a really interesting feature and I've set out to replicate the idea using jQuery.

So in this tutorial I want to demonstrate how we can build a very simple HTML5 webpage recreating a full author bio display. The entire bio container is hidden until the user hovers over the avatar photo. Take a peek at my live demo to see what it should look like:

hidden author bio display hover tutorial screenshot


Advertise here with BSA

]]>

Advertise here with BSA


I was browsing through websites one day and came across one really interesting feature. Jennifer Perrin has a small blog on her website which uses a fixed top navbar. In the center you’ll find a profile avatar photo which displays her full author bio(triggered by hover). This is a really interesting feature and I’ve set out to replicate the idea using jQuery.

So in this tutorial I want to demonstrate how we can build a very simple HTML5 webpage recreating a full author bio display. The entire bio container is hidden until the user hovers over the avatar photo. Take a peek at my live demo to see what it should look like:

hidden author bio display hover tutorial screenshot

Page Setup

First I know the effect will be created using jQuery so I’ll be downloading a local copy for this project. It’s all pretty simple except for the hovering triggers based on event delegation. But we can get into that later in the article.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Hidden Author Bio Display Demo - DesignM.ag</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designm.ag/favicon.ico">
  <link rel="icon" href="http://designm.ag/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
</head>

I’ve also created a new stylesheet named styles.css. This has all my typical page resets along with a number of extra styles to position the bio and top navbar. To keep things simpler I didn’t use a whole lot of extra text or links within this toolbar. But for your own website it’s entirely possible to move things around as necessary.

  <header id="topbar">
    <div id="logo"><h1>MySite Logo</h1></div>
    
    <div id="avatar-icon">
      <img src="img/avatar.jpg" alt="Author avatar photo" class="authoravi">
      <div id="author-bio-box">
        <img src="img/avatar.jpg" alt="author big photo" class="bigavi">
        <h2>Jake Rocheleau</h2>
        <p>Jake is a writer and designer found all over the Internet. He specializes in UI design, frontend development, branding, and content strategy.</p>
      </div>
    </div>
  </header>

This is really the most important HTML on the webpage. Directly after the opening body tag I’ve setup a new header element as the base container. The logo and the avatar have their own separate divs positioned within this container. Whenever a user hovers on top of the #avatar-icon image, we display the internal #author-bio-box.

CSS Design

You should take a look over my basic styles and CSS resets if you’re unfamiliar with page structure. At the top I’m referencing an external web font named Montserrat Alternates. Beneath the top navigation bar I’ve setup a wrapper div which contains filler Lorem Ipsum text. You can see how the bio display works even when scrolling down through a webpage.

#avatar-icon {
  position: relative;
  width: 100px;
  margin: 0 auto;
  text-align: center;
  padding-top: 6px;
  cursor: pointer;
}

#avatar-icon .authoravi {
  width: 55px;
  height: 55px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

/* header top bar */
#topbar {
  display: block;
  position: fixed;
  top: 0;
  width: 100%;
  min-width: 750px;
  height: 70px;
  padding: 0 45px;
  z-index: 9999;
  background-color: #6e7cc9;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#6e7cc9), to(#6a74af));
  background-image: -webkit-linear-gradient(top, #6e7cc9, #6a74af);
  background-image: -moz-linear-gradient(top, #6e7cc9, #6a74af);
  background-image: -ms-linear-gradient(top, #6e7cc9, #6a74af);
  background-image: -o-linear-gradient(top, #6e7cc9, #6a74af);
  background-image: linear-gradient(top, #6e7cc9, #6a74af);
  border-bottom: 1px solid #53597c;
}

To keep this avatar centered in position I’m using margin: 0 auto on the fixed-width container. We also need a relative positioning so the interior author box can use absolute positioning. #avatar-icon becomes the new container for this absolute position, as opposed to the entire body element.

Using a fixed position on the #topbar header is key for the navigation to follow along with the user. I’m using large padding on the HTML body so everything on the page gets pushed down beneath this fixed bar. Using the CSS property top: 0 will force this bar to stay fixed at the top of the page, while the other content appears below.

/** bio box **/
#author-bio-box {
  display: none;
  position: absolute;
  cursor: default;
  width: 300px;
  top: 0;
  left: -100px;
  padding: 5px 15px 8px 15px;
  background: rgba(20,20,20,0.9);
  z-index: 99999;
  -webkit-border-radius: 0 0 7px 7px;
  -moz-border-radius: 0 0 7px 7px;
  border-radius: 0 0 7px 7px;
  -webkit-box-shadow: 1px 1px 4px rgba(0,0,0,0.6), -1px -1px 3px rgba(0,0,0,0.5) inset;
  -moz-box-shadow: 1px 1px 4px rgba(0,0,0,0.6), -1px -1px 3px rgba(0,0,0,0.5) inset;
  box-shadow: 1px 1px 4px rgba(0,0,0,0.6), -1px -1px 3px rgba(0,0,0,0.5) inset;
}

#author-bio-box .bigavi {
  width: 95px;
  height: 95px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

#author-bio-box h2 {
  display: block;
  font-family: 'Trebuchet MS', Helvetica, Arial, sans-serif;
  font-size: 2.5em;
  line-height: 1.5em;
  text-align: center;
  color: #fff;
  cursor: text;
  font-variant: small-caps;
  letter-spacing: -0.03em;
}
#author-bio-box p {
  display: block;
  font-size: 1.5em;
  line-height: 1.35em;
  color: #fff;
  cursor: text;
}

Finally we get to the hidden author box and other internal elements. The #topbar div uses a z-index of 9,999 so that it appears on top of all other page content. Since we need this author bio to appear on top of the bar I’m using 99,999 z-index to setup the correct layout.

Width is fixed at 300px but since this bio is offset in the center, it won’t appear correct. We can’t use absolute positioning because the content itself will appear outside the boundary box. It’s smarter to use a negative left margin to reposition the author bio exactly where it should appear. Note this value should also be changed as you update the bio box width, so keep this in mind when adjusting for your own project(s).

jQuery Display Effects

Possibly the most confusing piece of my jQuery code is event delegation with the .on() method. By using the body element as my selector it works like an updated event handler to also bind events onto hidden or dynamically-appended elements. Check out this Stack Overflow post to get a better understanding.

$(function(){
  $('body').on('mouseenter', '#avatar-icon', function(e){ 
    $('#author-bio-box').css('display','block');
  });

  $('body').on('mouseleave', '#author-bio-box', function(e){
    $(this).css('display','none');
  });
});

Also worth noting are the mousenter and mouseleave event triggers. mouse over/out will trigger if the user re-hovers something other than the target element. So if we open the author bio and the user hovers the new avatar image or the bio paragraph, it would see we are hovering something new and close the whole box. Mouseleave will only trigger when leaving the entire container – much safer and provides exactly the effect we need.

So once the user hovers onto #avatar-icon we immediately display the author bio box. And once the mouse leaves those boundaries this box gets re-hidden from view. Truly a simple yet powerful script if you know how to use it.

hidden author bio display hover tutorial screenshot

Final Thoughts

I can admit that this solution probably wouldn’t work best on all websites. But if you’re designing a small author-based blog why not try it out? It is a really interesting concept which is perfect for any fixed-width title bar. Feel free to download a copy of my source code and let us know what you think in the post discussion area.


Advertise here with BSA

]]>
http://designm.ag/tutorials/hidden-author-bio-display-using-jquery/feed/ 0
How To Design Custom Pricing Plan Tables with HTML5 and CSS3 http://designm.ag/tutorials/custom-pricing-plan-tables-html5-css3/ http://designm.ag/tutorials/custom-pricing-plan-tables-html5-css3/#comments Tue, 21 Jan 2014 16:53:25 +0000 Jake Rocheleau http://designm.ag/?p=82331

Advertise here with BSA


Any company selling a service with payment plans usually breaks up the structure into different packages. Smaller packages will cost less but also provide fewer features. Pricing tables are the perfect UI component to display these packages in an easy-to-compare design.

For this tutorial I want to demonstrate how we can create pricing tables with just a bit of HTML5 and CSS3. Despite the name, I haven't actually used any <table> elements within the design. You might feel these are easier but they also depend on a rigid formulaic structure. Pricing tables can have many facets including service terms, plan details, pricing details, and of course the purchase/signup button.

custom designed html5 css3 pricing tables tutorial open source

Live Demo - Download Source Code


Advertise here with BSA

]]>

Advertise here with BSA


Any company selling a service with payment plans usually breaks up the structure into different packages. Smaller packages will cost less but also provide fewer features. Pricing tables are the perfect UI component to display these packages in an easy-to-compare design.

For this tutorial I want to demonstrate how we can create pricing tables with just a bit of HTML5 and CSS3. Despite the name, I haven’t actually used any <table> elements within the design. You might feel these are easier but they also depend on a rigid formulaic structure. Pricing tables can have many facets including service terms, plan details, pricing details, and of course the purchase/signup button.

custom designed html5 css3 pricing tables tutorial open source

Getting Started

This demonstration is mostly built around aesthetics so I haven’t even bothered touching the jQuery library. The document header references a single stylesheet named styles.css which imports an external web font Alegreya Sans.

Looking towards the internal table itself you will see it’s built using a container div, along with internal block elements like <header> and <section>. This makes everything easier to read when skimming through the code. And we can separate block sections from each table to distinguish between background colors and font styles.

<div id="pricing" class="clearfix">
  <div class="price-table">
    <header>
      <h3>Basic</h3>
    </header>
    <section class="price-details">
      <p>$19<span class="price-recur">per month</span></p>
    </section>
    <section class="details">
      <ul class="details-list">
        <li class="wizard">Easy Setup Wizard</li>
        <li class="storage">250GB Storage</li>
        <li class="scripts">Open Source Scripts</li>
        <li class="support">24/7 Tech Support</li>
      </ul>
    </section>
    <section class="purchase-btn"><a href="javascript:void(0);">Purchase</a></section>
  </div><!-- @end "Basic" .price-table -->

To save room I’ve only copied the very first pricing table HTML for the “Basic” plan. The header section uses a background gradient plus a small text shadow to stand apart from the page. Pricing details are split using a span element with the class .price-recur. So the numeric cost will appear much larger than the denoted timeframe(per month).

You’ll also notice the .details-list contains list items with different classes. These each represent a different background icon from the Gentle Edges icon set. The PNGs are white by default which is perfect for this dark tabular color scheme.

The outer container #pricing uses a clearfix class to keep everything aligned properly. The tables are floated next to each other using fixed width values. These could be redefined to use flexible widths based on the container, if your layout is responsive. Basically you can adjust these numbers in CSS to get them aligned any way you’d like.

Typical CSS Styles

Each of the table designs follows the same class structure. Higher-priced tables have more listed icon features, and so they appear longer on the page.

/* page structure */
#w {
  display: block;
  width: 800px;
  margin: 0 auto;
  padding: 15px 10px;
  background: #fff;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
  -webkit-box-shadow: 1px 2px 4px rgba(0,0,0,0.55);
  -moz-box-shadow: 1px 2px 4px rgba(0,0,0,0.55);
  box-shadow: 1px 2px 4px rgba(0,0,0,0.55);
}


#pricing {
  display: block;
  margin-bottom: 20px;
}

.price-table {
  display: block;
  float: left;
  width: 185px;
  text-align: center;
  color: #fff;
  background: #6f8590;
  margin-right: 10px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

Each inner table is fixed at 185px width. This comes out to 740px along with an extra 10px margin. The total body wrapper is 800px so these tables come in at just about the perfect width value. Also the table itself has rounded corners which are then translated to other elements such as the header.

.price-table header {
  display: block;
  padding: 15px 0;
  border-bottom: 1px solid #54656d;
  -webkit-border-top-right-radius: 5px;
  -webkit-border-top-left-radius: 5px;
  -moz-border-radius-topright: 5px;
  -moz-border-radius-topleft: 5px;
  border-top-right-radius: 5px;
  border-top-left-radius: 5px;
  background-color: #5f8597;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#324a56), to(#5f8597));
  background-image: -webkit-linear-gradient(top, #324a56, #5f8597);
  background-image: -moz-linear-gradient(top, #324a56, #5f8597);
  background-image: -ms-linear-gradient(top, #324a56, #5f8597);
  background-image: -o-linear-gradient(top, #324a56, #5f8597);
  background-image: linear-gradient(top, #324a56, #5f8597);
}
.price-table header h3 {
  font-size: 2.7em;
  font-weight: bold;
  text-shadow: 1px 2px 0 rgba(0,0,0,0.3);
}

.price-table .price-details {
  padding: 20px 0;
  background: #cedee6;
  font-size: 4.46em;
  line-height: 1.1em;
  font-weight: bold;
  color: #4b5d72;
  margin-bottom: 15px;
  text-shadow: 1px 2px 0 rgba(255,255,255,0.6);
}
.price-table .price-details .price-recur {
  display: block;
  font-size: 0.4em;
  line-height: 0.9em;
  font-weight: normal;
}

.price-table .details-list {
  list-style: none;
  text-align: left;
  margin-bottom: 10px;
}
.price-table .details-list li {
  display: block;
  padding: 8px 0;
  padding-left: 40px;
  font-size: 1.2em;
  line-height: 20px;
  font-weight: bold;
  background-position: 6px 5px;
  background-repeat: no-repeat;
  border-bottom: 1px solid #a7b7bf;
}

You’ll notice the header uses a CSS3 background gradient with browser prefixes to create the glossy effect. As we move down to .price-details the background turns into a stationary color, and the pricing table itself uses a darker gray for the original background. Each of these sections will appear divided and still come together forming a recognizable pricing table.

On each of the .details-list li elements we need to keep the same background properties, but swap out different images. I figured the simplest way to do this would be including the same background-position and background-repeat values for each list item. Then for individual classes we switch between the icon URL itself.

The Recommended Table

You may have already noticed that the “Pro” table has a lighter purple hue in comparison to the darker teal. Many pricing tables will encapsulate one of the plans to appear more noticeable than the others. Companies offer these plans as the best deal for your money, and hope to persuade visitors into choosing that plan for its greater value.

The recommended table’s header is much shorter in height because I’ve included a small notice to catch people’s attention. You could get fancy using ribbons or badges, however I wanted to avoid extraneous images for this design. The table itself has an additional class so we can target internal elements using .price-table.recommended as the selector.

.price-table.recommended {
  background: #6c7b9b;
}

.price-table.recommended header {
  padding: 5px 0;
  background-color: #5a76b1;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#495e8a), to(#5a76b1));
  background-image: -webkit-linear-gradient(top, #495e8a, #5a76b1);
  background-image: -moz-linear-gradient(top, #495e8a, #5a76b1);
  background-image: -ms-linear-gradient(top, #495e8a, #5a76b1);
  background-image: -o-linear-gradient(top, #495e8a, #5a76b1);
  background-image: linear-gradient(top, #495e8a, #5a76b1);
  border-bottom: 1px solid #3b577e;
}
.price-table.recommended .notice {
 font-size: 1.2em;
 line-height: 20px;
 background: #3b577e;
 font-weight: bold;
}

.price-table.recommended .price-details {
  background: #bac7ea;
  padding: 20px 0;
}

To compensate for the loss of space I’ve reduced the header padding from 30px down to 10px. This is also why the small .notice text uses a line-height of 20px. I wanted the last two tables to stay perfectly aligned, even though they do feature slightly different content. Mostly all of the background colors have been updated along with the purchase button.

.price-table.recommended .purchase-btn a {
  border-color: #6a3fc2 #7045bf #651fbb;
  background: #6149ad;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a67d8), to(#6149ad));
  background-image: -webkit-linear-gradient(top, #7a67d8, #6149ad);
  background-image: -moz-linear-gradient(top, #7a67d8, #6149ad);
  background-image: -ms-linear-gradient(top, #7a67d8, #6149ad);
  background-image: -o-linear-gradient(top, #7a67d8, #6149ad);
  background-image: linear-gradient(to bottom, #7a67d8, #6149ad);
}
.price-table.recommended .purchase-btn a:hover {
  background: #634fc2;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#8876e2), to(#634fc2));
  background-image: -webkit-linear-gradient(top, #8876e2, #634fc2);
  background-image: -moz-linear-gradient(top, #8876e2, #634fc2);
  background-image: -ms-linear-gradient(top, #8876e2, #634fc2);
  background-image: -o-linear-gradient(top, #8876e2, #634fc2);
  background-image: linear-gradient(to bottom, #8876e2, #634fc2);
}
.price-table.recommended .purchase-btn a:active {
  background: #503d88;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#6d58bd), to(#503d88));
  background-image: -webkit-linear-gradient(top, #6d58bd, #503d88);
  background-image: -moz-linear-gradient(top, #6d58bd, #503d88);
  background-image: -ms-linear-gradient(top, #6d58bd, #503d88);
  background-image: -o-linear-gradient(top, #6d58bd, #503d88);
  background-image: linear-gradient(to bottom, #6d58bd, #503d88);
}

custom designed html5 css3 pricing tables tutorial open source

Closing

You won’t find a need for pricing plan tables in every project. Actually you probably won’t need them for a majority of web projects. But there are many companies which offer a recurring service, like TypeKit or MaxCDN. These are the designs which can truly incorporate pricing tables with a sense of purpose. Feel free to use my source code in your own website layouts, and to share any questions or ideas you may have in the post discussion area below.


Advertise here with BSA

]]>
http://designm.ag/tutorials/custom-pricing-plan-tables-html5-css3/feed/ 0