DesignM.agWeb Design Tutorials for Developers http://designm.ag Articles and Resources for Web Designers Tue, 02 Sep 2014 14:29:27 +0000 en-US hourly 1 http://wordpress.org/?v=3.9.2 How To Design Hover Effects for UI Elements in Photoshop http://designm.ag/tutorials/hover-effects-for-ui-elements-in-photoshop/ http://designm.ag/tutorials/hover-effects-for-ui-elements-in-photoshop/#comments Mon, 25 Aug 2014 13:16:57 +0000 http://designm.ag/?p=84904

Advertise here with BSA


Designing in Adobe Photoshop is a different experience compared to building websites right in the browser. It requires an understanding of the various tools, effects, and positioning techniques. One major difference is how you would create interactions such as hover and click events.

In this tutorial I want to demonstrate how you might go about designing interactive states with Photoshop Layer Comps. These behave like document states where you can rearrange elements and save a snapshot of each particular style. I've also released my PSD file for free which you can download and modify for your own needs.

photoshop layer comps button nav menu screenshot


Advertise here with BSA

]]>

Advertise here with BSA


Designing in Adobe Photoshop is a different experience compared to building websites right in the browser. It requires an understanding of the various tools, effects, and positioning techniques. One major difference is how you would create interactions such as hover and click events.

In this tutorial I want to demonstrate how you might go about designing interactive states with Photoshop Layer Comps. These behave like document states where you can rearrange elements and save a snapshot of each particular style. I’ve also released my PSD file for free which you can download and modify for your own needs.

photoshop layer comps button nav menu screenshot

Getting Started

I’m creating a new document 1000px wide by 550px high. The dimensions don’t really matter but this should give plenty of space for the elements. I’ll be creating 1 button along with a horizontal nav menu with a dropdown sub-menu.

create new document adobe photoshop

If you press CTRL/CMD+R this brings up the document rulers. I’ve dragged one vertical and one horizontal ruler to align directly with the center of the document. This isn’t necessary but it helps to see where each item relates to the overall document size.

The first layer is filled with white to create a background instead of transparency. Next I’ll create a new layer and choose the Rounded Rectangle tool. This will make our button which can be duplicated later for the other button states.

Creating the Button Design

In Photoshop CS5 or earlier the interface looks slightly different, but all of the same button styles work between versions. I’m using CS6 which groups together the vector mask and button color into one shape layer. They layer icon looks very different but these are the exact same thing and will work perfectly between different versions of Photoshop.

create new rounded rectangle diaglog window

Click to drag out your rectangle or click once to bring up the shape dialog box for a more precise design. I’ve made the button 200px by 50px with a fill color of #93c34d. To change this color after making the rectangle just double-click on the shape layer.

rounded rectangle shape tool color design

Once positioning the button you might want to hide any grids & guides which are active. Then with the shape layer selected move to the bottom of the layers panel and click the “fx” button for layer effects.

Add these settings to your shape:

button inner shadow photoshop effect

button gradient overlay photoshop effect

button stroke effect photoshop ui

The gradient overlay & inner shadow use white so the button color can be easily changed by updating the shape’s fill. However the stroke color would still need to be edited manually to match a new color scheme.

For the text I’m using Helvetica Neue with the color #526733. To get the button text aligned just hit CTRL/CMD+A to select the entire document, then CTRL/CMD+click on both the shape and text layers. In the option bar you’ll notice alignment buttons for aligning to vertical & horizontal centers. Click both and then reposition the button using rulers/grids as needed.

Also I’ve created a new group named “Green Button” which contains the text and shape layer.

Button States

Next we should duplicate this button group to create a new group called “Green Button Hover”. Double-click on this new shape and change the fill color to #a8cd71. I’m also lightening the new text layer’s color to #637943.

button group duplicate photoshop screen dialog

This next green button will have a fill of #8baf57 along with a darker stroke of #70863f. The Inner Shadow has also been changed to remove the 1px glossy border and replace it with a darker shadow for the “sunken in” look. Just copy my settings below:

button effect active state inner shadow

I’ll hide this active group so the original button is displayed. With both of these states complete we just need to create the navigation menu before moving onto layer comps.

Horizontal Nav Menu

I’m creating a new group called “Nav Bar” and drawing a regular Rectangle(not rounded) at 800px wide by 50px high. The fill color is #003663 and I’ve positioned this close to the top of the document.

create navigation bar menu photoshop rectangle tool ui

I’ll create five new text layers with Helvetica to add links onto the menu. Press CTRL/CMD+’(apostrophe) to display grids for an easier text alignment. The links can say anything you like but try to use the following text settings:

text settings photoshop menu navbar items

So the nav bar itself is created and the links seem fine. Now we need another group inside the “Nav Bar” group called “Dropdown”. Be sure to drag this group above the text & rectangle layer, but still kept inside the parent group. Then create a selection around one of the links – in my example “portfolio” – and fill a new layer with white.

I’ll duplicate the original portfolio link and move this into the “Dropdown” group, then change the text color to #103350. Now we can hide the dropdown group to get the original menu or re-display it and still get the hover effect. Underneath this link item drag out another rectangle shape layer at 180px wide by 200px high.

rectangle nav menu selected dropdown

This will contain the actual dropdown sub-menu links that appear when hovering. While still selecting this sub-menu rectangle apply the following Drop Shadow settings with a layer effect:

drop shadow fx layer effect screenshot sub menu

Using your grid type some menu text into the sub-nav rectangle. There is no perfect method of spacing so use your best judgement based on text size and how much space should appear between links. I’m using the same font styles from the menu except with a color of #697276.

Now toggle the “Dropdown” group closed and create another group inside “Nav Bar”. This will be called “Dropdown Hover” and only needs 2 layers. I’ll duplicate the very first sub-menu item in the list and move this duplicate into the “Hover Dropdown” group. Then I’ll draw a rectangle behind this text and fill with #253b4d.

photoshop nav menu dropdown layers organized groups

How these layers are ordered on top of each other will be essential to get the design working properly. Each hover effect should be stacked on top of the lower element so that layers can be easily turned on & off without any editing.

Creating Layer Comps

If your layers and groups are structured properly we can now create the final layer comps. These are most important to developers who may not know how to use Photoshop and would prefer direct access to each individual state of the user interface.

layer comps window open photoshop

In the Photoshop menu select Window -> Layer Comps and you’ll see one comp with the italicized text “Last Document State”. This will usually be selected as you make changes and toy around with the document. To create a new Layer Comp just click on the notepad icon at the bottom of this window pane. If you hover your mouse for a few seconds it should say “Create New Layer Comp”. But before creating the comps we need to hide/show the proper layers first.

I’ll start by hiding everything except the nav bar and the original button groups. This is how the page would look without any user interaction. Create a new layer comp with the name “Default”.

create new layer comp photoshop dialog

Then hide the original button and display the hover button group. This comp should be named “Button Hover”. Hide the hover group and then show the active button with a comp named “Button Clicked” or “Button Active”. Once this is done hide the active button to re-display our original button design. Now we just need 2 more comps for the navigation menu.

With the Nav Bar group open re-display the “Dropdown” group. This will show what it looks like when a user hovers onto the nav menu without hovering the sub-nav menu. Create a new comp named “Dropdown Menu”. Then show the sub menu hover group and create the final comp named “Dropdown Menu Hover”.

final layer comps screenshot photoshop

Now anyone can open this document and quickly switch between states without needing to manually show/hide individual layers or layer groups. This is a fantastic technique for web designers who often need to create various UI states for the same page elements.

Be sure to grab a copy of the free PSD file!


Advertise here with BSA

]]>
http://designm.ag/tutorials/hover-effects-for-ui-elements-in-photoshop/feed/ 0
Building a Mega-Navigation Menu with CSS3 and jQuery http://designm.ag/tutorials/meganav-menu-with-css3-jquery/ http://designm.ag/tutorials/meganav-menu-with-css3-jquery/#comments Mon, 05 May 2014 15:22:50 +0000 http://designm.ag/?p=84368

Advertise here with BSA


Larger navigation menus will typically include separate dropdown lists to appear on hover. But for some websites it can be necessary to expand this dropdown across the entire page. Designers might call this a "mega navigation" for its influence over the whole menu.

In this tutorial I want to demonstrate a method of creating one unified mega navigation menu. There are many different techniques you can use to achieve a similar effect. I'll be using jQuery to embed sub-navigation content into a dropdown mega nav box. Take a look at my live demo to see the final design.

mega navigation menu howto tutorial preview jquery


Advertise here with BSA

]]>

Advertise here with BSA


Larger navigation menus will typically include separate dropdown lists to appear on hover. But for some websites it can be necessary to expand this dropdown across the entire page. Designers might call this a “mega navigation” for its influence over the whole menu.

In this tutorial I want to demonstrate a method of creating one unified mega navigation menu. There are many different techniques you can use to achieve a similar effect. I’ll be using jQuery to embed sub-navigation content into a dropdown mega nav box. Take a look at my live demo to see the final design.

mega navigation menu howto tutorial preview jquery

Getting Started

The first step is to download a copy of jQuery to include in the main document. I’ve created a simple stylesheet which we can get into after the HTML. The page layout itself is wrapped in the center with a small header section.

After this header it’s fairly obvious that the navigation menu is large and takes up space. The container nav element uses an ID of #menu which spans the entire width of the page. But the content is centered using the .wrap class. Within this wrapper is another ID #navbar which is applied to an unordered list of links.

<nav id="menu">
  <div class="wrap">
    <ul id="navbar" class="clearfix">
      <li class="first"><a href="#">Home</a></li>
      <li><a href="#">Products<span class="arrow"></span></a>
        <div class="megacontent">
          <div class="col">
            <h3>Tech</h3>
            <ul class="navlist">
              <li><a href="#">PC Cases</a></li>
              <li><a href="#">Hard Drives</a></li>
              <li><a href="#">Memory</a></li>
              <li><a href="#">Sound Cards</a></li>
              <li><a href="#">Graphic Cards</a></li>
              <li><a href="#">Wireless Mice</a></li>
              <li><a href="#">Wireless Keyboards</a></li>
            </ul>
          </div>
          ...

Each list item contains one primary navigation element. Secondary elements are considered mega nav structures wrapped in a div tag. We could include a long list of links, or we could embed a video.Any type of content may be added into the mega navigation regardless of the unordered list structure.

It’s all contained within a class .megacontent and never gets displayed until it’s loaded into the dropdown menu. This is located much lower down beneath the entire navigation. You’ll find an empty div with the ID #megamenu and this will be the container for each submenu’s dropdown.

CSS Styles

I’ve used a separate stylesheet named styles.css which includes a few resets and some layout positioning. You’ll also notice I’ve included a separate Google Web Font called Nova Square. Most of this code is rudimentary design including the background-size effect for the photo heading.

/** page structure **/
.wrap {
  display: block;
  width: 850px;
  margin: 0 auto;
}

#top {
  display: block;
  width: 100%;
  height: 60px;
  background: #fff;
}

#fullimg {
  display: block;
  height: 350px;
  background: url('../img/leader-sm.jpg') no-repeat;
  background-size: contain;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  -webkit-box-shadow: 2px 2px 1px rgba(0,0,0,0.3);
  -moz-box-shadow: 2px 2px 1px rgba(0,0,0,0.3);
  box-shadow: 2px 2px 1px rgba(0,0,0,0.3);
}

#page {
  display: block;
  padding: 20px 0;
}

A bit further down is the mega navigation structure. Since #menu spans the entire page width it will be filled using a CSS3 gradient. This way the content is aligned to the center but we still get this design effect regardless of browser size.

/** navigation **/
#menu {
  display: block;
  position: relative;
  width: 100%;
  height: 55px;
  margin-bottom: 15px;
  background-color: #383838;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#383838), to(#282828));
  background-image: -webkit-linear-gradient(top, #383838, #282828);
  background-image: -moz-linear-gradient(top, #383838, #282828);
  background-image: -ms-linear-gradient(top, #383838, #282828);
  background-image: -o-linear-gradient(top, #383838, #282828);
  background-image: linear-gradient(top, #383838, #282828);
}

#navbar {
  display: block;
  list-style: none;  
}
#navbar li {
  display: block;
  float: left;
}

#navbar li a {
  display: block;
  position: relative;
  float: left;
  line-height: 55px;
  padding: 0 10px;
  font-size: 1.4em;
  color: #ddd;
  font-weight: bold;
  letter-spacing: -0.02em;
  text-decoration: none;  
}
#navbar li.first a {
  padding-left: 0;
}
#navbar li a:hover, #navbar li a.open {
  color: #fff;
}
#navbar li a.open {
  background-color: #282828;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#282828), to(#181818));
  background-image: -webkit-linear-gradient(top, #282828, #181818);
  background-image: -moz-linear-gradient(top, #282828, #181818);
  background-image: -ms-linear-gradient(top, #282828, #181818);
  background-image: -o-linear-gradient(top, #282828, #181818);
  background-image: linear-gradient(top, #282828, #181818);
}

Each of the list items will float along with the anchor links. It is essential to include a clearfix on the unordered list to keep everything recognized within the document structure.

When hovering onto a link it’ll automatically lighten the font color. But if we detect it has some mega navigation content the link also gets an appended class of .open. This changes the background color to stand out from the rest of the menu.

/** mega navigation **/
.megacontent {
  display: none;
}

#megamenu {
  display: none;
  position: relative;
  top: 0;
  width: 850px;
  height: auto;
  padding: 15px 10px;
  background: #fff;
  z-index: 999;
}

#megamenu .col {
  float: left;
  min-width: 120px;
  margin-right: 10px;
}

#megamenu .col h3 {
  display: block;
  font-size: 1.55em;
  font-weight: bold;
  color: #5e6699;
  margin-bottom: 6px;
}

#megamenu .col .navlist li a {
  display: block;
  width: 100%;
  color: #515463;
  font-size: 1.2em;
  padding: 4px 2px;
  text-decoration: none;
}
#megamenu .col .navlist li a:hover {
  background: #e5e6ec;
}


#megamenu .postlist {
  width: 100%;
}
#megamenu .postlist li {
  display: block;
  position: relative;
  float: left;
  margin-right: 10px;
}

#megamenu .postlist li h4 {
  position: absolute;
  bottom: 15px;
  left: 10px;
}
#megamenu .postlist li h4 a {
  padding: 6px 5px;
  color: #eee;
  font-size: 1.35em;
  font-weight: bold;
  text-decoration: none;
  background: #323232;
}

The block of code above is most important for getting everything to display properly. Both the .megacontent and #megamenu divs are not displayed on the page. But #megamenu is the only one which does get displayed, since all the navigation content is imported into that div. .megacontent is more of a container which most users never get to see, but it’s good for old phones and screen readers to have the menus close together.

The .col stands for “column” and this is used to create multi-column spans across the menu. No matter how much content is used, the mega navigation dropdown will span the entirety of the inner page. This is good for consistency and it helps the menu appear bigger on-screen.

Capturing Hover States with jQuery

There’s a few checks we need to make regarding the hover state, but this script only has two primary actions. First we determine if the hovered link contains mega navigation content, and if so then we copy it into the #megamenu div.

The second action is to display the menu and detect once the user is done hovering so we can hide it again. You should have some understanding of event handlers before modifying the code too much.

$(function() {
  var $megabox     = $('#megamenu');
  var fadeinspeed  = 200;
  var fadeoutspeed = 240;
  
  $('#navbar li a').on('mouseenter', function(event){
    if($(this).next().attr('class') == 'megacontent') {
      var mmenu = $(this).next().html();
      $megabox.html(mmenu);
      
      $(this).addClass('open');
      $megabox.fadeIn(fadeinspeed);
    }
  }).on('mouseleave', function(event){
    var newelm = event.toElement || event.relatedTarget;
    var $link = $(this);
    
    if($(newelm).attr('id') != 'megamenu') { // if newly hovered elm isn't megamenu
      $link.removeClass('open');

      if($(newelm).next().attr('class') != 'megacontent') { // if newly hovered elm isn't a megamenu link
        $megabox.fadeOut(fadeoutspeed);
      }
    }
  });

The variable $megabox will hold the jQuery element so it doesn’t need to be repeatedly targeted in the DOM. Also I’m setting the fade-in and fade-out speeds through variable names which you can easily update. The event handler is targeting every anchor link within the #navbar for mouseenter events(basically hovering).

But there is a slight distinction between hover and mouseenter – specifically that mouseenter changes to mouseleave when not hovering anymore. We need to capture both events and deal with the mega nav menu accordingly. If the hovered link contains an internal .megacontent then we know it needs to display a new menu.

I’ve merely copied the .megacontent into our primary #megamenu with the jQuery html() method. Then using fadeIn() the effect is complete.

Chaining Hover Events

The two variances mouseenter and mouseleave can be tied onto the same target. You’ll notice I have two .on() methods with both events triggering different blocks of code. When leaving the link we need to make sure the user isn’t hovering onto the mega nav itself.

Both of the properties event.toElement and event.relatedTarget can be pulled from the event variabile. This is automatically created during an event handler and the properties change whether it’s a hover, click, scroll, or something else.

$('#navbar li a').on('mouseenter', function(event){
  // when mouse is hovering a link do something
}).on('mouseleave', function(event){
  // when the mouse is gone do something else
}

This is what my event handler would look like without any code. It’s one big jQuery block yet very easy to understand once you break it down into the primary functions.

Hiding the Mega Menu

We know that hovering off the link elsewhere on the page will hide the menu, unless hovering onto the menu itself. So now we need to check when the user is hovering the mega menu and then hovers elsewhere on the page.

What if they hover back onto the primary link? In that scenario we should keep the menu visible, otherwise it needs to be hidden.

  $($megabox).on('mouseleave', function(event){
    var newelm = event.toElement || event.relatedTarget;
    var $link = $('#navbar li a.open');
    
    if($(newelm) != $link) { $link.removeClass('open'); }

    if($(newelm).next().attr('class') != 'megacontent') {
      $megabox.fadeOut(fadeoutspeed);
    }
  });

  $('body').on('click', 'a[href^="#"]', function(event){
    event.preventDefault();
  });
});

I’m using a very similar function to check if the hovered item isn’t the primary nav link. It’s basically the same as before except checking for a different hover element when the user moves their mouse off the menu.

At the bottom of my code you’ll notice a snippet which prevents any link with the href=”#” attribute from loading. In most cases it will cause the website to jump up towards the top of the page and it’s an ugly effect in tutorials. You’re free to remove this block of code or keep it – but it should only block links which have the empty hash symbol and nothing more.

mega navigation menu howto tutorial preview jquery

Closing

Not every website project is in need of these mega navigation menus. I typically see them on magazines or larger websites using multiple categories and styles of post content. It’s fantastic at capturing interest and drawing a closer user experience. Feel free to download a copy of the source code and see what other styles of navigation you can build.


Advertise here with BSA

]]>
http://designm.ag/tutorials/meganav-menu-with-css3-jquery/feed/ 0
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 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 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