Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

July 19 2013

00:13

Pure: What, Why, & How?

This tutorial will introduce you to Pure, a CSS library made of small modules, that can help you in writing completely responsive layouts, in a very fast and easy way. Along the way, I’ll guide you through the creation of a simple page in order to highlight how you can use some of the library’s components.


Why Create Responsive Layouts?

Over the past few years in web development, three words that are bouncing around, over and over again are: Responsive Web Design (RWD). At this point you should already know what it is, but, just in case you missed it, here are some resources to fill in the gaps:

But the question is: Why go responsive? The answer is that we don’t have any control over which resolution the next device will be using when they visit our website. No longer can we just display sentences like, “Best viewed at 1024×768 resolution” (although you can still find them on the web). One of the main reasons for this phenomenon was from the growth in the width of PC monitors and also from the spread of mobile devices which are connected to the Internet. Additionally, based on StatCounter, currently ~ 16% of users are connected through a mobile device. Now I’m not saying that RWD is just a matter of optimizing a website for a given screen size, what I mean is that we’re creating a great experience for users visiting our website regardless of the devices they are using.

With that said, it’s also clear that not all of us work for a company where every person has a single role (designer, developer, tester, and so on). So, let’s say that you’re a solo developer, working as a freelancer and you don’t know much about web design. There are a lot of libraries available that can speed up your work-flow. The most complete ones are surely Boostrap and Foundation but sometimes they can be overkill and you may need something smaller. In these instances, a new interesting project has been launched by Yahoo which we can use, called Pure.


What Is Pure?

Citing the Pure website, it is a set of small, responsive CSS modules that you can use in every web project. As said before, the complete library is really light, being only 4.2KB minified and gzipped, but to keep your website even lighter, you can include just some of the available modules. Basically, it’s composed of the following modules:

  • Base
  • Grid
  • Forms
  • Buttons
  • Tables
  • Menus

One of the things I really appreciate about Pure is that it’s based on Normalize.css, a well known library that renders elements more consistently and in line with modern standards and also works in older browsers. Since it’s really small, it doesn’t offer a complete solution to all of your problems, but it has several prebuilt common UI elements that you can find in a lot of websites on the web. Another interesting feature of Pure is that it’s highly extensible and customizable. The authors used SMACSS to build it and all of its classes start with pure-, so you can easily recognize them.

Although Pure is an interesting project to look at, keep in mind that it is really new and might not be a good fit for large projects. In fact, the current version (0.2.0 at the time of this writing) has several issues that you probably wouldn’t find in more mature frameworks and its documentation could also be improved upon. Nonetheless, I liked it and being a precursor, you have the advantage to study and learn Pure, from the very start, which could end up being the next well known project on the web.


Let’s See Pure in Action

They say that an image is worth a thousand words. For us, as developers and designers, a demo that we can play around with is even better. So, to see what Pure can do for us, let’s create a basic demo app. Our demo will consist of a simple Homepage containing some information about myself (sometimes my imagination scares me). The image below shows you what the final result should look like on a large screen:

Final Result on Desktop

And the following image, instead, shows you how it will look on a smartphone:

Final Result on Mobile

Step 1: Create the Horizontal Menu

As I said, Pure has several prebuilt common elements that you can find in a lot of websites on the web. A horizontal menu is surely one of them and will give us the chance to take a look at some of the classes of the menus module.

To create this using HTML5, we usually have a <nav> element wrapping an unordered list that contains the main links of our website. Once the list is created, we have to display it horizontally. To achieve this, we have to apply three classes to the list wrapper (<nav>): .pure-menu, .pure-menu-open, and .pure-menu-horizontal. The first class applies rules that are common to all menus in Pure. The .pure-menu-open class is used to show (instead of hide) the list items, while the .pure-menu-horizontal class is the one responsible for showing the list items on the same line. Please note that by default, the menu isn’t centered.

Now, to enhance the user interface, we should highlight the list item that links to the current page. This is done by applying the .pure-menu-selected class to the <li> element you want to highlight. By doing so, the color of the text will turn from grey to black.

The complete code of our menu is displayed below:

<nav id="main-menu" class="pure-menu pure-menu-open pure-menu-horizontal">
   <ul>
      <li class="pure-menu-selected"><a href="#">Home</a></li>
      <li><a href="#">Projects</a></li>
      <li><a href="#">Publications</a></li>
      <li><a href="#">Portfolio</a></li>
      <li><a href="#">Services</a></li>
   </ul>
</nav>

Step 2: The Author Description

After the menu, you can see we have an ideal “row” containing on the left side, a photo and on the right side, a small description of me. This “row”, is actually a responsive grid made of two grid units, where the first wraps the photo and occupies 25% of its space, while the second wraps the description and occupies the remaining 75%, as long as the width of the screen is larger than 767px. On the contrary, if the screen’s width is equal to or smaller, the grid units are stacked and occupy 100% of the width available. Please note that the units have a 100% width, so if the elements inside them are smaller in width, they will occupy only part of the unit. To see how this works, try resizing the window and notice how the photo does not consume 100% of the width, while at the same time, the grid units are stacked.

As noted before, Pure has a specific module for managing grids. To declare a responsive grid, you have to apply to the container a class called .pure-g-r. The grid units though, instead, share a similar name, .pure-u-*-*, where the final part of the class specifies how much space the given unit will take up. For example, if you apply to an element the .pure-u-1-4 class, it’ll reserve 25% of the available width, as I did for the photo. Another example could be .pure-u-2-3 which will allow the unit to take up 66.6% of the grid space.

This grid system is really interesting because it can save you a lot of time if you don’t know how to manage float, clear, and other rules to create layouts. In addition, they will save you from all the pain of managing the responsive side of the layout.

With that said, the code that implements the first grid should look like this:

<article id="about-me" class="pure-g-r">
   <h1>Aurelio De Rosa</h1>
   <div class="pure-u-1-4">
      <img src="http://aurelio.audero.it/images/aurelio-de-rosa-2.jpg" alt="Aurelio De Rosa" />
   </div>
   <section class="pure-u-3-4">
      <p>
         I'm an Italian web and app developer who have a bachelor degree in Computer Science and more
         than 5 years' experience programming for the web using HTML5, CSS3, JavaScript and PHP.
         I mainly use the <abbr title="Linux Apache MySql PHP">LAMP</abbr> stack and frameworks like
         <a href="http://jquery.com/" target="_blank">jQuery</a>, <a href="http://jquerymobile.com/" target="_blank">jQuery Mobile</a> and
         <a href="http://phonegap.com/" target="_blank">Cordova (PhoneGap)</a>. My interests also include web security,
         web accessibility, SEO and <a href="http://wordpress.org/" target="_blank">WordPress</a>.
      </p>
      <p>
         Currently I'm self-employed working with the cited technologies. I'm also a regular blogger for
         several networks (<a href="http://www.sitepoint.com/author/aderosa/" target="_blank">SitePoint</a>,
         <a href="http://mobile.tutsplus.com/author/aurelio-de-rosa/">Tuts+</a> and
         <a href="http://flippinawesome.org/authors/aurelio-de-rosa/" target="_blank">FlippinAwesome</a>)
         where I write articles about the topics I usually work with and more.
      </p>
   </section>
</article>

Step 3: The Information Grid

The second and last grid is split into three equal parts. I created them to show you other components of the library, so you can have a good overview of them. In fact, the first unit has a table, the second has a form, and the third has a vertical menu.

The code below shows you how to split the grid into three parts:

<article class="pure-g-r">
   <div class="pure-u-1-3">
   </div>
   <div class="pure-u-1-3">
   </div>
   <div class="pure-u-1-3">
   </div>
</article>

Now, let’s explore each unit of this responsive grid.


Step 4: A Responsive Table

Another one of the available modules in Pure, is Tables. Like the name says, it contains rules to style a <table> element and its children. By default, tables will have a vertical border applied to visually separate columns. However, you can also add a horizontal border, applying the .pure-table-bordered class or show only the latter using the .pure-table-horizontal class to the <table> element. Additionally, you can also create striped tables to aid the user in reading the data. To achieve this, you have two possibilities. The first will work on browsers that support nth-child and consists of applying the .pure-table-striped class name to the <table> element. The second, instead, works in all the browsers, including Internet Explorer 8 and lower, but it’s more verbose. It consists of adding the .pure-table-odd class name to every other <tr> element. For compatibility reasons, I’ll go for the second approach.

Currently, tables have a problem when viewed on small screens, but it’ll be fixed in the next release. Please note that you won’t see it in the demo because I fixed it. High five for me.

The code that creates the striped table is shown below:

<h3>Funny Price Table</h3>
<table class="pure-table">
   <thead>
      <tr>
         <th>Hours Number</th>
         <th>Price (&euro;)</th>
         <th>Safe (%)</th>
      </tr>
   </thead>
   <tbody>
      <tr class="pure-table-odd">
         <td>1</td>
         <td>30 &euro;</td>
         <td>0%</td>
      </tr>
      <tr>
         <td>5</td>
         <td>135 &euro;</td>
         <td>10%</td>
      </tr>
      <tr class="pure-table-odd">
         <td>10</td>
         <td>255 &euro;</td>
         <td>15%</td>
      </tr>
      <tr>
         <td>20</td>
         <td>480 &euro;</td>
         <td>20%</td>
      </tr>
      <tr class="pure-table-odd">
         <td>50</td>
         <td>1050 &euro;</td>
         <td>30%</td>
      </tr>
   </tbody>
</table>

Step 5: A Stacked Contact Form

Forms are yet another module of the Pure library. It allows you to display your forms in several different types of styles. In this demo, we’ll create a stacked form, where the input elements are below the labels. To do this, we have to add the .pure-form and the .pure-form-stacked classes to the <form> element. Then we have to place both the label and the input tags within a wrapper, where we’ll apply the .pure-control-group class and then put all of these wrappers into a <fieldset> element. The submit and the reset button will have a wrapper as well, but their wrapper will have the class .pure-controls. Please note that for the submit button, we used the class .pure-button-primary to highlight it. The cited class belongs to the Buttons module and is used to change the style of the button, applying a blue color.

Here’s what your form code should look like:

<h3>Contact me</h3>
<form id="contact" name="contact" action="#" method="post" class="pure-form pure-form-aligned">
   <fieldset>
      <div class="pure-control-group">
         <label>Name:</label>
         <input type="text" name="name" placeholder="Name" />
      </div>
      <div class="pure-control-group">
         <label>Email</label>
         <input type="email" name="email" placeholder="Email" />
      </div>
      <div class="pure-control-group">
         <label>Subject</label>
         <input type="text" name="subject" placeholder="Subject" />
      </div>
      <div class="pure-control-group">
         <label>Message:</label>
         <textarea name="message" placeholder="Your message here..."></textarea>
      </div>
      <div class="pure-controls">
         <input type="submit" class="pure-button-primary" value="Submit" />
         <input type="reset" value="Reset" />
      </div>
   </fieldset>
</form>

Step 6: A Vertical Menu With a Header

The final element that you’ll learn how to create, using Pure, will be a vertical menu with a header. A menu of this type is styled with a black border, all around. To use it, we’ll apply to the list wrapper, two of the three classes we’ve already used in the first step, that is .pure-menu and .pure-menu-open. In addition, to create the header, we must add another element and apply to it the .pure-menu-heading class.

The code for this menu is listed below:

<h2>Where to find me</h2>
<div class="pure-menu pure-menu-open">
   <a href="#" class="pure-menu-heading">My profiles</a>
   <ul>
      <li><a href="http://www.twitter.com/AurelioDeRosa">Twitter</a></li>
      <li><a href="http://www.linkedin.com/in/aurelioderosa">LinkedIn</a></li>
      <li><a href="https://github.com/AurelioDeRosa">GitHub</a></li>
      <li><a href="https://plus.google.com/111199469497044249730">Google+</a></li>
   </ul>
</div>

Conclusion

So that completes this introduction to Pure. I hope you enjoyed it. If you’d like to follow the development of Pure, you can visit its repository on GitHub. Feel free to submit issues, issue pull requests, and contribute.

June 20 2013

20:44

Developing With Sass and Chrome DevTools

In this article we’ll take a look at how we can better integrate Chrome DevTools into our Sass development workflow.


Tutorial Sneak Peek!

Here’s a peek of what we’ll be doing in this tutorial via an animated GIF:

edit-sass

On the left is a terminal and the Sublime text editor, and on the right is Chrome. Changes to the .scss file are being persisted to disk, which is reflected in Sublime, the Sass watch command is generating a new version of a CSS file when it detects changes to the Sass file, which is in turn picked up by DevTools and reflected onto the page.


The Need for a Better Workflow

So what are we trying to solve here? Why would we want a better workflow? Well, let’s review an example of debugging some Sass-generated CSS, given the following .scss file, which contains:

$myColor: green;

body {
	.box {
		color: $myColor;
	}
}

And now the CSS, which is generated by the above Sass file, would look like this:

body .box {
  color: green; }

Now we just need a little bit of HTML to apply our styling to:

<div class="box">Hello</div>

Ok, so far so good. Now we want to start designing and developing our page using Chrome DevTools. First we inspect the div with a class of box by right clicking on it and selecting Inspect Element. Then we can check out the styles pane, which shows a green value for the color property, a note on the filename it’s contained within, along with the line number that the selector appears on. Now here’s where the problem lies – the processed CSS does not follow, line for line, what the source .scss file looks like, which can have a negative impact on our development workflow.

sublime-source-vs-output

In the image above, the left pane shows a source .scss file and the right side shows the processed version. (Note I’m using the SCSS bundle for syntax highlighting in Sublime Text)

dev-tools-regular-view

DevTools then provides a link to the file and line number of the selector, highlighted in red above, which unsurprisingly links to the processed file (image below). This now acts as a limitation for editing the file within DevTools as we can’t benefit from file saving. For example, if we persist changes to the processed file, they’ll just be overwritten when Sass next runs.

In fact, we don’t even have a clear indication of what the corresponding line number is – of course, practically speaking, our above example is very simple and we can very quickly understand what line maps to what, by looking at the code. However in a larger .scss file, things can get trickier.

sources-panel-regular

As you can see above, DevTools has no understanding of our .scss file, we can address this however by utilizing a DevTools and Sass workflow, which is what we’ll be looking at in this tutorial. To summarize, a lack of Sass support in the DevTools could mean:

  • We don’t immediately know the line number a selector and/or CSS property exists on, within our source file.
  • Persisting our CSS changes to the file system is pretty much out of the question.
  • Even simply viewing the .scss file in the sources panel is difficult as DevTools doesn’t recognize the extension as one which should be viewed.

Preparing for Sass Support

Chrome

Important: Sass support is an experimental feature. Please keep in mind that, while it has been around for a while now, things may change. If they do, we’ll do our best to update this article, accordingly.

Now let’s navigate to about:flags in the omnibox, then find Enable Developer Tools experiments, enable it and restart Chrome.

chrome-flags

The image below shows an experiments panel, you can reach this by clicking on the cogwheel at the bottom right corner of DevTools and clicking ‘Experiments‘, then check the box for Support for Sass.

dev-tools-experiments

After closing and opening DevTools, you can now go to the General menu item in the left sidebar of the settings window and navigate to the Sources section, from there, check ‘Enable source maps‘ and ‘Auto-reload CSS upon Sass save‘. The timeout can be left at the default value.

sass-support-dev-tools

Sass

This tutorial uses the latest version of Sass (3.3.0 at the current time of this writing) as there is some initial support for source maps. Here’s how you can install Sass using Rubygems:

gem install sass --pre
sass-gem

We now need to tell Sass to compile our .scss files, using the following command:

sass --watch --scss --sourcemap styles.scss:styles.css

From above, the styles.scss is your source file and the styles.css is the processed file, which your HTML page would use. Here’s how you would link in the processed .css file:

<link rel="stylesheet" type="text/css" href="styles.css">

If you see something similar to the image below in your terminal:

sass-command-line

…and you see a generated .map file, then, congratulations: Sass debugging is working! Here’s what those other command options are doing from the previous compile command:

  • --watch: Will watch for changes to the source .scss file and compile it as soon as it has detected a change.
  • --scss: Will display what style of Sass we are using.
  • --sourcemap: Will generate corresponding source map files.

Now, having an understanding of source maps isn’t critical to follow along, however it’s certainly something worth reading about as it’s intended to help the development process. See below for a few resources on source maps:


From Elements to Sources

elem-to-source

Assuming all went well, opening up your page where Sass support is enabled in DevTools should allow for Sass debugging. The first thing to note is that the filename will show the corresponding .scss source file, which is useful, in addition to that, the line number correctly reflects the line number in our source file.

elements-sass

Clicking on the filename will take you right to the sources panel with the line corresponding to the selector in question highlighted.

Note: You now have a viewable Sass file right in your browser with syntax highlighting!

sources-panel-sass

Ok, so finding the corresponding CSS selector from the Elements panel is cool, but what about CSS properties?

In the screenshot below, the Sources panel has highlighted the CSS property I was interested in, to get there I had Command-Clicked on the property from within the Elements panel. The fact that it has taken me to the line where the value was defined (rather than the line: property: $value;) is very powerful!

sources-property-sass

Note: Navigating to a CSS property in the sources panel from command clicking the property in the Elements panel is not specific to Sass, it can be achieved with regular CSS too.


Sass Editing With Persistent Changes

Editing a Sass file is not much different than editing a regular CSS file, one thing we will need to do however is ensure DevTools knows where the .scss file is located at on the file system. From within the Sources panel, the left hand sidebar should have a Sources pane which displays the .scss file, right click it and choose Save as, then overwrite the existing .scss source file.

sources-save-as-sass

Because we checked ‘Auto-reload CSS upon Sass save‘ and because Sass is running in the terminal with the watch flag, changes are made pretty quickly and the DevTools are able to show us those changes.

Even mixins work as expected, pasting the following, in an almost empty .scss file within the sources panel results in the correct CSS being generated, which DevTools is able to reload from within a second.

@mixin button {
    border: 2px solid green;
    display: inline-block;
    padding: 10px;
    border-radius: 4px;    
}

.box {
    @include button;   
}
mixin-sources

As you can see in the image above, the left hand side shows the .scss source file, which is what we would make changes to, the right hand side shows the generated .css file which DevTools has picked up changes from (almost immediately thanks to the watch flag in the terminal)


Sass Debugging at Fluent Conf

Paul Irish gave a great talk at Fluent which had lots of juicy information on the Chrome DevTools, but also the use of Sass. Skip ahead to 5:30 for the Sass information.


Summary

Let’s go over some of the main points discussed in this tutorial:

  • Sass capabilities in Chrome DevTools are a great way to view and modify Sass resources, although don’t forget to enable it in both about:flags and in the settings panel.
  • When using Sass and the Chrome DevTools in a project, you’re likely to have a more efficient workflow with viewing/editing the source file, rather than the generated file.
  • CSS properties in the elements panel can be Command-clicked, the file name displayed to the right of the selector is also clickable. Both will take you to the relevant portion in the sources panel.
  • Utilize the Sources panel’s editing capabilities by doing a ‘Save as‘ on the .scss file, future saves (Command+S) should overwrite the file.
  • Chrome Canary and the latest version of Sass 3.3.0 (due to Source maps) were used in this tutorial, be sure to try them out!

Interesting links

As you can see, the development workflow with Sass is not perfect, but it’s definitely a lot better than what it used to be. As time goes on, DevTools will provide a more streamlined workflow for editing CSS files and bugs will be fixed! Any issues you do find can be raised as a bug at crbug.com.

Thanks for reading this article!

May 24 2013

13:00

Design a Pricing Plan Using CSS3 in Under 15 Minutes – Downloadable

Today we continue the series of tutorials on basic HTML5 and CSS3 coding and we jump even deeper into CSS3 with this video on how to design a pricing plan.

If you own a product which you sell only on a subscription basis, then you will probably need pricing tables in order to showcase your product and the purchase options better. This tutorial will teach you how to do that.

The tutorial is based on lots of things we went through in the previous tutorials, but today you will also learn how to:

  • Only style some elements of a list without giving a class to each of them.
  • You will also learn how to apply different styles only on the first and last element of a parent (which could also be a list as well).
  • Regarding transitions, which we’ve worked with since the second tutorial, you will learn how to scale objects up or down on hover by using CSS instead of relying on JavaScript, as we had to before.

At the end of the video I also make a promise to you regarding what am I going to come with next time. Sneak peek: it’s for mobile.

Until next time, I hope you enjoy the video and, as always, I am looking forward to your feedback and comments.

Comparison Table Preview

By the end of this tutorial you will be able to design a pricing plan like the image below.

Design a Pricing Plan Using CSS3 in Under 15 Minutes - Downloadable

Saw the demo? If you’re ready to design a similar pricing plan, free up at least 23 minutes of your time and get ready to design your very first pricing table!

Pricing Plans Using CSS3 Video Tutorial

When You Design a Pricing Plan, Keep in Mind the Following:

  • Don’t over design it, people are after the information, not the design.
  • Make it visually pleasing and easy to read.
  • Don’t over complicate the code, be sure to always keep your CSS in check in case you will need to update it at a future date.

Tell us what you think about this video tutorial in the comments!

May 21 2013

14:55

The Right Way to Retinafy Your Websites

Making your website ready for Retina display doesn’t have to be a hassle. Whether you are building a new website or upgrading an existing one, this guide is designed to help you get the job done smoothly.


Make it Retina First

The easiest and most time-saving way to add Retina support is to create one image that is optimized for Retina devices, and serve it to non-Retina devices as well.

By now, every modern browser uses bicubic resampling and does a great job with downsampling images. Here’s a comparison of downsampling in Photoshop vs. Google Chrome, using an image from our Growth Engineering 101 website.

Growth Engineering 101

There are two ways to let the browser downsample images for you: img tags or CSS background images.

You can have img tags serve the Retina-optimized image, and set the width and height attributes to half of the resolution of the actual image (e.g. 400×300 if the image dimensions are 800×600).

<img src="http://www.example.com/Retina-image-800x600-2x.png" width="400" height="300">

If you use images as CSS backgrounds, you may use the CSS3 background-size property to downsample the image for non-Retina devices.

<div class="photo"></div>
.photo {
    background-image: url(Retina-image-800x600-2x.png);
    background-size: 400px 300px;
    background-repeat: no-repeat;
    display: block;
    width: 400px;
    height: 300px;
}

In both cases, be sure to use even numbers in both dimensions to prevent displacement of pixels when the image is being downsampled by the browser.


When Downsampling is Not Good Enough

Usually, browser downsampling should work quite well. That said, there are some situations where downsampling in the browser might make images blurry.

Here we have a bunch of 32px social icons.

32x32 px social icons

And here is how they will appear, when downsampled to 16px by Photoshop’s as well as Google Chrome’s bicubic filter. It seems that we get better results from Photoshop in this case.

16x16 px social icons - Transparent BG - Chrome vs Photoshop 16x16 px social icons - White BG - Chrome vs Photoshop

To get the best results for our users, we can create two versions of the same image: one for Retina devices, and another one that has been downsampled by Photoshop for non-Retina devices.

Now, you can use CSS media queries to serve Retina or non-Retina images, dependent upon the pixel density of the device.

/* CSS for devices with normal screens */
.icons {
    background-image: url(icon-sprite.png);
    background-repeat: no-repeat;
}
/* CSS for high-resolution devices */
@media only screen and (-Webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
    .icons {
        background-image: url(icon-sprite-2x.png);
        background-size: 200px 100px;
        background-repeat: no-repeat;
    }
}

If you use a background color for small icons, on the other hand, downsampling by the browser works rather well. Here is the same downsampling example with a white background.

16x16 px social icons - Zoom 200%

Polishing Your Downsampled Images

If you’re still not satisfied with the results from Photoshop’s downsampling, you can go the extra mile and hand-optimize the non-Retina version to get super crisp results.

Below are some examples of images from the Blossom product website that I hand-optimized for those who are still on non-Retina devices.


Borders and Strokes

Here’s an example of downsampling issues with hairlines, where I re-draw the lines of the downsampled image.

Borders and Strokes - Teaser Image

View the Retina Version of this Image on Dribbble.

Borders and Strokes - Photoshop vs Chrome Borders and Strokes - Photoshop vs Hand

Text

Next, we come to an example of downsampling issues with text. In this case, I manually re-wrote the text “Feature Pipeline” to make the result as crisp as possible.

Text - Original

Retina Version
Text - Photoshop vs Hand Text - Photoshop vs Chrome

When details, crisp fonts, and clean hairlines are important, you might want to go the extra mile.


Try to Avoid Images

The main disadvantages of rasterized images are their considerable file size and that they don’t scale well to different sizes without affecting the image quality. Great alternatives to rasterized graphics are CSS, Scalable Vector Graphics (SVG), and Icon Fonts.

If you have any chance to build the graphical elements for your website in CSS, go for it. It can be used to add gradients, borders, rounded corners, shadows, arrows, rotate elements and much more.

Here are a few examples of interaction elements in Blossom that are implemented in CSS. The subtle gradient is powered by CSS gradients, and the custom font in use on this button is Kievit, served via Typekit. No images.

CSS Solution - Button

In the following screenshot, the only two images used are the user avatar and the blue stamp. Everything else – the circled question mark, the dark grey arrow next to it, the popover, its shadow and the arrow on top of it – is pure HTML and CSS.

CSS Solution - Popover

Here, you can see how projects in Blossom appear. It’s a screenshot of a project’s website used as cover on a stack of paper sheets. The paper sheets are implemented with divs that are rotated using CSS.

CSS Solution - Stack

Also, the circled arrow in the right-hand side of the screenshot below is pure CSS.

CSS Solution - Circled Arrow

Tools

Here are some awesome tools that will help save time when creating effects with CSS.

Scalable Vector Graphic

The primary advantage to SVG is that, unlike rasterized graphics, they scale reasonably well to various sizes. If you’re working with simple shapes, they typically are smaller than PNGs. Often, they are used for things like charts.

Icon Fonts

Icon Fonts are frequently used as a replacement for image sprites. Similar to SVG, they can be scaled up infinitely without any loss of quality and are usually smaller in size, when compared to image sprites. On top of that, you can use CSS to change their size, color and even add effects, such as shadows.

Both SVG and Icon Fonts are well supported by modern browsers.


Retina-Ready Favicons

Favicons are really important for users who need an easy way to remember which website belongs to which browser tab. A Retina-ready Favicon will not only be easier to identify, but it will also stand out among a crowd of pixelated Favicons that haven’t yet been optimized.

To make your Favicon Retina-ready, I highly recommend X-Icon Editor. You can either upload a single image and let the editor resize it for different dimensions, or you can upload separate images optimized for each size to get the best results.

X-Icon Editor

How to Make Existing Images Retina-Ready

If you want to upgrade a website with existing images, a bit more work is required, as you’ll need to re-create all images to make them Retina-ready, but this doesn’t have to waste too much time.

First, attempt to identify images that you can avoid by using alternatives like CSS, SVG and Image Fonts, as noted previously. Buttons, Icons and other common UI widgets usually can be replaced with modern solutions that don’t require any images.

In case you actually need to re-create rasterized images, you’ll of course want to return to the source files. As you might assume, simply resizing your rasterized bitmap images to be twice as big doesn’t get the job done, because all of the details and borders will become pixelated.

No need to despair – image compositions which mostly contain vectors (i.e. in Adobe Photoshop or Illustrator) are quite easy to scale up. That said, don’t forget to verify if your Photoshop effects in the blending options, such as strokes, shadows and bevels, still appear as you intended.

In general, making Photoshop compositions directly out of vectors (shapes) and Photoshop’s Smart Objects will save you a great deal of time in the future.


How to Optimize the File Size of Images

Last, but not least, optimizing the file size of all images in an application or website could effectively save up to 90% of image loading times. When it comes to Retina images, the file size reduction gets even more important, as they have a higher pixel density that will increase their respective file sizes.

In Photoshop, you can optimize the image file size, via the “Save for Web” feature. On top of that, there is an excellent free tool, called ImageAlpha, which can reduce the size of your images even more with just a minor loss of quality.

Unlike Photoshop, ImageApha can convert 24-bit alpha channel PNGs to 8-bit PNGs with alpha channel support. The icing on the cake is that these optimized images are cross-browser compatible and even work for IE6!

You can play around with different settings in ImageAlpha to get the right trade-off between quality and file size. In the case below, we can reduce the file size by nearly 80%.

Image Alpha

When you’re finished setting your desired compression levels, ImageAlpha’s save dialog also offers to “Optimize with ImageOptim” – another great and free tool.

ImageOptim automatically picks the best compression options for your image and removes unnecessary meta information and color profiles. In the case of our stamp file, ImageOptim was able to reduce the file size by another 34%.

Image Optim

After we updated all assets at Blossom.io for high resolution displays and used ImageAlpha and ImageOptim to optimize the file size, we actually ended up saving a few kilobytes in comparison to the assets we had before.


Save Time, Read This Book

Retinafy.me - Retinafy your Websites and Apps

If you want to learn more about how to get your apps and websites ready for Retina displays, I highly recommend “Retinafy your web sites & apps”, by Thomas Fuchs. It’s a straight-forward step by step guide that saved me a lot of time and nerves.


Awesome Retina-Ready Sites on the Web

Kickoff
http://kickoffapp.com/
LayerVault
http://www.layervault.com

Apple
http://www.apple.com

Panic

http://www.panic.com

Thanks for reading! Any questions?

May 08 2013

13:00

Create a Contact Form in HTML5 and CSS3 for Dummies – Downloadable

Today I will teach you how to create a simple contact form in HTML5 and CSS3 that you can download for free. Many WordPress plugins come with fully functional contact forms that can be installed and used right away, but we believe in beautiful design and in your right to style it however you choose. Therefore today’s video will focus on how to create, but mainly how to style, your contact form using CSS3.

There is not much HTML5 in this video tutorial, unfortunately, as the contact form is built with code available in previous versions of HTML, but you can use today’s tutorial as a way to reinforce many of the things we learned together in the previous tutorials. So without any further discussion, here it is:

Create a Contact Form in HTML5 and CSS3

What you will learn:

  • the basics of CSS3 styling
  • how to create an HTML form
  • how to create an elegant CSS3 contact form

create-css3-contact-form

By the end of the tutorial you will have something similar to the screenshot above. Feel free to view the demo just after the video tutorial to get a feel of what you will be making in under 25 minutes. It’s a good exercise for both beginners and experts alike!

Challenge For You

Can you make this form Responsive? I will give you a hint, but it will be somewhat irrelevant to a contact form, but surely you are smart enough to work your way through it, yes?

Hint: It’s all about media queries!

How to Make It Work

Although making it functional will require a little bit of server side programming, I’ll be glad to point you to the right direction!

In order to make this form function for your website, you’ll need to code it with PHP.

How to Make a Contact Form Using PHP

Note: this tutorial is over three years old but it will still work, you will just need to add security features (Google it!).

Good luck!

April 18 2013

13:00

WordPress Plugin Development for Designers – Custom Post Types

Hello Everyone! Welcome back to the third part of this series on WordPress Plugin development for designers.

In the first part we identified the importance of WordPress plugins for you as designers and the basic structure of a plugin. Then we followed it up with the necessary coding required for developing plugins in the second part, by creating a jQuery slider for WordPress.

I am happy to announce that SlidesJS has won the voting contest and I’ll be using it through the rest of this tutorial series.

I hope you have used the slider plugin and tried to fix the responsive issue we had in the demo. We got good responses containing the possible solutions. So we are going to start the third part by fixing the responsive issue in the slider.

Download Slider Version 2 | Demo

Following is an image from demo we created in the previous part, illustrating the responsive issue.

wpdd_part3_1

Making SlidesJS Responsive

SlidesJS is designed to use 940px as its default width. Most of the websites are designed in a grid with at least 960px width. So default SlidesJS slider will be responsive in full width pages. We are using the TwentyEleven theme in this demo. It doesn’t offer the full width in its default pages or posts. Therefore we have to adjust the slider according to our themes to make it responsive.

CSS media queries can be used effectively to make the slider responsive. So let’s take a look at the default media queries provided by SlidesJS.

<style>
<!--
/* For tablets & smart phones */
   @media (max-width: 767px) {
     body {
       padding-left: 20px;
       padding-right: 20px;
     }
     .container {
       width: auto
     }
   }

   /* For smartphones */
   @media (max-width: 480px) {
     .container {
       width: auto
     }
   }

   /* For smaller displays like laptops */
   @media (min-width: 768px) and (max-width: 979px) {
     .container {
       width: 724px
     }
   }

   /* For larger displays */
   @media (min-width: 1200px) {
     .container {
       width: 1170px
     }
   }

-->
</style>

960px layouts will fit into the media query between 768px and 979px. Slider container is defined as 724px for that particular width range. Basically what you have to do is adjusting the width of slider container based on your themes content area dimensions. So the updated media queries to suit TwentyEleven theme are as follows.

<style>
<!--
    /* For tablets & smart phones */
    @media (max-width: 767px) {
      body {
        padding-left: 20px;
        padding-right: 20px;
      }
      .container {
        width: 400px
      }
    }

    /* For smartphones */
    @media (max-width: 480px) {
      .container {
        width: 300px;
      }
    }

    /* For smaller displays like laptops */
    @media (min-width: 768px) and (max-width: 1199px) {
      .container {
        width: 600px
      }
    }

    /* For larger displays */
    @media (min-width: 1200px) {
      .container {
        width: 600px
      }
    }
-->
</style>

You can see that I have modified the widths of all the media queries to suit TwentyElevan theme container sizes. Now let’s look at the slider after the code updates. Make sure to add these styles for media queries into the example.css file in the plugin.

wpdd_part3_2

We have completed the responsive version of static slider for WordPress. But it’s useless until we enable the capabilities for adding images dynamically through the WordPress dashboard. So let’s get started on making dynamic sliders.

Planning the Dynamic Slider Functions

In the current version of the plugin, we are using the images inside the plugin folder. But we want to put our own images in an user friendly method. Also we should be able to create multiple sliders for different locations of our web sites. Let’s list down the functionality we need to implement in this part.

  • Create multiple sliders
  • Upload images dynamically through WordPress media uploader.
  • Assign and remove images of sliders at any given time

Implementing these functionalities is not a very difficult task for people who are knowledgeable in working with PHP. But as designers you might find it a little difficult to understand if you have zero background about PHP. So I am going to explain things as simple as possible to make it easy for you.

Also keep in mind that you don’t need to understand each and every detail discussed here. I’ll tell you the tasks you need to focus and tasks you can omit as designers. So stay tuned and get ready with your code editor.

Creating Slider – Role of Custom Post Type

Most of you will be familiar in working with WordPress posts. Even if you haven’t developed or designed anything on WordPress, there is a high possibility that you have wrote an article on a WordPress blog. WordPress posts are designed to write article, tutorials or some content for your website. Following image displays the post creation screen of WordPress.

wpdd_part3_3

Usually we get fields like post title, post content, categories, featured image to insert necessary data for specific posts. Similarly WordPress provides a technique called Custom Post Types. Basically custom post type can be considered as a special kind of post. We can use custom post types to create some amazing designs and features to WordPress. In this part we are going to use specific custom post type to create sliders.

Most important thing to keep in mind is that custom post types doesn’t show in the normal post section and hence will not get displayed on your blog. We have the capability to create unique designs for these post types and decide where we should display them.

Creating Slider Post Type

I assume that you have already installed and activated the previous version of the plugin we developed in the last part. Here I’ll be adding and modifying the existing codes of the plugin.

First we have to register a new post type for sliders. You can insert the following code into the end of the 1wd_slider.php file of the plugin.


add_action('init', 'fwds_register_slider');

function fwds_register_slider() {

    $labels = array(

       'menu_name' => _x('Sliders', 'slidesjs_slider'),

    );

    $args = array(

       'labels' => $labels,

       'hierarchical' => true,

       'description' => 'Slideshows',

       'supports' => array('title', 'editor'),

       'public' => true,

       'show_ui' => true,

       'show_in_menu' => true,

       'show_in_nav_menus' => true,

       'publicly_queryable' => true,

       'exclude_from_search' => false,

       'has_archive' => true,

       'query_var' => true,

       'can_export' => true,

       'rewrite' => true,

       'capability_type' => 'post'

    );

    register_post_type('slidesjs_slider', $args);

}

WordPress executes an action called init in its initialization process of a user request. We can call any function on the init action. Here I have used a function called fwds_register_slider.

Inside the function we have to define some labels and parameters for custom post types. Labels will decide the text displayed on menu items and forms. There is a bunch of arguments to configure various features of a custom post type. Finally we register the custom post type using the register_post_type function. First parameter to this function will be the name of the custom type. You can use any unique name for that. Next we pass the arguments as the second parameter.

Understanding the complete code and configurations is not necessary at this stage as a beginner in WordPress. Following is a preview of the custom post type section for Sliders once we include this code.

wpdd_part3_4

As you can see, there is a separate section for Slider posts on the left menu and the label is converted into the text we used in the labels variable.

Things to Focus

  • Whenever you want to create Sliders, Accordions, Tabs or similar design components, use the following block of code with a new function name for init action.
  • In the labels section, change the text you want to appear and the unique post type name according to your preference.
  • Keep the arguments variable as it is now and don’t worry about the various parameters used there for the moment.
  • Finally use the same unique name used in the labels array for the register_post_type function.

Each time you use this code with different function and unique post type, new section will be added to the left menu. Now try to use Sliders in the dashboard.

We can use this section to create sliders. But still it works as normal post type and won’t do anything different. Our next task is to add images into sliders. Let’s move forward.

Creating Slider Image Fields

We have to insert different images to each new slider. WordPress meta boxes can be used effectively to add additional fields to the slider creation screen. Consider the following code.


add_action('add_meta_boxes', 'fwds_slider_meta_box');

function fwds_slider_meta_box() {

    add_meta_box("fwds-slider-images", "Slider Images", 'fwds_view_slider_images_box', "slidesjs_slider", "normal");

}

function fwds_view_slider_images_box() {
    global $post;

    $gallery_images = get_post_meta($post->ID, "_fwds_gallery_images", true);
    // print_r($gallery_images);exit;
    $gallery_images = ($gallery_images != '') ? json_decode($gallery_images) : array();

    // Use nonce for verification
    $html =  '<input type="hidden" name="fwds_slider_box_nonce" value="'. wp_create_nonce(basename(__FILE__)). '" />';

    $html .= '
'; $html .= "
<table class="form-table">
<tbody>
<tr>
<th><label for="Upload Images">Image 1</label></th>
<td><input id="fwds_slider_upload" type="text" name="gallery_img[]" value="".$gallery_images[0]."" /></td>
</tr>
<tr>
<th><label for="Upload Images">Image 2</label></th>
<td><input id="fwds_slider_upload" type="text" name="gallery_img[]" value="".$gallery_images[1]."" /></td>
</tr>
<tr>
<th><label for="Upload Images">Image 3</label></th>
<td><input id="fwds_slider_upload" type="text" name="gallery_img[]" value="".$gallery_images[2]."" /></td>
</tr>
<tr>
<th><label for="Upload Images">Image 4</label></th>
<td><input id="fwds_slider_upload" type="text" name="gallery_img[]" value="".$gallery_images[3]."" /></td>
</tr>
<tr>
<th><label for="Upload Images">Image 5</label></th>
<td><input id="fwds_slider_upload" type="text" name="gallery_img[]" value="".$gallery_images[4]."" /></td>
</tr>
</tbody>
</table>
";

        echo $html;

}

First we have to call a new function on add_meta_boxes action to create a meta box for our sliders. Inside the function we define a new meta box using the add_meta_box function as shown in the following code.


function fwds_slider_meta_box() {

    add_meta_box("fwds-slider-images", "Slider Images", 'fwds_view_slider_images_box', "slidesjs_slider", "normal");

}

First parameter is a unique key for meta box followed by meta box title. Third parameter is a new function to execute the meta boxes. Fourth parameter is the unique post type we created earlier and you can leave the final parameter to its default value of normal.

Then we need to create the fwds_view_slider_images_box function to implement the meta box.Inside the function we get the available image values for the current slider from the database. We can save images of each slider into database with slider id and a key (_fwds_gallery_images).

In the initial loading, there wont be any existing images and hence the gallery images will be empty. Then we create the fields for the images using HTML codes. I have used 5 text boxes here to enter 5 images for each slider.

Now your slider creation screen should look like the following image.

wpdd_part3_5

Things to Focus

  • Create add_meta_box functions and load it with respective parameters. If you are creating 2 types of sliders, use 2 add_meta_box functions.
  • Create new function like fwds_view_slider_images_box for each of the sliders you want to use.
  • I have used 5 images per slider. Add or remove text boxes according to your preference to get more or less images per slider.

Uploading Images to Slider

Now we can start uploading images to the slider. Just click the Add Media button on the Slider creation screen to load the WordPress media uploader. Then upload images as you do for normal posts. You should get a screen like the following once an image is uploaded.

wpdd_part3_6

In the link to section on the right, you can select whether to use the image as an attachment or media file. Select media file to get the direct link to the uploaded image. Now copy the link and close the upload window. Then insert the copied image url into the Image 1 field we created earlier. Continue this process for all the slides you want to appear in the slider.

Once all the links are filled, your slider creation screen will look like the following.

wpdd_part3_7

Saving Slider Images

We have uploaded and inserted the images into the slider. Now images need to be saved to the database. Even though image fields are in the slider creation screen, it won’t be saved automatically when the post is saved. We have to use a simple code to insert the data into the database as shown below.


add_action('save_post', 'fwds_save_slider_info');

function fwds_save_slider_info($post_id) {

    // verify nonce

    if (!wp_verify_nonce($_POST['fwds_slider_box_nonce'], basename(__FILE__))) {

       return $post_id;

    }

    // check autosave

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {

       return $post_id;

    }

    // check permissions

    if ('slidesjs_slider' == $_POST['post_type'] && current_user_can('edit_post', $post_id)) {

       /* Save Slider Images */

       //echo "
";print_r($_POST['gallery_img']);exit;

       $gallery_images = (isset($_POST['gallery_img']) ? $_POST['gallery_img'] : '');

       $gallery_images = strip_tags(json_encode($gallery_images));

       update_post_meta($post_id, "_fwds_gallery_images", $gallery_images);

    } else {

       return $post_id;

    }

}

We call a custom function on save_post action to save the image details to the database. update_post_meta function is used to save these details into the _fwds_gallery_images key. I’ll show you the things you need to know in this section as it might be little complex for the beginners in design.

Things to Focus

  • When you are saving different types of posts like sliders, accordions,tabs, make sure to create new function on save_post action and use this block of code.
  • Inside the check permission section, use your own post type instead of slidesjs_slider.
  • Use your own unique key like _fwds_gallery_images to save the data into the database.

Now when the slider is published, all the images will be saved to the database. Then click on the Sliders section from the left menu and you will get a list shown in the following image.

wpdd_part3_8

You will be able to see a separate shortocde in front of each slider you create. You can use these to generate sliders once we complete the following section.

Generating Slider Using Uploaded Section

In the previous part we used a shortcode function to include images to the slider as shown in the following code.


add_shortcode("1wd_slider", "fwds_display_slider");
function fwds_display_slider() {

 $plugins_url = plugins_url();

 echo '
<div class="container">
<div id="slides"><img alt="" src="'.plugins_url( 'img/example-slide-1.jpg' , __FILE__ ).'" />
 <img alt="" src="'.plugins_url( 'img/example-slide-2.jpg' , __FILE__ ).'" />
 <img alt="" src="'.plugins_url( 'img/example-slide-3.jpg' , __FILE__ ).'" />
 <img alt="" src="'.plugins_url( 'img/example-slide-4.jpg' , __FILE__ ).'" />
</div>
</div>

';
}

As you can see all the images are hard coded in this version. Now we have the option of using dynamic sliders as well as dynamic images. So let’s move into implementing the shortcode.


add_shortcode("1wd_slider", "fwds_display_slider");

function fwds_display_slider($attr,$content) {

    extract(shortcode_atts(array(

               'id' => ''

                   ), $attr));

          $gallery_images = get_post_meta($id, "_fwds_gallery_images", true);

          $gallery_images = ($gallery_images != '') ? json_decode($gallery_images) : array();

          $plugins_url = plugins_url();

         $html = '
<div class="container">
<div id="slides">
';

 foreach ($gallery_images as $gal_img) {

 if($gal_img != ""){

 $html .= "<img alt="" src="&quot;.$gal_img.&quot;" />";

 }

 }

 $html .= '

</div>
</div>
';

     return $html;

}

Now we use the post ID passed to the shortcodes to retrieve the images dynamically. Then we assign each image to the slider using a foreach loop. Finally we return the resulted slider to be displayed inside our pages.

Things to Focus

  • You can use get_post_meta function with specific key to load any kind of details saved in the database.
  • We can pass any number of attributes to shortcode and you have to include them inside the extract function to retrieve the values.
  • Here we are getting image links from database. You can get and save any type of information using the get_post_meta function according to your shortcode type.

Now we have completed our slider plugin for this part and you can try creating sliders with different images. Once created, copy the shortwcode from the list and insert into a post or page to see it in action.

Following image shows the preview of our slider in the TwentyElevan theme.

wpdd_part3_9

Whats Next?

In this part we completed the slider functionality. Now its dynamic and effective to suit various types of sections in your web pages.

What about sizes, effects, speeds of sliders?

Definitely a plugin becomes much more user friendly and customizable when you have options to choose and settings to define it’s features. So in the next part we will be adding options to our slider to complete the initial part of this plugin development series.

By the end of next part you will be able to create basic WordPress plugins for UI components using the techniques discussed here. Until then I hope you will practice these theories with different sliders.

Can You Solve These?

In the previous part I asked you to fix the responsive issues in the slider. In this part I provided more questions to solve and learn. Try the following and let me know how it goes.

  • Can you insert options into slider and use it inside shortcodes?
  • SlidesJS slider does not play automatically. Can you find how it can be set to slide automatically?

Looking forward to your answers.

Wrap Up

In this part I was forced to omit explanations for each and every code line due to the complexity it can cause for you as web designers. Your focus should be on using this code and creating different types of sliders as well as other components without worrying too much about the complex codes.

By now you should be able to insert another type of slider into the same plugin with the instructions I gave on the Things to Focus sections.

Let me know how it goes and any help you need in making different sliders using this plugin.

April 15 2013

13:00

Creating a CSS3 Dropdown Menu – Video Tutorial

We have talked a lot about about HTML5 and CSS3 in the past couple of months and today we continue the series of video tutorials with a new addition: creating a CSS3 dropdown menu from scratch. It is extremely easy to do, so don’t be scared.

The video is a bit longer, around 40 minutes, this is because I have gone into great detail explaining the process. Once you are able to do it on your own, 10-15 minutes should be enough for you to go through the necessary coding and create this dropdown menu.

We used to have to create dropdown menus with JavaScript, but today we only need to use CSS3. CSS3 loads faster than JavaScript, which is one of the many benefits of using CSS3 menus. However, because there is no dropdown function on mobile from a design and usability perspective using a CSS3 dropdown menu would be a mistake.

As promised, you can check out my previous video tutorial about how to create a responsive website using HTML5 and CSS3.

April 08 2013

13:00

Create a Responsive Website Using HTML5 and CSS3 – Video Tutorial

A few weeks ago we released two different introductory articles about HTML5 and CSS3, and I promised you we’d do some cool stuff together in the upcoming months. Well, I have been working hard on this video tutorial and I really hope you enjoy it.

In this tutorial I will teach you how to create a responsive website using HTML5/CSS3 from scratch. So rather than talking about, let’s get straight to it. I hope you will leave me feedback in as I would like to get hear some of your opinions very, very much!

Create a Responsive Website – Video Tutorial

March 22 2013

13:00

Basic Web Design Video Course – Complete HTML Markup & CSS Styles [Part 3]

Sup folks, it’s Mike here again, your design guru and this is the third part of our Basic Web Design Video Course. This time we are going to completely markup the HTML using the tags that we have learned in the previous videos. After that we are going to style it using CSS. Also, we are going to cover CSS reset, Clearfix Hack and new CSS3 properties to solve the most common issues encountered when you are starting to learn web design.

Buckle up and let’s get started.


Part 1: Basic Web Design Video Course – Wireframing, Photoshop Tools & Panels, and Designing
Part 2: Basic Web Design Video Course – Basic HTML Tags, Structure & CSS Properties
Part 3: Basic Web Design Video Course – Complete HTML Markup & CSS Styles

PSD Template Download - HTML/CSS File DownloadDemo


Final Product

1wd-basic-web-design-video-course

Complete HTML Markup

Applying CSS Styles Part 1

Applying CSS Styles Part 2

Finally, we’ve completed the markup and styled our very first layout. Always remember to reset your CSS before styling the whole layout and apply CSS3 box-sizing to all the elements. Also, if you encounter some issues with things like the wrapper and posts just apply the Clearfix Hack.

So, that’s it for this part. I hope you learned something and found the videos helpful. If you have any suggestions regarding the videos and for the next part to be covered feel free to mention it below. Thank you!

March 16 2013

13:00

CSS3 Introduction – New Features, What it Can Do, and Resources

A short time ago I posted an introduction article about HTML5 and I promised you a CSS3 introduction and what new things it brings to the industry, although it’s been some time since it was officially released. If you didn’t read the article on HTML5 yet, I strongly advise you do so, as CSS3 works better with the latest markup language from the World Wide Web Consortium.

CSS2 appeared back in 1998 and since then a lot has happened on the internet. Its only revision was made in 2011, CSS2.1, but experts in the industry say it was only a matter of time until CSS3 should have been released, as the features it comes with are entirely necessary and were missed during the past years. What many people didn’t know about CSS3 was that its development started only one year after the submission of its previous version. So the W3C has been working on this improved version since 1999, for more than 12 years until the first CSS3 stable version was released.

Although it sounds like there is a big difference between CSS2 and CSS3 (which is quite true), all modern browsers were quite quick to adopt the new addition to the W3C family. All major browsers support most CSS3 features that are currently available. As with HTML5, the Consortium still considers CSS3 to be under continuous development and it is very unlikely for it to get a final version, for the same reasons HTML5 will probably not. With the web requirements, and the industry in general, changing so fast, coding needs to move forward at the same pace.

Main differences

Maybe the biggest difference between CSS2 and CSS3 is the separation of modules. While in the previous version everything was a large single specification defining different features, CSS3 is divided into several documents which are called modules. Every single module has new capabilities, without hurting the compatibility of the previous stable release. When we talk about modules, we can name more than fifty of them, however four of these have been published as formal recommendations. The big four is comprised of the following:

  • Media Queries (published in 2012)
  • Namespaces (published in 2011)
  • Selectors Level 3 (published in 2011)
  • Color (published in 2011)

The media queries might well be the most important addition to CSS. What it does is simple: it allows certain conditions to be applied to different stylesheets, making websites fluid and fit all kinds of screen sizes. Media queries allow developers to tailor to different resolutions without having to change or remove content.

media queries

Example of a responsive grid built with media queries

Media queries work very easily and once you have used them once you are pretty much set. Let’s look below at some lines of code.

@media screen and (max-width: 600px) {
    background: #FFF;
}

By starting to style in the media query above, you will only style for screens with a maximum width of 600 pixels. In the example above, all screens with a maximum width of 600 pixels will show you a white background. However, the max-width is not the only condition you can apply to a stylesheet. You can use max-device-width too (which is the screen resolution, unlike max-width which is the viewing area), you can use min instead of max, but you can also combine two conditions, such as in the example below, which will only apply for screens with a viewing area between 600 and 900 pixels.

@media screen and (min-width: 600px) and (max-width: 900px) {
    background: #FFF;
}

CSS3 has some pre-defined stylesheets for portable devices, such as iPhone or iPad, which you can see below:

<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" type="text/css" href="iphone4.css" />

and

<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"/>
<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css"/>

As you can see above, the media queries can come in quite handy when developers need to make fluid grids work on different devices with different screen sizes.

Some other important design considerations of CSS3 are, for example, the borders, which now can be made rounded without hacks. CSS3 has actually introduced rounder borders, which is a huge help for designers and developers. However, many of these features do not work in older versions of Internet Explorer , but this is not something new for us, we’ve heard it before. The only code you need to add in the stylesheet (in the specific class) is something similar to:

-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border: 2px solid #897048;

As you can see, it is much easier than before. Gradients are also available in CSS3, another cool addition that we have wanted to see for some time, as well as box/text shadows and border images. In order to add text shadow to content without any hacks, CSS3 simply requires something similar to the following line of code:

text-shadow: 2px 2px 2px #ddccb5;

Creating columns for content has never been easier than with CSS3, as now you have four lines of code you can use at any time. These are:

  • column-count
  • column-width
  • column-gap
  • column-rule

Another great time saver is the option of inserting multiple background directly from CSS, instead of using all kinds of hacks as we used to do before. The code is simple to write and to remember, and I am sure you will use it at some point in time.

.multiplebackgrounds {
height: 100px;
width: 200px;
padding: 20px;
background: url(top.gif) top right no-repeat,
url(bottom.gif) top left repeat-y,
url(middle.gif) bottom repeat-z;
}

Vendor prefixes

Back when CSS3 was newly released, vendor prefixes were used all the time, as they helped browsers interpret the code. Sometimes you still need to use them today, in case the browser you are testing in doesn’t read the code. So below is a short list with all the vendor prefixes for major browsers:

  • -moz- : Firefox
  • -webkit- : Webkit browsers such as Safari and Chrome
  • -o- : Opera
  • -ms- : Internet Explorer

Note that, according to an official press release from a few weeks ago, Opera will soon build their new desktop and mobile browser on webkit too, instead of their current Presto rendering engine. This means that the -o- vendor prefix will disappear at some point in time, leaving us with only three major ones.

Browser logos

Vendor prefixes are used in order to make CSS3 compatible with all major browsers

New pseudo-classes

The arrival of CSS3 brings us a bunch of new pseudo-classes, including structural ones, that target elements based on their position in the document and relation to different other elements.

  • :only-child – in case you have an element in the document tree that is the only child of its parent, it can be targeted by this pseudo-class.
  • :empty – targets elements that don’t have any children or any text, for example an empty element such as <p></p>.
  • :nth-child(n) – it takes advantage of numeric (n) values and targets child elements in relation to their position within the parent. To give you a precise example, a list of blog comments would probably look more appealing with alternating background colors – this can be done using this pseudo-class.
  • :first-of-type – this targets the first of a specific type of element within a parent, and is the opposite of :last-of-type.
  • :first-child – targets the first child element in a parent, regardless of its type. It is the opposite of :last-child.
  • :not(s) – this one targets elements that are not matched by the specified selector (s).
  • :root – this one targets the root element of a document.

There are more pseudo-classes added to the new CSS3, but as this is basically an article for beginners, it is not really worth mentioning them.

Examples

There are not many examples of CSS3 that I can show you, as it usually is used in collaboration with HTML5 or jQuery. CSS is for styling and enhancement, not for creating applications. Therefore there are only two interesting links I want to share with you.

1. Rotating Multiple Images

rotating multiple images

2. Robot Animation

Robot Animation

Where to learn?

As I advised you in the HTML5 article (and even much more now), CSS3 is impossible to master unless you have prior CSS knowledge. I assume, since you’ve read this article, that you have prior CSS experience, so you just have to build on that. Otherwise you need to take it from the top. In order to ease you into the CSS3 learning process, I will recommend several sources below:

Conclusion

HTML5 and CSS3 are here to stay, and in combination these two tools are very powerful and can create beautiful, high-quality solutions. Therefore you need to learn them and start using them today, otherwise you will fall behind your competitors.

As promised before, I will start working on putting together several HTML5/CSS3 tutorials so that you will be able to learn even more from 1WD. However, until that comes, please make sure you have at least some basic knowledge of HTML5 and CSS3, so that we are all on the same page when we start. See you next time!

August 16 2012

13:00

Create a Stylish Tweet Book with Jquery and CSS

Twitter is a popular social networking service used by millions of users to share text-based content. It has been described as the “SMS of the Internet.” We love to tweet links and ideas we are interested as well as follow other people with similar interests. Everyone loves to follow a lot of people and hence there is a possibility of missing the most important tweets.

So in this tutorial I am going to create a stylish Tweet book to keep your best friends and view their Tweets. As you complete this tutorial you will gain knowledge in working with jQuery and CSS to create a stylish book design. You will also learn to work with the Twitter API using jQuery and AJAX. So let’s get started.

Once you open the demo click on the button with the arrow to open the book. Then click on a letter to load friends. Then click view button to get the recent tweets.

Demo | Download

Structuring Tweet Book Components

Before we start any project we need to plan what we need and how we’re going to do things. So let’s list the layout components of our Tweet Book.

  • Cover Page – This will be the initial book cover with logo, title, letters and open button.
  • Twitter Friends List – This section will have the list of Twitter users and their profile picture inserted into an array.
  • Friends Tweets – This section will have profile information on the left side and tweets on the right side.

Designing Cover Page

This is the section which will be displayed initially. Other then the ‘open book’ button, we don’t have any jQuery or Twitter API related functionality here. So let’s see how to design a book cover using CSS.

<div class='tweet_books'>
    <div  id="startup_page">
       <div class="tb_cover_outer">
            <div class="tb_cover_letters">
               <div class="tb_cover_letter">A</div>
               <div class="tb_cover_letter" style="background: #8791d9;">B</div>
               <div class="tb_cover_letter" style="background: #3bcbd0;">C</div>
               <div class="tb_cover_letter" style="background: #da5c83;">D</div>
           </div>
            <div class="tb_cover_inner">
               <div class="tb_cover_bar"></div>
               <div class="tb_cover_img"><img src="bird.jpg" /></div>
               <div class="tb_cover_title">Tweet Book</div>
                <div class="tb_cover_open"><div class="arrow_left"></div></div>
           </div>
       </div>
   </div>
</div>
  • We create a DIV with the class tweet_books as the main container of the Tweet Book.
  • Then we have 2 DIV elements called tb_cover_outer and tb_cover_inner. This will be the back section of the cover and front section of the cover respectively.
  • You can see that the letter bar has the class tb_cover_letters and is placed between the inner and outer cover. This is because we want to show the letters between the front and back cover like a bookmark.
  • Then we have the Twitter Bird, Title, Open button and shaded bar on the left inside the inner cover.

Following is the necessary styles for the cover page.

<style>
    @font-face {
        font-family: 'HelveticaNeueLT Com 65 Md';
        src: url('fonts/HelveticaNeueLTCom-Md.ttf');
        src: local('fonts/HelveticaNeueLT Com 65 Md'), url('fonts/HelveticaNeueLTCom-Md.ttf') format('truetype');
    }
    body{
        background-image: url('back.jpg');
        font-family: 'HelveticaNeueLT Com 65 Md';
    }
    ul{
        list-style:none;
        font-weight: bold;
    }
    .tweet_books{
        height: 650px;
        margin: 40px auto;
        width: 937px;
    }
    .letter:hover{
	cursor:pointer;
    }
    .tb_cover_close:hover{
        cursor:pointer;
    }
    .tb_cover_open:hover{
        cursor:pointer;
    }
    /* Cover Page
    */
    #startup_page{
        margin: 0px 0 50px 380px;
        position: absolute;
    }
    .tb_cover_outer{
        background-image: url("coverBackground.png");
        border: 1px solid #364258;
        border-radius: 0 5px 5px 0;
        box-shadow: 0 0 1px 2px #525E7B inset, 0 1px 3px #393891 inset;
        height: 620px;
        width: 500px;
    }
    .tb_cover_inner{
        background-image: url("coverBackground.png");
        border: 1px solid #969AA0;
        border-radius: 0 5px 5px 0;
        height: 617px;
        position: relative;
        top: 1px;
        width: 492px;
    }
    .tb_cover_title{
        color: #46536B;
        font-family: 'HelveticaNeueLT Com 65 Md';
        font-size: 50px;
        font-weight: bold;
        margin: 0 auto;
        padding-left: 30px;
        text-shadow: 1px 1px 1px #6E83A3;
        width: 325px;
    }
    .tb_cover_bar{
        background: none repeat scroll 0 0 #5B6C8B;
        border-left: 1px solid #7D94B4;
        border-right: 1px solid #7D94B4;
        box-shadow: 0 0 7px #141313 inset;
        float: left;
        height: 100%;
        margin-left: 20px;
        width: 25px;
    }
    .tb_cover_open{
        background: none repeat scroll 0 0 #323D51;
        border: 1px solid #262525;
        border-radius: 5px 0 0 5px;
        box-shadow: 0 0 1px #B1B1B1 inset;
        height: 50px;
        left: 453px;
        position: absolute;
        top: 275px;
        width: 50px;
    }
    .tb_cover_letter{
        background: none repeat scroll 0 0 #BDDC2F;
        border-radius: 0 3px 3px 0;
        color: #FFFFFF;
        font-family: 'HelveticaNeueLT Com 65 Md';
        font-size: 13px;
        font-weight: bold;
        height: 13px;
        left: 484px;
        margin: 3px 0;
        padding: 3px 3px 3px 2px;
        width: 13px;
        text-align:center;
    }
    .tb_cover_letters{
        float: right;
        left: 6px;
        position: relative;
        margin-top: 10px;
    }
    .tb_cover_img{
        height: 135px;
        margin: 170px auto 10px;
        width: 150px;
    }
    .arrow_right {
        float: left;
        height: 0;
        margin: 12px 15px;
        width: 30px;
        height: 30px;
        background-image: url('sprites.png');
        background-position: -2px -25px;
    }
    .arrow_left {
        background-image: url('sprites.png');
        background-position: -2px -50px;
        float: left;
        width: 30px;
        height: 30px;
        margin: 12px 15px;
    }
</style>

Now I’ll explain the most important properties in the above code from the design perspective.

  • Positioning of the letter bar is important. So I have positioned it relatively to the outer cover. You can change the left and top values for class tb_cover_letters to adjust the letter bar between inner and outer covers.
  • CSS box-shadow property is used to create the shaded bar on the left of the book cover. Adjust the spread distance to get different shades.
  • You can adjust the color and text-shadow of tb_cover_title class to get the text effects on Title.

Once the above section is completed you should have the cover page of the Tweet Book as shown below.

Tweet Book Cover Design

Creating Twitter Friends List

In this section we are going to create the screen to show the list of Twitter friends with their profile images. Once the book is opened we cannot show the list of users since we haven’t clicked on a letter yet. So we have to show a default message to users. Let’s get started on the design.

We are going to position all 3 sections of the Tweet Book one above the other using the same coordinates and keep the other 2 sections hidden. Following is the HTML code for the friends list page and should be inserted after the cover page code.

<div class="book_cover" id="followers_page">
        <div class="book_pages" style="left: 3px; width: 862px;"></div>
        <div class="book_pages" style="left: 5px; width: 858px;"></div>
        <div class="book_pages" style="left: 7px; width: 854px;"></div>
        <div id="followers_page_rows" class="book_pages" style="left: 9px; width: 850px;">
            <div class="page_left">
                <div class="followers_message">Click On a Letter To Load Friends</div>
            </div>
            <div class="page_bind"><span class="top"></span><span class="bottom"></span></div>
            <div class="page_right"></div>
        </div>
    </div>
  • List page is named as followers_page and has a class called book_cover.
  • Then we have 4 DIV elements with the class book_pages. The last DIV will be used to display our content and the first 3 are used to style the book to show that it has more pages.
  • Inside the element with the ID followers_page_rows, we have 3 sections called page_left,page_bind and page_right. page_left and page_right will act as the 2 pages shown on a book when it’s opened. page_bind will contain the effects to show shading and image.
  • Inside the page we provide a message asking the users to click on a letter to start.

Then we need to add the code for letters bar and close button as shown below. This code should be included after the friends list page.

<div class="letters">
        <div class="letter">A</div>
        <div class="letter" style="background: #8791d9;">B</div>
        <div class="letter" style="background: #3bcbd0;">C</div>
        <div class="letter" style="background: #da5c83;">D</div>
    </div>
    <div class="tb_cover_close"><div class="arrow_right"></div></div>

You can find the CSS style for this section under the section Book Pages Styles and Followers Page Styles in the style.css file in project files folder. I am not including the CSS for this section here as its long and contains easy to understand styles.

Initially the letter bar and close button will be hidden. So you should have a something like the following in your demo.

You can see that the book screen is shown and our book cover design is displayed under the book screen. So initially we want to hide the book screen and show book cover. Then once user clicks on open button book cover should be hidden and book screen should be opened. So let’s move onto some jQuery stuff for handling those functionalities.

    $(document).ready(function(){
    	$("#profile_page").hide();
        $("#followers_page").hide();
	$(".tb_cover_open").live("click",function(){
            $("#startup_page").fadeOut("slow");
            $("#followers_page").fadeIn("slow");
            $(".letters").css("display","block");
            $(".tb_cover_close").css("display","block");
        });
    });
  • First we keep the cover page visible and hide the other 2 pages using the jQuery hide function.
  • Next we assign a click event to the open button on the book cover to call a jQuery function.
  • Inside the function we hide the cover page using fadeOut and display the friend list screen using fadeIn.
  • Also we have shown the letters and close button which is hidden initially.

So you should have the following screen once the open button is clicked.

Configuring Friend Details

Now we have to define set of friends to be included in the Tweet Book. I am going to use javascript array to include friends. You can load the friends from database or JSON file by customizing the code.

       var obj = { "Dainis" :"1stwebdesigner",
            "Kim Thoenen" :"KeiAiAm",
            "manish kumar":"ManishDcs",
        };
        $.each(obj, function(key, value) {
            var letter = key.charAt(0);
            letter = letter.toUpperCase();
            if(followers[letter]){
                followers[letter] = followers[letter] + "," + value;
            }else{
                followers[letter] = value;
            }
        });

First we define the list of friends with their name and Twitter username in a js array.You can add any number of names as you wish. Then we loop through the array and assigns each friend to a new array with first letter of the name.

Displaying Friends List

Once the user clicks on a letter we are going to animate the letter and make it move to the left of the page and display the users list for the letter with their profile image. So let’s get started.

I am going to use the $(“.letter”).click(function() for this functionality.Explanation is going to be done step by step using small code parts. You can find the complete $(“.letter”).click(function() function inside the index.html of project files.

	    $("#followers_page").fadeIn("slow");
            $("#profile_page").fadeOut("slow");
            $(".active_letter").animate({
                left: "0px"
            }, 2000 );
            $(".active_letter").removeClass(".active_letter");
            var letter = $(this).html();
            letter = letter.toUpperCase();
            $(this).css("z-index","22");
            $(this).addClass("active_letter");
            $(this).animate({
                left: "-880px"
            }, 1000,function() {$(this).css("z-index","1");} );
  • First we animate the letter on the left back to the letter bar. Initially all the letters will be on the right side.
  • Then we remove the active_letter class from the previous letter.
  • Then we add the active_letter class to the clicked letter and animate it to the left hand side.
  • z-index used to place the letter on top or between the book cover depending on the condition.

Once the above animation is completed we need to load the users list using the code below.

$("#followers_page_rows .page_right").html("");
            $("#followers_page_rows .page_left").html("");
            var letterFollowers = (followers.hasOwnProperty(letter)) ? followers[letter] : '';
            var url = "https://api.twitter.com/1/users/lookup.json?screen_name="+letterFollowers+"&include_entities=true";
            if(letterFollowers != ''){
                $.ajax({
                    url : url,
                    dataType : "jsonp",
                    success : function(data)
                    {
                        var count = 0;
                        $.each(data, function(key, value) {
                            count++;
                            var html = '<div class="followers_row"><div class="followers_profile_image">

                <div class="followers_profile_image_inner"><img src="'+value.profile_image_url+'" /></div></div>

<div class="followers_profile_name">'+value.name+'</div><div class="followers_profile_view" data-followid="'+value.screen_name+'" >view</div></div>

<div class="seperater"></div>';
                            if(count>5){
                                $("#followers_page_rows .page_right").append(html);
                            }else{
                                $("#followers_page_rows .page_left").append(html);
                            }
                        });
                    },
                    error : function()
                    {
                        alert("Failure!");
                    }
                });
            }
  • First we clear any available content on the left and right side of the page.
  • Then we get the Twitter usernames of users for the current letter by using the JavaScript array.
  • We can get information about users by passing Twitter usernames to the following API URL. https://api.twitter.com/1/users/lookup.json
  • Once the AJAX request is successfully completed, we assign the users to left and right pages of book with their profile image and the view profile button.

Now we have completed the first 2 screens of the Tweet Book and it should look like the following image. In the next section we are going to complete the tutorial by creating the profile information and tweets page.

Designing and Loading Tweets

We are going to create a page which contains the profile image, username and description on the left section and tweets on the right section. Let’s get started with the HTML code for the page.

    <div id="profile_page" class="book_cover">
        <div class="book_pages" style="left: 3px; width: 862px;"></div>
        <div class="book_pages" style="left: 5px; width: 858px;"></div>
        <div class="book_pages" style="left: 7px; width: 854px;"></div>
        <div class="book_pages" style="left: 9px; width: 850px;">
            <div class="page_left"></div>
            <div class="page_bind"><span class="top"></span><span class="bottom"></span></div>
            <div class="page_right"></div>
        </div>
    </div>

Above page section will be similar to the followers page with a different ID called profile_page.


Loading Tweets

Once the view button is clicked we call a jQuery function called $(“.followers_profile_view”).live(“click”,function(). I’ll explain the necessary details about the code in the following section.

$(".followers_profile_view").live("click",function(){
            var screenName = $(this).attr("data-followid");
            var url = "https://api.twitter.com/1/users/lookup.json?screen_name="+screenName+"&include_entities=true";
            $.ajax({
                url : url,
                dataType : "jsonp",
                success : function(data)
                {
                    $("#profile_page .page_left").html("");
                    var originalImage = "https://api.twitter.com/1/users/profile_image?screen_name="+data[0].screen_name+"&size=bigger ";
                    var html = '<div class="profile_image"><div class="profile_image_inner"><img src="'+originalImage+'" style="width:73px;height:73px" /></div></div>

            <div class="profile_name">'+data[0].name+'</div><div class="profile_username">@'+data[0].screen_name+'</div>

<div class="profile_desc">'+data[0].description+'</div>';
                    $("#profile_page .page_left").html(html+"<div class='more_tweets' id='back_to_list'>Back</div>");
                    $.ajax({
                        url : "https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=false&screen_name="+data[0].screen_name+"&count=50",
                        dataType : "jsonp",
                        success : function(tweets)
                        {
                            console.log(tweets);
                            console.log(url);
                            $("#followers_page").fadeOut("slow");
                            $("#profile_page").fadeIn("slow");
                            var tweetHTML = '';
                            $("#profile_page .page_right").html("");
                            var keyIndex = 1;
                            var sections = 0;
                            $.each(tweets, function(key, tweetsValue) {
                                tweetsValue.text = replaceURLWithHTMLLinks(tweetsValue.text);
                                if(keyIndex%5 == 1){
                                    sections++;
                                    tweetHTML += "<div class='followers_row_section' id='section"+sections+"' >";
                                    tweetHTML += '<div class="followers_row"><div class="followers_profile_image">

                    <div class="followers_profile_image_inner" >

<img src="'+data[0].profile_image_url+'"></div></div>

<div class="followers_tweet_name">'+data[0].name+'</div><div class="followers_tweet_desc">'+tweetsValue.text+'</div></div><div class="seperater"></div>';
                                }
                                else if(keyIndex%5 == 0){
                                    tweetHTML += '<div class="followers_row"><div class="followers_profile_image">

                    <div class="followers_profile_image_inner">

<img src="'+data[0].profile_image_url+'"></div></div>

<div class="followers_tweet_name">'+data[0].name+'</div><div class="followers_tweet_desc">'+tweetsValue.text+'</div></div><div class="seperater"></div>';
                                    tweetHTML += "<div class='more_tweets' id='more"+sections+"'>More</div>";
                                }
                                else{
                                    tweetHTML += '<div class="followers_row"><div class="followers_profile_image">

                    <div class="followers_profile_image_inner">

<img src="'+data[0].profile_image_url+'"></div></div>

<div class="followers_tweet_name">'+data[0].name+'</div><div class="followers_tweet_desc">'+tweetsValue.text+'</div></div><div class="seperater"></div>';
                                }
                                keyIndex++;
			    });
                            $("#profile_page .page_right").append(tweetHTML);
                            $("#profile_page .page_right .followers_row_section").each(function(){
                                $("#profile_page .page_right").prepend(this);
                            });
                        },
                        error : function()
                        {
                            alert("Failure!");
                        }
                    });
                },
                error : function()
                {
                    alert("Failure!");
                }
            });
        });
  • We have to get the username by using the data-followid attribute in the view button we defined earlier.
  • Next we make the AJAX request to get the information from Twitter as we did earlier. Difference is that we are using only a single username this time.
  • Once data is received we assign the user profile information to the left side of the page.
  • Then we make another AJAX request to Twitter API to get the recent tweets by the given user using https://api.twitter.com/1/statuses/user_timeline.json as the URL.
  • Next we hide the followers list by using fadeOut and display tweet screen with fadeIn functions.
  • Finally we loop through the tweets received and assigns it to the right hand side of the page.

Now you should be able to view the tweet list of the user as shown in the screen below.

Adding Controls

Finally we need to add some controls to do the following tasks.

  • Click More button to load next set of tweets.
  • Click Back button to get to the followers page.
  • Click the close button to close the book and display book cover.

So we need to include the following JavaScript codes to provide above functionality.

       $(".more_tweets").live("click",function(){
            var moreId = $(this).attr("id");
            var slideId = moreId.replace("more","section");
            $("#"+slideId).fadeOut("slow");
        });
	$("#back_to_list").live("click",function(){
            $("#profile_page").fadeOut("slow");
            $("#followers_page").fadeIn("slow");
        });
       $(".tb_cover_close").live("click",function(){
            $("#followers_page").fadeOut("slow");
            $("#profile_page").fadeOut("slow");
            $("#startup_page").fadeIn("slow");
            $(".letters").css("display","none");
            $(".tb_cover_close").css("display","none");
        });

Finally we have a cool Tweet Book which can be used to keep track of the tweets of your best friends. Hope you enjoyed the tutorial and try adding other social media profiles and make it a Social Sharing Book.

August 11 2012

13:00

Create a Minimal Coming Soon Page using HTML5 and CSS3

In this tutorial we are going to create a Coming Soon page using HTML5 and CSS3 with a minimalist style and light colors. We will use the minimal Coming Soon page designed in Photoshop by Stelian a few days ago. If you’ve missed that tutorial be sure to check it out here:

Create a Minimal Coming Soon Page in Adobe Photoshop.

Final Result

Coming Soon Page - Final Result

View Demo | Download Source Files

As you can see, the page contains a lot of gradients and shadows. We will create them using just CSS3. As you may know, CSS3 provides a lot of new properties that let us create cool effects without the need of using images.

For the countdown timer we will use jQuery and the jQuery countdown plugin from tutorialzine.com. Of course we will customize it a bit to match our design.

In this tutorial we will also use some new HTML5 tags (and make them work on Internet Explorer 7 and 8) and some interesting attributes like “placeholder” and “required” for the subscription form. The “placeholder” attribute lets us show text inside the email input field when it’s empty, while the “required” attribute lets us define the email input field as required, so the user cannot submit the form without entering their email. We will also provide a jQuery fallback for these two attributes, for older browsers and for browsers that don’t support them yet.

So, enough talking and let’s begin.

1. The Files’ Structure

Let’s create a new folder and name it “coming-soon-page”. Inside this folder we will have these files and subfolders:

  • index.html – our main HTML file;
  • css- the stylesheets’ folder,
  • js- the folder for our JavaScript files,
    • jquery.countdown.js – the jQuery plugin for the countdown timer,
    • script.js – our custom JavaScript file for initializing the timer, for the other animations and for providing a fallback for the “placeholder” and “required” HTML5 attributes on browsers that don’t support them,
    • modernizr.custom.js – a JavaScript library for detecting if the browser supports the “placeholder” and “required” attributes;
  • images – the images’ folder;
  • fonts – the fonts’ folder, will contain the font that we will use for the timer.

2. The Page’s Structure

Below is the main HTML structure of the index.html file of our page:

<!DOCTYPE html>

<html>

<head>

	<meta charset="utf-8" />

	<title>Minimal Coming Soon Page</title>

	<!-- CSS -->
	<link rel="stylesheet" href="css/reset.css">
	<link rel="stylesheet" href="fonts/stylesheet.css">
	<link rel="stylesheet" href="css/style.css">

	<!--[if lt IE 9]>
		<link rel="stylesheet" href="css/ie.css">
	<![endif]-->

	<!-- IE fix for HTML5 tags -->
	<!--[if lt IE 9]>
		<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->

	<!-- jQuery and Modernizr-->
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
	<script src="js/modernizr.custom.js"></script>

	<!-- Countdown timer and other animations -->
	<script src="js/jquery.countdown.js"></script>
	<script src="js/script.js"></script>

</head>

<body>

	<header>
		<!-- The headline and description of our page -->
	</header>

	<div id="main">
		<div id="links">
			<!-- The main links, support, download, etc. -->
		</div>

		<div id="counter">
			<!-- The countdown timer -->
		</div>

		<form action="" method="get">
			<!-- The subscription form -->
		</form>

		<div class="social-media-arrow">
			<!-- The social media arrow, on the right of the page -->
		</div>

		<footer>
			<!-- The page's footer that will contain the social icons -->
		</footer>
	</div>

</body>

</html>

As you can see, the HTML code is pretty simple and explains itself. In the “head” tag we have imported all the stylesheet and JavaScript files that we need.

You can note the conditional comments where we use the file “ie.css” for Internet Explorer 7 and 8. In this file we will add a few lines for IE 7-8 as you will see below. We also import the JavaScript file “html5.js” for making IE 7 and 8 understand the new HTML5 tags, “header” and “footer”.

The body of our page is also simple. It contains the header, where we will put the headline and the page’s description; and the “main” div where we will put the links, the countdown timer, the subscription form and the footer.

Let’s style the page’s body. We will use mainly the Arial font on our page (except for the timer), and a repeated background pattern (that you will find in the source files):

body {
	background: url(../images/body-pattern.jpg) top left repeat;
	font-family: Arial, Helvetica, sans-serif;
	padding-bottom: 40px;
}

3. The Header

As said above, the header of our page will contain the headline and the description. Here is the HTML code:

<header>
	<h1>We are working our butts off to finish this website</h1>
	<p>Our developer, Michael, is doing his best to finish this website before the counter, but we can’t help him.</p>
</header>

And here is its style:

/* ---- Header ---- */

header {
	width: 720px;
	margin: 80px auto 0 auto;
}

header h1 {
	font-size: 30px;
	font-weight: bold;
	color: #272727;
	text-shadow: 0 1px 0 #fff;
}

header p {
	margin: 20px 0 0 3px;
	font-size: 14px;
	color: #272727;
}

Our page now looks like this:

Coming Soon Page - Header

4. The Main Area

The main area of the page is contained in the “main” div as you can see in the HTML code above. This area will contain the links, the timer, the subscription form, the footer and the social media arrow.

Here is the style of the main area:

/* ---- Main Area ---- */

#main {
	position: relative;
	width: 700px;
	margin: 50px auto 0 auto;
	padding: 20px 0 0 25px;
	background: url(../images/main-content-pattern.jpg) top left repeat;
}

It has a width of 700 pixels, it’s center aligned and has a repeated grid pattern as background. It also has a relative position. We will need this line for giving an absolute position to the social media arrow, as you will see below.

5. The Links

Below you can see the HTML for the links:

<div id="links">
	<div class="home"><a href="">http://1stwebdesigner.com/</a></div>
	<div class="support"><a href="">http://support.1wd.com/</a></div>
	<div class="browser"><a href="">Google Chrome OS. 10.X.23</a></div>
	<div class="books"><a href="">http://1wd.co/e-books/</a></div>
	<div class="download"><a href="">http://1wd.com/download/</a></div>
	<div class="ups"><a href="">UPS Signed Worldwide</a></div>
</div>

And the CSS:

/* ---- Links ---- */

#links {
	width: 700px;
	font-size: 12px;
	font-weight: bold;
	color: #aaa;
	line-height: 18px;
	overflow: hidden;
}

#links a {
	position: relative;
	color: #aaa;
	text-decoration: none;
}

#links a:hover {
	color: #aaa;
	text-decoration: none;
}

.home, .support, .browser, .books, .download, .ups {
	float: left;
	width: 180px;
	margin-left: 42px;
	padding-left: 25px;
}

.home { background: url(../images/home.png) left center no-repeat; margin-left: 0; }
.support { background: url(../images/support.png) left center no-repeat; }
.browser { background: url(../images/browser.png) left center no-repeat; clear: right; }

.books, .download, .ups { margin-top: 10px; }

.books { background: url(../images/books.png) left center no-repeat; margin-left: 0; }
.download { background: url(../images/download.png) left center no-repeat; }
.ups { background: url(../images/ups.png) left center no-repeat; clear: right; }

The links area has a width of 700 pixels and each link has its own icon. Then we play a little bit with margins and padding to make them match the PSD design. We also use a relative position for the links so later we can add a simple animation to them with jQuery.

The page should look like this:

Coming Soon Page - Links

6. The Countdown Timer

For the countdown timer we will be using the jQuery countdown plugin from tutorialzine.com. Our timer will be contained in the “counter” div. Here is the HTML code:

<div id="counter"></div>

The “counter” div will be empty because all the HTML code of the timer will be generated by the jQuery plugin. Here is the HTML code that the plugin will generate:

<div id="counter" class="countdownHolder">

	<div class="countDays">
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="boxName">
			<span class="Days">DAYS</span>
		</span>
	</div>
	<span class="points">:</span>
	<span class="countDiv countDiv0"></span>

	<div class="countHours">
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="boxName">
			<span class="Hours">HRS</span>
		</span>
	</div>
	<span class="points">:</span>
	<span class="countDiv countDiv1"></span>

	<div class="countMinutes">
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="boxName">
			<span class="Minutes">MNTS</span>
		</span>
	</div>
	<span class="points">:</span>
	<span class="countDiv countDiv2"></span>

	<div class="countSeconds">
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="position">
			<span class="digit static">0</span>
		</span>
		<span class="boxName">
			<span class="Seconds">SECS</span>
		</span>
	</div>

</div>

Depending on the time that we set when we initialize the counter, the plugin will show the right numbers on the four boxes (“DAYS”, “HOURS”, “MINUTES”, “SECONDS”) and animate the timer.

Note: I will not explain the plugin in detail here. Martin Angelov, the creator of this plugin, did  a pretty good job on explaining how it works. You can check it out on tutorialzine here.

Now let’s style this counter and make it match our PSD design:

/* ---- Counter ---- */

#counter {
	width: 700px;
	height: 145px;
	margin: 55px auto 0 auto;
	font-family: 'LeagueGothicRegular', Arial, Helvetica, sans-serif;
	font-size: 92px;
	color: #272727;
	text-shadow: 0 1px 0 #fff;
	overflow: hidden;
}

.countDays, .countHours, .countMinutes, .countSeconds {
	float: left;
	width: 102px;
	height: 138px;
	padding-left: 36px;
	background: #e7e7e7;
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.1)), to(rgba(0,0,0,.07)));
	background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.07));
	background-image: -moz-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.07));
	background-image: -ms-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.07));
	background-image: -o-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.07));
	background-image: linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.07));
	border: 1px solid #ccc;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
	border-radius: 4px;
	-moz-box-shadow:
		0 2px 3px 0 rgba(255,255,255,.2) inset,
		0 2px 2px 0 rgba(0,0,0,.1);
	-webkit-box-shadow:
		0 2px 3px 0 rgba(255,255,255,.2) inset,
		0 2px 2px 0 rgba(0,0,0,.1);
	box-shadow:
		0 2px 3px 0 rgba(255,255,255,.2) inset,
		0 2px 2px 0 rgba(0,0,0,.1);
}

.points {
	float: left;
	width: 40px;
	margin: 0;
	font-family: Georgia, serif;
	font-size: 44px;
	font-weight: bold;
	text-align: center;
	line-height: 138px;
	text-shadow: none;
}

.position {
	position: relative;
	float: left;
	width: 35px;
	height: 92px;
	margin: 8px 0 0 0;
}

.digit {
	position: absolute;
	top: 0;
	left: 0;
}

.boxName {
	float: left;
	width: 80px;
	margin: -5px 0 0 7px;
	font-size: 36px;
	color: #a6a6a6;
	text-shadow: 0 1px 0 rgba(255,255,255,.5);
}

.Hours { margin-left: 5px; }
.Seconds { margin-left: 2px; }

Here we have used the “League Gothic” font that you will find in the source files. If you want to use this font on your designs, you can download it here.

As you can see, we have used only CSS3 properties for creating shadows and gradients. These new properties lets us create complex designs without the need of slicing images. This way our pages are very lightweight and we can save a lot of time.

The CSS3 properties used here are: “border-radius”, “box-shadow”, “linear-gradient” and “text-shadow”. You can easily understand what these properties do by just reading their name.

We have also used the “rgba” attribute that is very interesting and convenient because it lets us assign transparent colors to the various CSS properties.

Now we initialize the countdown timer by adding these lines to the “script.js” file (inside the “js” folder):

$(document).ready(function(){

	/* ---- Countdown timer ---- */

	$('#counter').countdown({
		timestamp : (new Date()).getTime() + 51*24*60*60*1000
	});

});

The counter will show the time left to 51 days from now. Our page looks like this:

Coming Soon Page - Countdown Timer

7. The Subscription Form

For the subscription form we will use two new HTML5 attributes, as we mentioned before. These new attributes are “placeholder” and “required”. Here is the HTML code of our form:

<form action="" method="get">
	<input type="text" class="email" placeholder="Input your e-mail address here..." required />
	<input type="submit" class="submit" value="Let me Notified" />
</form>

We have a text input field for collecting the user’s email and a submit button. The text field is required so the user must fill it with an email address before submitting the form. When it’s empty, it shows the text “Input your e-mail address here…”.

Let’s style our form:

/* ---- Subscription Form ---- */

form {
	position: relative;
	margin: 40px auto 0 auto;
}

.email {
	width: 498px;
	height: 35px;
	padding: 0 15px;
	background: #f1f1f1;
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.02)), to(rgba(0,0,0,.02)));
	background-image: -webkit-linear-gradient(top, rgba(255,255,255,.02), rgba(0,0,0,.02));
	background-image: -moz-linear-gradient(top, rgba(255,255,255,.02), rgba(0,0,0,.02));
	background-image: -ms-linear-gradient(top, rgba(255,255,255,.02), rgba(0,0,0,.02));
	background-image: -o-linear-gradient(top, rgba(255,255,255,.02), rgba(0,0,0,.02));
	background-image: linear-gradient(top, rgba(255,255,255,.02), rgba(0,0,0,.02));
	border: 1px solid #cbcbcb;
	-moz-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset;
	-webkit-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset;
	box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
	border-radius: 4px;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 13px;
	color: #b3b2b2;
	font-style: italic;
}

.email:focus {
	outline: 0;
	border: 1px solid #c0c0c0;
	-moz-box-shadow: 0 2px 3px 0 rgba(0,0,0,.2) inset;
	-webkit-box-shadow: 0 2px 3px 0 rgba(0,0,0,.2) inset;
	box-shadow: 0 2px 3px 0 rgba(0,0,0,.2) inset;
}

.submit {
	width: 140px;
	height: 37px;
	margin: 0 0 0 5px;
	padding: 0;
	background: #888;
	background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.1)), to(rgba(0,0,0,.1)));
	background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -moz-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -ms-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -o-linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: linear-gradient(top, rgba(255,255,255,.1), rgba(0,0,0,.1));
	border: 1px solid #636363;
	-moz-box-shadow:
		0 1px 2px 0 rgba(253,252,252,.35) inset,
		0 -1px 2px 0 rgba(0,0,0,.15) inset;
	-webkit-box-shadow:
		0 1px 2px 0 rgba(253,252,252,.35) inset,
		0 -1px 2px 0 rgba(0,0,0,.15) inset;
	box-shadow:
		0 1px 2px 0 rgba(253,252,252,.35) inset,
		0 -1px 2px 0 rgba(0,0,0,.15) inset;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
	border-radius: 4px;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 13px;
	font-weight: bold;
	color: #fff;
	text-shadow: 0 1px 0 rgba(0,0,0,.35);
	line-height: 13px;
	cursor: pointer;
}

.submit:hover {
	background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(255,255,255,.1)), to(rgba(0,0,0,.1)));
	background-image: -webkit-linear-gradient(bottom, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -moz-linear-gradient(bottom, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -ms-linear-gradient(bottom, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: -o-linear-gradient(bottom, rgba(255,255,255,.1), rgba(0,0,0,.1));
	background-image: linear-gradient(bottom, rgba(255,255,255,.1), rgba(0,0,0,.1));
	-moz-box-shadow: 0 1px 2px 0 rgba(0,0,0,.15) inset;
	-webkit-box-shadow: 0 1px 2px 0 rgba(0,0,0,.15) inset;
	box-shadow: 0 1px 2px 0 rgba(0,0,0,.15) inset;
}

.submit:active {
	-moz-box-shadow:
		0 1px 2px 0 rgba(0,0,0,.15) inset,
		0 3px 13px 3px rgba(0,0,0,.3) inset;
	-webkit-box-shadow:
		0 1px 2px 0 rgba(0,0,0,.15) inset,
		0 3px 13px 3px rgba(0,0,0,.3) inset;
	box-shadow:
		0 1px 2px 0 rgba(0,0,0,.15) inset,
		0 3px 13px 3px rgba(0,0,0,.3) inset;
	color: #ddd;
}

We have used the CSS pseudo-classes :hover, :focus and :active for changing the style of the input field and submit button when the user enters his email, hovers over the button or clicks on it.

We have also used the same CSS3 properties that we used for the countdown timer, “border-radius”, “box-shadow”, “linear-gradient” and “text-shadow”.

The page should look like this:

Coming Soon Page - Subscription Form

And here is how the form looks if the user clicks on the submit button while leaving the text field empty:

Coming Soon Page - Empty Field

We defined the text input field as required so the browser doesn’t allow the form to be submitted  if the user leaves the field empty.

These two new HTML5 attributes (“placeholder” and “required”) are very useful and can save us a lot of time, but they aren’t supported by older browsers like Internet Explorer 7 and 8.

For this we will use the Modernizr Javascript library that will let us know if the browser supports the two attributes.

Another problem that we have here appears when we use the Safari browser. Safari doesn’t support the “required” attribute, but Modernizr returns “true” when checking if this feature is supported.

So, we have to check if the browser doesn’t support the new attributes and if the browser is Safari. If so, we have to provide a jQuery fallback for showing the placeholder text and for detecting if the text input field is left empty and show a warning popup if it is.

After including Modernizr (the file “modernizr.custom.js”) in the “head” part of our page, we need to add these lines to the “script.js” file:

/* ---- Using Modernizr to check if the "required" and "placeholder" attributes are supported ---- */

if (!Modernizr.input.placeholder) {
	$('.email').val('Input your e-mail address here...');
	$('.email').focus(function() {
		if($(this).val() == 'Input your e-mail address here...') {
			$(this).val('');
		}
	});
}

// for detecting if the browser is Safari
var browser = navigator.userAgent.toLowerCase();

if(!Modernizr.input.required || (browser.indexOf("safari") != -1 && browser.indexOf("chrome") == -1)) {
	$('form').submit(function() {
		$('.popup').remove();
		if(!$('.email').val() || $('.email').val() == 'Input your e-mail address here...') {
			$('form').append('<p class="popup">Please fill out this field.</p>');
			$('.email').focus();
			return false;
		}
	});
	$('.email').keydown(function() {
		$('.popup').remove();
	});
	$('.email').blur(function() {
		$('.popup').remove();
	});
}

You can note how we added a new paragraph that contains the text “Please fill out this field.” to the form and we assigned to it the class “popup”.

Here is the CSS code for styling the popup and making it appear below the text input field:

.popup {
	position: absolute;
	top: 45px;
	left: 0;
	width: 140px;
	padding: 10px;
	background: #e7e7e7;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
	border-radius: 4px;
	-moz-box-shadow: 0 2px 2px 0 rgba(0,0,0,.1);
	-webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,.1);
	box-shadow: 0 2px 2px 0 rgba(0,0,0,.1);
	font-family: Arial, Helvetica, sans-serif;
	font-size: 13px;
	color: #888;
}

Now, if we open the page on Safari and we click the submit button without entering any text in the input field, the form will look like this:

Coming Soon Page - Safari

8. The Footer

On the footer part of our Coming Soon page we will add some icons that will link to our social media accounts.

Here is the HTML:

<footer>
	<ul>
		<li><a class="digg" href=""></a></li>
		<li><a class="twitter" href=""></a></li>
		<li><a class="vimeo" href=""></a></li>
		<li><a class="skype" href=""></a></li>
	</ul>
</footer>

And the CSS:

/* ---- Footer ---- */

footer {
	width: 700px;
	margin: 0 auto;
	padding: 35px 0 25px 0;
	overflow: hidden;
}

footer ul {
	float: right;
	width: 125px;
	height: 22px;
}

footer ul li {
	float: left;
}

footer a {
	position: relative;
	display: block;
	margin-left: 10px;
}

.digg {
	width: 10px;
	height: 16px;
	background: url(../images/digg.png) center center no-repeat;
}

.twitter {
	width: 21px;
	height: 16px;
	background: url(../images/twitter.png) center center no-repeat;
}

.vimeo {
	width: 16px;
	height: 16px;
	background: url(../images/vimeo.png) center center no-repeat;
}

.skype {
	width: 16px;
	height: 16px;
	background: url(../images/skype.png) center center no-repeat;
}

We will also add a beautiful arrow to give a professional look to the page. For this we will just need an empty div:

<div class="social-media-arrow"></div>

And we will style it like this:

.social-media-arrow {
	position: absolute;
	top: 125px;
	right: -95px;
	width: 108px;
	height: 256px;
	background: url(../images/social-media-arrow.png) top left no-repeat;
}

The page should look like this:

Coming Soon Page - Footer

9. Some jQuery Animations

Now we are going to animate the links and the social icons so that when the user hovers over them they will move slowly. For this we need to add a few lines to the “script.js” file:

/* ---- Animations ---- */

$('#links a').hover(
	function(){ $(this).animate({ left: 3 }, 'fast'); },
	function(){ $(this).animate({ left: 0 }, 'fast'); }
);

$('footer a').hover(
	function(){ $(this).animate({ top: 3 }, 'fast'); },
	function(){ $(this).animate({ top: 0 }, 'fast'); }
);

10. Compatibility with Internet Explorer 7 – 8

Since Internet Explorer 7 and 8 don’t support the new CSS3 properties, the gradients and shadows will not be visible on these browsers, but the page will still be usable. Also, thanks to the jQuery fallback that we have created, the subscription form will work fine.

To end this tutorial we only need to add these three lines to the “ie.css” file:

.email {
	line-height: 35px;
}

This is because on IE 7 and 8 the text in the input field doesn’t align (vertically) in the center.

Conclusion

Finally we did it! We created our Coming Soon page and we’re ready to use it on our site. We used some new CSS3 properties and some new HTML5 tags and attributes that saved us a lot of time and made our page fast and lightweight.

So, what do you think about this tutorial? Did you learn something new? Also, what do you think about these new properties? Will you use them? Or maybe you want to wait until they are better supported by the different browsers?

August 06 2012

13:00

Create a Sliding Navigation Menu with jQuery

Having a sliding navigation menu helps users to find the important pages of your website in a cool way. It is important to keep your navigation menu simple and user-friendly while keeping it attractive.

Consider a situation where you include your blog categories in a navigation menu. If you have a long category list, a drop down navigation menu will exceed the page height and the user might need to scroll to navigate to the last part of the menu. These small things are enough for a user to navigate away from your site.

To solve that, we are going to create a complete navigation menu using jQuery. I will explain how to compress large menus using sliding panels to keep the depth of your menu to a minimum level. Take a look at the demo before we get started. You can see that sub level menu items are hidden initially and displayed as sliding panels on click.

Demo | Download


Creating Main Menu Items

In most navigation menus, main items will be displayed initially and sub items are displayed when you hover on the main menu items. So let’s see how to create main menu items using an Unordered list.

<ul id='header_nav'>
    <li><img src="images/home-icon.png" /></li>
    <li>About Us</li>

    <li>Categories</li>
    <li>Archive</li>
    <li>Contact</li>
    <li>Write For Us ?</li>
</ul>

Styles for main menu items are given below.

.level1{
        background-color: #000000;
        border-radius: 3px 3px 3px 3px;
        color: #FFFFFF;
        display: inline;
        float: left;
        margin: 0 5px;
        padding: 14px 10px;
        position: relative;
        font-family: arial;
        font-size: 13px;
        border-top:1px solid #ababab;
        border-left:1px solid #7e7e7e;
        border-right:1px solid #6f6f6f;;
        font-family: 'HelveticaNeueLT Com 65 Md';
        height:12px;
        background: rgb(158,158,158); /* Old browsers */
        background: -moz-linear-gradient(top,  rgba(158,158,158,1) 0%, rgba(191,191,191,1) 1%, rgba(158,158,158,1) 1%, rgba(130,130,130,1) 3%, rgba(130,130,130,1) 49%, rgba(99,99,99,1) 100%); /* FF3.6+ */
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(158,158,158,1)), color-stop(1%,rgba(191,191,191,1)), color-stop(1%,rgba(158,158,158,1)), color-stop(3%,rgba(130,130,130,1)), color-stop(49%,rgba(130,130,130,1)), color-stop(100%,rgba(99,99,99,1))); /* Chrome,Safari4+ */
        background: -webkit-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* Chrome10+,Safari5.1+ */
        background: -o-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* Opera 11.10+ */
        background: -ms-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* IE10+ */
        background: linear-gradient(to bottom,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e9e9e', endColorstr='#636363',GradientType=0 ); /* IE6-8 */
    }

I have defined a class called level1 for the main menu items. I have used gradient colors for the menu items. Gradient colors can be easily generated and customized using free online gradient generators.

Important thing here is that list items does not have a class called level1. I am assigning the class for each level dynamically using jQuery after the page is loaded. Following is the code for assigning the class to menu items based on the depth.

        $("#header_nav > li ").addClass("level1");
        $("#header_nav  > li > ul > li ").addClass("level2");
        $("#header_nav  > li > ul > li > ul > li ").addClass("level3");
  • First line selects the immediate li items in header_nav element and adds class level1
  • Likewise we can assign classes level2 and level3 to the sub menu items using the above jQuery selector expressions.

Now our menu should look like the following screen.

Initial Menu Screen

Creating Sub Menu Items

Now we have main menu items with the styles applied. Lets see how we can create sub menu items using CSS and HTML. Consider the following code:

<ul id='header_nav'>
    <li><img src="images/home-icon.png" /></li>
    <li>About Us</li>
    <li>Categories
	<ul>
            <li><a>Coding</a></li>
            <li><a>Freebies<span class="arrow-right"></span></a></li>
            <li><a>Tutorial<span class="arrow-right"></span></a></li>
            <li><a>Web Design</a></li>
        </ul>
    </li>
    <li>Archive</li>
    <li>Contact</li>
    <li>Write For Us ?</li>
</ul>
  • We have to create another unordered list inside the main menu item to display the sub menu items. I have created a link inside each sub menu item as shown above.
  • Also you can see span element with the class arrow-right. Freebies and Tutorial items are going to have another sub menu ( sliding menu) items.
  • So whenever you have a sub menu with another sub level, you have to use <span class=”arrow-right”></span> inside the link. This will show a small arrow to indicate that another sub level exists for the given menu.

The following code is used to style the level2 elements.

#header_nav ul{
        position:absolute;
        padding:0;
        left:-1px;
        display:none;
        margin-top: 20px;
        font-family: 'HelveticaNeueLT Com 65 Md';

    }

    .level2 a{
        padding: 14px 10px 10px;
        display: block;
        font-family: 'HelveticaNeueLT Com 65 Md';

    }

    .level2{
        width:150px;
        margin: 0;
        border-radius:0px;
        border-top:1px solid #000;
        font-family: 'HelveticaNeueLT Com 65 Md';
        color: #FFFFFF;
        display: inline;
        float: left;
        font-family: arial;
        font-size: 13px;
        border-left:1px solid #7d7d7d;
        border-right:1px solid #7d7d7d;;
       	background: #afafaf; /* Old browsers */
        background: -moz-linear-gradient(top, #afafaf 0%, #7e7e7e 1%, #7a7a7a 38%, #747474 50%, #6b6b6b 77%, #686868 99%, #757575 100%); /* FF3.6+ */
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#afafaf), color-stop(1%,#7e7e7e), color-stop(38%,#7a7a7a), color-stop(50%,#747474), color-stop(77%,#6b6b6b), color-stop(99%,#686868), color-stop(100%,#757575)); /* Chrome,Safari4+ */
        background: -webkit-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* Chrome10+,Safari5.1+ */
        background: -o-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* Opera 11.10+ */
        background: -ms-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* IE10+ */
        background: linear-gradient(to bottom, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#afafaf', endColorstr='#757575',GradientType=0 ); /* IE6-9 */
    }

.arrow-right {
    border-bottom: 5px solid transparent;
    border-left: 5px solid #FCFCFC;
    border-top: 5px solid transparent;
    float: right;
    height: 0;
    margin-top: 3px;
    width: 0;
    margin-right: 10px;
}
  • Initially, sub menus will be hidden. I have used display:none on #header_nav ul to make them hidden. First change it to display:block to get a quick look at how its positioned.
  • You can see the space between main menu item and sub menu item. I have used margin-top: 20px. The sub menu will overlap with the main menu if we don’t specify a margin. Remove it and see what happens.
  • The next important thing is position:absolute. Main menu items are positioned relatively, so we can position sub menus absolutely compared to the main menus. If you remove this sub menu items will align horizontally as main menu items. So we have to position it absolutely to get the vertical (dropdown) behavior.
  • Also we need to specify width for sub menu items in the level2 class. Otherwise each item will have its own width and will not have a great look. Change it according to your preference. I have defined it as 150px
  • Apart from the above, other styles in level2 class are used to improve the look and feel of sub menus. Now we are done with creating sub menus and change it back to display:none again.

Now our menu should look like the following screen.

Sub Menu Initial Display

Displaying Sub Menus on Hover

Sub menus are hidden initially. So in this section I am going to explain how to show them. In this section we’ll:

  • Display the main menu in different color on hover.
  • Fill the gap between main menu and sub menu on hover.
  • Show the hidden sub menus and hide the other sub menus.

I am going to use jQuery function called $(“.level1″).live(“hover”,function(){}) in this section. This function will be called each time you hover on the level1 menu item. I’ll explain the code inside this function using smaller sections. You can find the complete code inside the project files.

Lets get started.

            $(".level1").removeClass("main_menu_hover");
            $(this).addClass("main_menu_hover");
  • First thing we have to do is highlight the main menu items on hover. I am using a class called main_menu_hover to provide a different color.
  • Initially we remove main_menu_hover class from all the level1 items if it exists. Then we add the class to the hovered menu item using $(this).addClass method.
            var numberofChildren = $(this).find("> ul").children().length;

            if(numberofChildren != 0){
                // Section 1
                $(".level1").removeClass("active_main_menu");
                $(this).addClass("active_main_menu");

                // Section 2
                $(".level1").find("ul").css("display","none");
                $(this).find(" > ul").css("display","block");

                // Section 3
                $(".level2").removeClass("active_first_element");
                $(".level2").removeClass("active_last_element");
                $(".level2").removeClass("active_only_element");

                // Section 4
                if(numberofChildren == 1){
                    $(this).find("ul li:first").addClass("active_only_element");
                }else{
                    $(this).find("ul li:first").addClass("active_first_element");
                    $(this).find("ul li:last-child").addClass("active_last_element");
                }

                // Section 5
                $(".level2 a").removeClass("sub_active");
                $(".level2").removeClass("menu_hover");

            }else{
                // Section 6
                $(".level1").find("ul").css("display","none");
                $(".level1").removeClass("active_main_menu");

            }
  • First we get the number of sub menu items for the currently hovered main menu.
  • If the main menu has sub items, we remove the class active_main_menu and add the class to the currently hovered element using Section 1 code. Initially there will not be any elements with active_main_menu class. Once you hover it will apply to the current item.
  • Apart from identifying the current element, active_main_menu class is used to fill the gap between main menu and sub menu. I’ll provide the CSS for this class in next section.
  • Section 2 – We have to hide all the displayed sub menus before showing the sub menu of current item. Then we display the current sub menu using $(this) element.
  • Section 3 – Code here is used to reset the classes on other elements which will be discussed next.
  • Section 4 – Some menus can have one sub menu and some can have more than one sub menu. So in this section if the menu has only one sub menu, we add the class active_only_element. Otherwise we add class active_first_element to the first item and active_first_element to the last item.
  • Above classes are used to display the first and last sub menu items in different styles than others.
  • Section 5 – This code is used to reset the classes of level2 sub menus once you hover on another main menu.
  • Section 6 – If the main menu does not have any sub menus, we rest the previously used sub menu classes using this code.

Following is the styes for the above section.

.main_menu_hover{
    background: #656565; /* Old browsers */
    background: -moz-linear-gradient(top, #656565 0%, #676767 1%, #696969 38%, #747474 50%, #6c6c6c 77%, #676767 99%, #676767 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#656565), color-stop(1%,#676767), color-stop(38%,#696969), color-stop(50%,#747474), color-stop(77%,#6c6c6c), color-stop(99%,#676767), color-stop(100%,#676767)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* IE10+ */
    background: linear-gradient(to bottom, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#656565', endColorstr='#676767',GradientType=0 ); /* IE6-9 */

}

.active_main_menu{
    height: 35px;
}

.active_first_element{
    border-radius:2px 2px 0 0;
    border-top:1px solid #000;
    background: -moz-linear-gradient(center top , #6C6C6C, #575758) ;
    background: -webkit-gradient(center top , #6C6C6C, #575758) ; /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(center top , #6C6C6C, #575758); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(center top , #6C6C6C, #575758); /* Opera 11.10+ */
    background: -ms-linear-gradient(center top , #6C6C6C, #575758); /* IE10+ */
    background: linear-gradient(center top , #6C6C6C, #575758); /* W3C */

}

.active_last_element{
    border-radius:0 0 2px 2px;
    border-top:1px solid #000;

}
.active_only_element{
    border-top:1px solid #000;
    background: -moz-linear-gradient(center top , #6C6C6C, #575758) ;
    background: -webkit-gradient(center top , #6C6C6C, #575758) ; /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(center top , #6C6C6C, #575758); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(center top , #6C6C6C, #575758); /* Opera 11.10+ */
    background: -ms-linear-gradient(center top , #6C6C6C, #575758); /* IE10+ */
    background: linear-gradient(center top , #6C6C6C, #575758); /* W3C */
    border-radius:2px;
}

Add Hover Effects to Sub Menu

Once you hover on the sub menu items it should be highlighted in order to provide a better outlook. Lets see how to provide highlighting effects on hover.

        $(".level2 > a").live("hover",function(e){
            $("li").removeClass("menu_hover");
            $(this).parent().addClass("menu_hover");
            e.preventDefault();
        });

The code above gets the immediate links of level2 (not links of level3) and removes the menu_hover class from previously applied elements and adds it to the current sub menu item.

.menu_hover{
    background: rgb(255,138,22); /* Old browsers */
    /* IE9 SVG, needs conditional override of 'filter' to 'none' */
    background: -moz-linear-gradient(top,  rgba(255,138,22,1) 0%, rgba(255,179,109,1) 1%, rgba(255,138,22,1) 3%, rgba(232,139,9,1) 40%, rgba(229,110,0,1) 82%, rgba(224,119,0,1) 97%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,138,22,1)), color-stop(1%,rgba(255,179,109,1)), color-stop(3%,rgba(255,138,22,1)), color-stop(40%,rgba(232,139,9,1)), color-stop(82%,rgba(229,110,0,1)), color-stop(97%,rgba(224,119,0,1))); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* IE10+ */
    background: linear-gradient(to bottom,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff8a16', endColorstr='#e07700',GradientType=0 ); /* IE6-8 */

    border-top:1px solid #000;
    padding-bottom: 0px;

}

Now we have both main menus and sub menus working perfectly. It should look like the screen below. Lets see how to create level3 sliding menus.

Sub Menu After Filling Gap

Creating Sliding Menu Panels

This is the most important part of this tutorial as it will hide the long menus and display as sliding panels on hover. This will decrease the size of your menu as well as provide interactivity for the user. Let’s build the sliding menu.

<ul id='header_nav'>
    <li><img src="images/home-icon.png" /></li>
    <li>About Us</li>
    <li>Categories
	<ul>
            <li><a>Coding</a></li>
            <li><a>Freebies<span class="arrow-right"></span></a>
                <ul>
                    <li><a>Icons<span class="items_num">5</span></a></li>
                    <li><a>Templates<span class="items_num">10</span></a></li>
                    <li><a>Fonts<span class="items_num">3</span></a></li>
                </ul>
            </li>
            <li><a>Tutorial<span class="arrow-right"></span></a></li>
            <li><a>Web Design</a></li>
        </ul>
    </li>
    <li>Archive</li>
    <li>Contact</li>
    <li>Write For Us ?</li>
</ul>
  • We have to add another unordered list to get sliding menus. It will be added after the anchor tag as shown in the code above.
  • Inside list items we have a link with the level3 menu text.
  • Also we can use <span class=”items_num”>5</span> in case you want display a number of items inside the level3 menu item. This can be used to define the blog posts inside specific category in a real world scenario.
#header_nav ul ul{
    position: relative;
    left: 0px;
    margin-top: 0;
    display:none;
}

.level3 a{
    padding: 8px 10px;
    display: block;
}
.level3{
    background: #49494A;
    border: none;
    outline: none;
    border-top: 1px solid #000;
    color: #FFFFFF;
    display: inline;
    float: left;
    font-family: arial;
    font-size: 13px;
    width: 150px;
}
  • We have to position level3 items relatively to the level2 items as shown in #header_nav ul ul. Change position, left and margin-top and see what happens.
  • Then we define the styles for level3 menus. Make sure to keep the width as same as the level2 menu.

Sliding menus are hidden initially. Let’s move on to displaying and applying effects on sliding menus.

Display Sliding Menu

         $(".level2 a").live("click",function(){
            $("li").removeClass("menu_hover");

            if($(this).hasClass("sub_active")){
                $(this).removeClass("sub_active");
                $(".level2 > ul").slideUp();
            }else{
                $(".level2 ul").slideUp();
                $(".level2 a").removeClass("sub_active");
                $(this).addClass("sub_active");
                $(this).parent().find("ul").slideDown();
            }
        });
  • Initially we call a function on the click event of anchor tag in level2 element.
  • First we remove the menu_hover class from all the menu items.
  • Then we check whether class sub_active is available in the current level2 menu. This class is used to identify whether to slide the panel up or down. Element with sub_active class means it is displayed currently and we need to hide it by using slideup.
  • If the class already exists, we remove the class and calls the slideup function to hide the menu.
  • If it is not available, we remove the sub_active class from previous elements and adds it to current element. Also we hide previously opened menus and display the current menu using slidedown method.

Following is the styles for above section.

.sub_active{
    background: rgb(255,138,22); /* Old browsers */
    background: -moz-linear-gradient(top,  rgba(255,138,22,1) 0%, rgba(255,179,109,1) 1%, rgba(255,138,22,1) 3%, rgba(232,139,9,1) 40%, rgba(229,110,0,1) 82%, rgba(224,119,0,1) 97%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,138,22,1)), color-stop(1%,rgba(255,179,109,1)), color-stop(3%,rgba(255,138,22,1)), color-stop(40%,rgba(232,139,9,1)), color-stop(82%,rgba(229,110,0,1)), color-stop(97%,rgba(224,119,0,1))); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* IE10+ */
    background: linear-gradient(to bottom,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* W3C */

    border-top:1px solid #ababab;
    padding-bottom: 0px;

}

Let’s take a look at our menu now using the screen below.

Sliding Panel Menu Display

Now we are coming to the final part of the tutorial. We need to apply hover effects to the sliding menu items and format and align the numbers properly. The following code is used to achieve this.

                $(".level3 a").live("hover",function(){
                    if(!($(this).parent().hasClass("accordian_element_hover"))){
                        $(this).parent().removeClass("level3").addClass("accordian_element_hover");
                    }
                });

                $(".accordian_element_hover a").live("hover",function(){
                    $(this).parent().addClass("level3").removeClass("accordian_element_hover");
                });

As we did earlier, we check for the existence of class called accordian_element_hover and add or remove it depending on the status of the element.

.accordian_element_hover{
    background: #2D2D2D;
    width:150px;
    border-top:1px solid #000;
    color: #FFFFFF;
    display: inline;
    float: left;
    font-family: arial;
    font-size: 13px;
}

.accordian_element_hover a{
    padding: 8px 10px;
    display: block;
}

.items_num{
    background: none repeat scroll 0 0 #636363;
    border: 1px solid #000000;
    border-radius: 2px 2px 2px 2px;
    color: #FFFFFF;
    float: right;
    font-size: 11px;
    height: 14px;
    padding: 2px 0;
    position: relative;
    text-align: center;
    top: -2px;
    width: 25px;
}

Finally we have a cool sliding navigation menu using jQuery effects as shown below.

Sliding Panel Menu Hover

Feel free to use it in your projects and provide your suggestions below!

July 19 2012

13:00

How to Create a Multi-Step Form Using RhinoSlider

How do you feel when you see a long Sign Up form for a website or service? Generally, people get bored when the Sign Up form is too long. Ideally, you should keep the form as simple as possible with minimum fields, and if that is not possible, try using a multi-step form.

The reason why Facebook Connect and Sign In with Twitter has become so popular these days is because of their simplicity, since users can sign up just by logging into their Facebook or Twitter account.

If you are using normal Sign Up forms and still require a lot of data from your users, a multi-step form is the best solution. So the form is broken into small sections and the user only sees one section at a time. Also, multi-step forms reduces the space you need on the page.

Multi Step Form Final Layout

In this tutorial I am going to show you how to make a multi-step Sign Up form using Rhinoslider. I think you would prefer seeing the demo first.

Demo Download

Why Use RhinoSlider

In a multi-step form, once you complete the first step, the second step will be displayed and Step 1 will be hidden. Normally we use sliding effects in step transitions. So this a scenario where we can use a Slider differently from its default behavior of creating image slideshows.

There are plenty of great sliders available and no point of reinventing the wheel by creating a slider from scratch. So I chose Rhinoslider for this tutorial as it provides great effects and is very easy to customize. So let’s get started on making a multi-step form.

Introduction to Rhinoslider

Before we create the multi-step form, you should have a basic idea of how RhinoSlider works. They recommend you to generate a custom version instead of full version with all the effects. So I have downloaded the default version for our tutorial.

You can open the demo file in the browser and it will look something like the following screen.

Rhino Slider Demo

So let’s look at the demo file code first.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Multi Step Form with Rhinoslider 1.05</title>
		<link type="text/css" rel="stylesheet" href="css/rhinoslider-1.05.css" />
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript" src="js/rhinoslider-1.05.min.js"></script>
		<script type="text/javascript" src="js/mousewheel.js"></script>
		<script type="text/javascript" src="js/easing.js"></script>
		<script type="text/javascript">
			$(document).ready(function(){
				$('#slider').rhinoslider();
			});
		</script>
		<style type="text/css">
			body { background-color:#000; }

			#slider {
				width:600px;
				height:250px;

				/*IE bugfix*/
				padding:0;
				margin:0;
			}

			#slider li { list-style:none; }

			#page {
				width:600px;
				margin:50px auto;
			}
		</style>
	</head>
	<body>
		<div id="page">
			<ul id="slider">
				<li><img src="img/slider/01.jpg" alt="" /></li>
				<li><img src="img/slider/02.jpg" alt="" /></li>
				<li><img src="img/slider/03.jpg" alt="" /></li>
				<li><img src="img/slider/04.jpg" alt="" /></li>
				<li><img src="img/slider/05.jpg" alt="" /></li>
			</ul>
		</div>
	</body>
</html>
  • You can see that 5 images are placed in the unordered list called #slider.
  • Once you initialize Rhinoslider with $(‘#slider’).rhinoslider() , all the images will be assigned to slider and will slide automatically.

Now we have a basic idea of how to use Rhinoslider. So Lets get started on creating multi-step form.

Creating the Multi-Step Form

We need to do some modifications in initializing the code to suit our multi-step form creation process. Consider the modified initialization code below.

                $('#slider').rhinoslider({
                    controlsPlayPause: false,
                    showControls: 'always',
                    showBullets: 'always',
		    controlsMousewheel: false,
		    prevText: 'Back',
                    slidePrevDirection: 'toRight',
		    slideNextDirection: 'toLeft'
                });
  • In the image slider top button is used to control automatic play and pause. We don’t need it in a multi step form. So we remove it by setting controlsPlayPause: false .
  • The controls and numbering on the slider are shown on hover by default. We make it permanent by setting showControls: ‘always’ and showBullets: ‘always’.
  • Slider moves on mousewheel by default. So we disable it by setting controlsMousewheel: false
  • Finally we change the previous button text to Back.

Creating Form Elements for Steps

Instead of images we want sections of form elements. So in this demo I created a simple registration form with 3 steps called PERSONAL DETAILS, ACCOUNT DETAILS and CONTACT DETAILS. Each section will have some form elements. I am going to replace the unordered list of images with my form elements as shown below.

<div id="wrapper">
        <h3>Account Registration</h3>

            <form action="" >

                <div id="slider">
                    <div class="form-step" >

                        <div class="row">
                            <div class="form-left">First Name *</div>
                            <div class="form-right"><input type="text" id="fname" name="fname" class="form-input" /></div>
                            <div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Last Name *</div>
                            <div class="form-right"><input type="text" id="lname" name="lname" class="form-input" /></div>
                            <div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Gender *</div>
                            <div class="form-right">
                                <select id="gender" name="gender">
                                    <option value="0">Select</option>
                                    <option value="M">Male</option>
                                    <option value="F">Female</option>
                                </select>
                            </div>
                            <div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Address</div>
                            <div class="form-right"><input type="text" id="address" name="address" class="form-input" /></div>
                            <div class="form-error"></div>
                        </div>

                    </div>
                    <div class="form-step" >
                        <div class="row">
                            <div class="form-left">Username *</div>
                            <div class="form-right"><input type="text" id="username" name="username" class="form-input" /></div>
<div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Password *</div>
                            <div class="form-right"><input type="text" id="pass" name="pass" class="form-input" /></div>
<div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Confirm Password *</div>
                            <div class="form-right"><input type="text" id="cpass" name="cpass" class="form-input" /></div>
<div class="form-error"></div>
                        </div>
                    </div>
                    <div class="form-step" >
                        <div class="row">
                            <div class="form-left">Email *</div>
                            <div class="form-right"><input type="text" id="email" name="email" class="form-input" /></div>
<div class="form-error"></div>
                        </div>
                        <div class="row">
                            <div class="form-left">Mobile No</div>
                            <div class="form-right"><input type="text" id="mobile" name="mobile" class="form-input" /></div>
<div class="form-error"></div>
                        </div>
                    </div>
                </div>
            </form>
        </div>
  • First I have added a div called wrapper and a heading called Account Registration.
  • Then I have replaced the ul with a div called #slider.
  • Next I have replaced the list items of images with divs with the class “form-step”.
  • Then necessary input fields for each section are added accordingly.
  • Once the slider is initialized divs with the class containing form-step will turn into a slide.

Now copy the images in the project folder to your demo folder and include the following CSS styles in the demo file.

<style type='text/css'>
        body { background-color:#fff; }
        #wrapper{
            border: 1px solid #DCDADA;
            border-radius: 5px 5px 5px 5px;
            box-shadow: 2px 2px 2px #E1E1E1;
            background: #fff;
            width:700px;
            height:480px;
            background:#f4f4f4;

        }
        #wrapper h3{
            font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
            font-size:16px;
            height:60px;
            background:url(img/title.png) no-repeat left top;
            margin:0;
            padding:16px 0 0 20px;
            text-shadow: 1px 1px 2px #000;
            filter: dropshadow(color=#000, offx=1, offy=1);
            color:#fff;
        }
        #slider {

            background: #fff;
            /*IE bugfix*/
            padding:0;
            margin:0;
            width:700px;
            height:400px;

        }

        #slider li { list-style:none; }

        #page {
            width:600px;
            margin:50px auto;
        }

        #slider{
            color: #000;
            background:#f4f4f4;
            font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
            font-size:12px;
        }

        .form-step{

            padding:16% 3% !important;

        }

        .form-submit{
            cursor: pointer;
            display: block;
            position: absolute;
            right: 0;
            bottom: 0;
            -moz-user-select: none;
            background: none repeat scroll 0 0 #6F95DC;
            border-radius: 5px 5px 5px 5px;
            color: #FFFFFF;
            display: block;
            margin: 0 20px 20px;
            padding: 10px;
            text-align: center;
            width: 125px;
            z-index: 10;
            font-weight: bold;
            text-decoration: none;
            background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#94b9e9), to(#4870d2));
            background-image: -moz-linear-gradient(#94b9e9, #4870d2);
            background-image: -webkit-linear-gradient(#94b9e9, #4870d2);
            background-image: -o-linear-gradient(#94b9e9, #4870d2);
            filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#94b9e9, endColorstr=#4870d2)";
            -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#94b9e9, endColorstr=#4870d2)";
            font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;

        }

        .errorDisplay{
            border:2px solid red;
        }

        .form-left{
            color: #717171;
            float: left;
            font-size: 13px;
            font-weight: bold;
            padding: 5px;
            width: 200px;
        }
        .form-right{
            float: left;
            width: 214px;
        }
        .row{
            float: left;
            margin: 5px 0;
            width: 100%;
        }
        .form-step input[type='text']{
            border: 1px solid #CFCFCF;
            border-radius: 4px 4px 4px 4px;
            height: 25px;
            padding: 3px;
            width: 200px;
        }
        select{
            border-radius: 4px;
            border: 1px solid #CFCFCF;
            -webkit-border-radius: 4px;
            -moz-border-radius: 4px;
            background: #FFF;
            padding: 2px;
            height: 30px;
            width:205px;
            font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
            font-size:12px;
            background:#f4f4f4;
        }

        select option{
            font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
            font-size:12px;
            background:#f4f4f4;
            color:#717171;
        }

        .form-error{
            color: red;
            font-size: 12px;
            padding: 8px;
        }

        .step-error{
            background:#f5715f !important;
            color:#FFF !important;
            -moz-box-shadow:1px 1px 4px #C6C4C4
                -webkit-box-shadow:1px 1px 4px #C6C4C4
                box-shadow:1px 1px 4px #C6C4C4
        }
        .step-success{
            background:#72e487 !important;
            color:#FFF !important;
            -moz-box-shadow:1px 1px 1px 4px #C6C4C4
                -webkit-box-shadow:1px 1px 1px 4px #C6C4C4
                box-shadow:1px 1px 1px 4px #C6C4C4
        }
        .bullet-desc{
            font-size: 14px;
            font-weight: bold;
        }
    </style>

Now the slider will look something like the image below:

Multi Step Form Layout 1

So let’s compare it with our final output screen.

  • Left button should be changed to Back
  • Right button should be changed to Proceed
  • Numbering menu should change to steps on the top bar

Converting Rhinoslider Icons to Buttons

First we have to make sure that we remove the default icons displayed for previous and next buttons and insert buttons for back and proceed. Open the CSS file in the Rhinoslider CSS folder and change the styles for rhino-btn as follows.

.rhino-btn {
    cursor: pointer;
    display: block;
    position: absolute;
    right: 0;
    bottom: 0;
    -moz-user-select: none;
    background: none repeat scroll 0 0 #6F95DC;
    border-radius: 5px 5px 5px 5px;
    color: #FFFFFF;
    display: block;
    margin: 0 20px 20px;
    padding: 10px;
    text-align: center;
    width: 125px;
    z-index: 10;
    font-weight: bold;
    text-decoration: none;
    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#94b9e9), to(#4870d2));
    background-image: -moz-linear-gradient(#94b9e9, #4870d2);
    background-image: -webkit-linear-gradient(#94b9e9, #4870d2);
    background-image: -o-linear-gradient(#94b9e9, #4870d2);
    filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#94b9e9, endColorstr=#4870d2)";
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#94b9e9, endColorstr=#4870d2)";
    font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
}

Take a look at the updated form below.

Multi Step Form Layout 2

Converting Numbered Menu Into Step Menu

We need to change the CSS styles related to the numbering menu in order to get it to the top part and make custom steps instead of just numbers. So update the styles of Rhinoslider CSS file with the following code:

.rhino-bullets li a.rhino-bullet {
    display: block;
    width: 100%;
    height: 90px;
    cursor: pointer;
    background: none repeat scroll 0 0 #F8FDFF;
    border: 1px solid #EEEEEE;
    font-size: 10px;
    text-align: center;
    padding: 10px 0 5px 0;
    color: #000;
    text-decoration:none;
    -webkit-user-select:none;
    -moz-user-select:none;
    user-select:none;
    font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
    font-size:13px;
}
.rhino-bullets {
    position: relative;
    top: -438px;
    z-index: 10;
    background: #fff;
    padding:0;
    float:left;
}

.rhino-bullets:before, .rhino-bullets:after {
    position:absolute;
    display:block;
    left:-16px;
    content:' ';
    width:16px;
    height:26px;

}

.rhino-bullets li {
    float:left;
    display:inline;
    margin:0;
    width: 233px;
}

.rhino-bullets li a.rhino-bullet.rhino-active-bullet {
    color:#000;
    background:#fff;
    border-bottom: none;
}

Now the CSS changes are completed and our screen will look like this:

Multi Step Form Layout 3

Adding Step Descriptions

Instead of using numbers for steps we planned to use descriptive text about the step with an image. So add the following code right after the initialization part of slider.

              var info = ["PERSONAL DETAILS","ACCOUNT DETAILS","CONTACT DETAILS"];
		var images = ["personal-details-icon.png","account-details.png","contact-details.png"];

                $('.rhino-bullet').each(function(index){
                    var link_text = $(this).html();
		    var description = $("#rhino-item"+(link_text-1)).attr("data");

                    $(this).html('<p style="margin: 0pt; font-size: 13px; font-weight: bold;"><img src="./img/'+images[index]+'"></p><p class="bullet-desc">'+info[index]+'</p></a>');
                });
  • We got 2 arrays for images and descriptions. Insert the text and images in the order of your steps.
  • Each step has a class called rhino-bullet. So while looping through each step we replace the number with the image and text from the array.

Here is our form after the text and image integration.

Multi Step Form Layout 4

Adjusting Control Buttons

In the slider we saw the previous and next buttons for each slide. But for multi-step form we don’t need a previous button in first step. So let’s see how we can remove that.

              $(".rhino-prev").hide();
                $('.rhino-next').after('<a class="form-submit" href="javascript:void(0);" >Proceed</a>');
                $(".rhino-next").hide();
  • When the page is loaded, active slide will always be the first section. So we hide the Back button by using $(“.rhino-prev”).hide().
  • Then before we go into the next step we need to validate the form. So we hide the default next button of Rhinoslider and insert the Proceed button as shown above.

Validating Form Steps

Generally we have to complete a step before we go to the next step in a multi-step form. In this section I’ll explain how to add validation to each step.

        $('.form-submit').live("click",function(){

                $('.form-error').html("");

                var current_tab = $('#slider').find('.rhino-active').attr("id");

                switch(current_tab){
                    case 'rhino-item0':
                        step1_validation();
                        break;
                    case 'rhino-item1':
                        step2_validation();
                        break;
                    case 'rhino-item2':
                        step3_validation();
                        break;
                }
            });

            var step1_validation = function(){

                var err = 0;

                if($('#fname').val() == ''){
                    $('#fname').parent().parent().find('.form-error').html("First Name is Required");
                    err++;
                }
                if($('#lname').val() == ''){
                    $('#lname').parent().parent().find('.form-error').html("Last Name is Required");
                    err++;
                }
                if($('#gender').val() == '0'){
                    $('#gender').parent().parent().find('.form-error').html("Please Select Gender");
                    err++;
                }
                if(err == 0){
                    $(".rhino-active-bullet").removeClass("step-error").addClass("step-success");
                    $(".rhino-next").show();
                    $('.form-submit').hide();
                    $('.rhino-next').trigger('click');
                }else{
                    $(".rhino-active-bullet").removeClass("step-success").addClass("step-error");
                }

            };
  • Our Proceed button has a class called form-submit. So every time we click on the proceed button the above validation function is called.
  • You can find the current tab using rhino-active class. Then based on the step you call a custom validation function.
  • I have shown the necessary validations for step 1 in the above code. Validations for the other two steps can be found in the project files.
  • If validation error is found, we display the errors in front of the field and make the highlight the step in red color by adding step-error class to active step.
  • If there are no errors, we make the step green by adding class step-success.
  • Then we hide our custom proceed button and display the default next button of Rhinoslider.
  • Then we make the next button click automatically by using $(‘.rhino-next’).trigger(‘click’) function which will move the form to the next step.

Following screens shows the form on validation errors and validation success.

Multi Step Form Layout 5

Customizing Rhinoslider Plugin

Now we are coming to the final part of the tutorial. We need to make some changes to the default Rhinoslider functionality to get things done as we need. You can click on the steps and move to the other steps in the demo we have now. So let’s see how we can disable it.

Disable Click Event for Steps

Open the rhinoslider-1.05.min.js file in the js folder and comment the following code section which provides the clickable functionality.

vars.buttons.bullets.click(function(){
        var itemID=$(this).attr('id').replace('-bullet','');
        var $next=vars.container.find('#'+itemID);
        var curID=parseInt(vars.navigation.find('.'+vars.prefix+'active-bullet').attr('id').replace('-bullet','').replace(vars.prefix+'item',''),10);
        var nextID=parseInt(itemID.replace(vars.prefix+'item',''),10);
        if(curID&lt;nextID){
            next($slider,settings,$next);
        }else if(curID&gt;nextID){
            prev($slider,settings,$next);
        }else{
            return false;
        }
        if(settings.autoPlay){
            pause();
        }
    });

Customizing Previous Button Functionality

I have made the previous button hidden in the initial step. Now we need to show it in other steps. So let’s customize the Rhinoslider previous button functionality to meet our requirements.

            vars.buttons.prev.click(function(){

                prev($slider,settings);
                if(settings.autoPlay){
                    pause();
                }
            });

The code above shows the default functionality of previous function. So let’s change it to the following.

          vars.buttons.prev.click(function(){
                    $(".rhino-next").hide();
                    $('.form-submit').show();
                    $('.form-submit').html("Proceed");

                    if(($slider.find('.rhino-active').index()) != 0){

                        prev($slider,settings);
                    }
                    if($slider.find('.rhino-active').index() == 1){
                        $(".rhino-prev").hide();
                    }

                    if(settings.autoPlay){
                        pause();
                    }
                });
  • Each time you click the previous button, by default the next button will be loaded. So we have to manually hide it and show our custom form submit button first.
  • Line $slider.find(‘.rhino-active’).index() will give you the index of the active step.
  • If step 1 becomes active, we hide the previous button. Otherwise we call the default previous button functionality by calling prev($slider,settings) .

Customizing Next Button Functionality

Also we need to customize the Rhinoslider next button functionality to meet our requirements. Let’s see how it works.

       vars.buttons.next.click(function(){
            next($slider,settings);
            if(settings.autoPlay){
                pause();
            }
        });

Above code shows the default functionality of previous function. So let’s change it to the following.

           vars.buttons.next.click(function(){
                    $(".rhino-next").hide();
                    $('.form-submit').show();
                    $(".rhino-prev").show();

                    if($slider.find('.rhino-active').index() != ($slider.find('.rhino-item').length -1)){
                        next($slider,settings);
                    }
                    if($slider.find('.rhino-active').index() == ($slider.find('.rhino-item').length -2)){
                        $('.form-submit').html("Submit");

                    }

                    if(settings.autoPlay){
                        pause();
                    }
                });
  • We need to hide the next button and display our custom form submit button on each next button click as we did earlier with previous button.
  • Also we need to show the previous button(Back button).
  • Then we display Submit as the button text if the form is on the final step.
  • If the active step is not the final one, we need to call next($slider,settings) to slide to next step.

We have completed the multi-step form creation process using Rhinoslider. Now you should have something similar to the provided demo. I suggest you download Rhinoslider and follow the tutorial steps to create the form instead of just looking at the project files. Finally compare your version with the demo version and make the necessary changes.

Customizing Multi-Step Form

Now we have a 3 step form. Its easy to add or remove steps according to your needs. Use the following guidelines for customizations.

  • Add or remove step descriptions from info array.
  • Add or remove step images from images array.
  • Add or remove validation functions for steps.
  • Adjust the width of rhino-bullets li class to match your needs.

Conclusion

It will take you around 2 hours to get used to Rhinoslider and create this Multi-Step form. But I think it’s worth doing it since you will have a form which can be used any time you require a multi-step form. You can add or remove steps as you wish.

In real-life projects you will not have the time to do everything from scratch. So tools such as this are useful to learn as you might need to customize existing plugins.

Some people like to do things from scratch, some like to just copy and paste the code and some like to learn the code before using it in projects. Let me know your preferences in the comments section since I am going to use your suggestions for my future tutorials.

July 17 2012

13:00

How to Create a Responsive Website in About 15 Minutes

The buzz around responsive websites has been going on for several months now, and a lot of websites are already responsive, or underway. You know what that means? Today I will teach you how to create a responsive website.

If you follow 1WD on Facebook or Twitter, then you already know that we’re already preparing for an explosive design, which includes being responsive. Watch out for it!

  • Tutorial Level: Beginner
  • Skills Required: Basic knowledge in HTML and CSS
  • Completion Time: Approximately 15 minutes
  • Warning: this tutorial is targeted towards beginners, but it can also be for designers and developers who want to have fun!

By the end of this quick tutorial about responsive design, you will already be on your way to web stardom, and by that I mean you’ll be ready to convert and create responsive websites!

Are you ready? Show me your war faces! Roaaar!

Preparing for the Responsive Website Tutorial

I promised that it will only take about 15 minutes to create a responsive website, and I will hold true to my words. Only, we shall start slow and small. We will start by creating a simple single-page website. Cool? Okay!

Frameworks you can use:

What is Responsive Design?

If you are fairly new to the term, then we have the perfect reading materials for you!

Our Goal

By the end of this tutorial you will end up with something similar to the page above. It is a very plain design, but it will do the trick for now. It is fairly easy to clone the image as seen above, but the main goal here is to make it responsive. To make the website respond based on the size of your device’s screen size.

Try opening the demo on your smartphone and you will see this:

This is what Foundation can do along with several other frameworks that focuses on making websites responsive for mobile devices.

You will find all the files, including the images, in the download link below.



Before moving on, download Foundation and unzip it to a folder where all of your files for this tutorial will be located. It should look like this:

Open index.html and see several elements blasted in one page as a demo. We won’t use everything you will see in it, but you can learn a lot from it. Now, delete it or move it somewhere else so that we can start from scratch.

Our Goal:

Our goal is to create a webpage which has the basic areas of a website: header, body, sidebar, and footer. Of course everything will be responsive, from images down to text and elements placement.

Step 1: Understanding the Foundation

Okay, it is already a given that we will use the structure above, but how will we translate that to HTML? Easy!

First, you need to understand a few things about Foundation and how layouting works. It uses 12 columns to define the width of each “section” which is derived from foundation.css’ width of 1000px. So, if we write:

<div class="row">
    <div class="twelve columns">
    </div>
</div>

The above code would mean that in this certain row, you will occupy twelve columns with the width of 1000px. While on the code below:

<div class="row">
     <div class="twelve columns">
         <div class="six columns">
         </div>
         <div class="six columns">
         </div>
     </div>
</div>

We placed two “six columns” inside of “twelve columns”, this would mean that “six columns” will occupy 50% of the width of “twelve columns”.  The same is true for other number of columns:

<div class="row">
     <div class="twelve columns">
         <div class="row">
         <div class="seven columns">
              <div class="row">
                   <div class="twelve columns">
                   </div>
              </div>
         </div>
         <div class="five columns">
         </div>
     </div>
</div>

For “seven columns” we placed another row inside which occupies “twelve columns”. This means that “twelve columns” will take the maximum width of “seven columns” and divide it into “twelve columns”. It’s a nest of rows and columns, which is important for our goal layout. Now that rows and columns, and nested columns, have been explained, let’s move on to the main show.

Step 2: Laying Out the Foundation

Using your favorite text editor, create a file named index.html then add the following at the very beginning of the file:


<!-- Rean's note: if you're wondering what are these items below, you should follow the link below -->
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!-->  <!--<![endif]-->

  <!-- Set the viewport width to device width for mobile -->

  Welcome to Foundation

  <!-- Included CSS Files -->

  <!--[if lt IE 9]>
    			<link rel="stylesheet" href="stylesheets/ie.css">
  <![endif]--><script type="text/javascript" src="javascripts/modernizr.foundation.js"></script>

  <!-- IE Fix for HTML5 Tags -->
  <!--[if lt IE 9]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->

The above code is where we deal with the evil of Internet Explorer. It is also where we call on to different stylesheets which are necessary to make the whole thing responsive and run on mobile devices. It comes with Foundation. Then type the following code:

<div class="row">
      <div class="twelve columns">
           <h2>Header Twelve Columns</h2>
      </div>
</div>
<div class="row">
      <div class="twelve columns">
           <div class="row">
              <div class="seven columns">
                  <h3>Body Seven Columns</h3>
             </div>
               <div class="five columns">
                  <h3>Sidebar Five Columns</h3>
              </div>
           </div>
      </div>
</div>
<div class="row">
      <div class="twelve columns">
          <h2>Footer Twelve Columns</h2>
      </div>
</div>

I have already explained what these “rows” and “twelve columns” are above.

Tip: if it’s not clear to you why we should wrap the sidebar and body with “twelve columns” you can try removing it and see what happens!

By now it should look like this:

We haven’t added stylings yet, but you can already see how it jives with our goal. I’m not much of a designer but I will do my best to make this look amazing.

Wait, wait, wait! What’s that navigation bar, you ask? As I have mentioned earlier, this is one of the beauties of Foundation. It has an extensive documentation that will teach you how to properly use forms, navigations, buttons, grids, CSS, and other elements covered by Foundation.

Everything is basically done now, all we need to do is add some images and paragraphs and design the whole thing. If you followed this tutorial, then by now you have already created your first responsive web page!

Step 3: Adding Content

This step is needed to actually see how the webpage will look like in its full glory. Copy some Lorem Ipsum and paste it on your “body” div, then insert images using <img> tag and then you’re on your way to becoming a superstart with this!

If you’ll go back and check the demo, you might notice that the background isn’t exactly white, but with a subtle pattern. Choose one on SubtlePatterns and see for yourself which works best.

Step 4: There is no Step 4

Well, actually there is a step 4. The next thing you need to do is study the files you downloaded and start creating your own responsive web page from scratch. There are a lot of other tools you can use aside from Foundation, but the idea is basically the same. Don’t forget to check the documentation!

What do you think about this tutorial? This is my first time writing one, and it may appear messy to experts, but comments and suggestions are always welcome so that we can all improve, right? Start typing now!

July 14 2012

13:00

How to Build a Website Using Twitter Bootstrap and SASS – Part 2

This is the second part of my tutorial on How to Build a Website Using Twitter Bootstrap and SASS where we shall be customizing the Twitter Bootstrap-based web page using SASS. Just to set the context right, we will be starting out where we left off in the previous tutorial. If you haven’t seen it yet, please check it out and work through it. There you will learn how to setup your system for TBS, Ruby, and Compass.

In this tutorial we will be furnishing our webpage from the last tutorial using SASS. By the end of this tutorial you will be at the next level of developing beautiful websites and applications!

What we’ll be creating

Step 1: Creating a custom SASS file

Lets remember that we are using the same file set which we used in the first part of this tutorial. Also, please make sure all the setup guidelines are being followed. Primarily, the Compass compiler should be watching our entire folder to make sure all the changes in the SASS files are being converted to the relevant CSS file.

We can customize the above page in multiple ways:

  • We can edit the bootstrap native rules right away, making changes to ‘bootstrap.css’ according to our design
  • We can override the bootstrap rules using another stylesheet

The latter is always preferable (we discussed in the first part of the tutorial, that it’s always recommended to use a separate stylesheet file to override rules of any plugins or frameworks), because when it comes to multiple theming of the page, we just have to change the custom CSS file to another one in order to apply different skins to the layout. So lets create a SASS file (extension of a sass file is .scss) and place it in the ‘sass’ folder. Since the page talks about 1stwebdesigner, I’m naming it  ’1wd.scss’, and including it in the HTML. Also make sure you are including it after the line which includes all bootstrap styles. Our folder structure now looks like:

Step 2: Overriding the rules, using a mother hook

As a first step towards customization I always prefer adding a mother class to the body tag of the page, so that I can always group all the custom rules by referring to that class. So, lets start by giving the body tag of our HTML page a class – ‘fwd’. This helps us to maintain a first level of grouping in terms of selectors and makes sure we don’t override the bootstrap selectors directly.

Step 3: Customizing the layout

We will also be using a pinch of CSS3 in our styles. So lets include the CSS3 mixins in our .scss files so that we can make use of most of the CSS3 features easily using a single line of code.

Lets start with the header.

Here is a comparison of our current header and the customized one:

The key changes that we’ll be doing here are:

  1. Changing the main navigation items to
    • Coding
    • Freebies
    • Inspiration
    • Tutorials
    • Web Design
    • WordPress
  2. Insert the 1WD logo.
    The container ‘brand’ which contains the text ‘Project name’ should be styled in order to contain the logo. Lets add the logo image as a bg and hide the text using ‘text-indent’ and give a relevant height and width and a margin-top of 5px to position it uniformly vertically. The customized style for brand will now look like:
    .brand{
     text-indent:-999px;
     width:169px;
     height:26px;
     padding:0;
     margin:5px 0 0 0;
     background:url(http://cdn1.1stwebdesigner.com/wp-content/themes/1stwd/img/1wd-logo-rd.png)
     no-repeat center center;
    }
    
  3. Change the bg color and add a border to the header container (Refer to the code snippet added towards the end of 4th point)
    Lets style the container ‘nav-inner’ by adding a bg-color and a border.
  4. Style the nav items and add a border-radius.
    Navigation list items are under the container with class ‘nav’. We have to style the ‘a’ tag within the ‘li’ tag that comes under ‘nav’. Let’s add a border-radius of 5px (line number 11) using css3 mixin which (@include border-radius(5px) generates all the necessary browser specific rules to the CSS file being generated ) and relevant margin and padding along-with a hover bg-color to it (line no: 12. ‘&’ is added as a prefix to indicate the grouping of the selector that follows it. In this case, ‘&:hover’ associates the pseudo class – :hover to the parent selector, which is a.). With all the custom styles added, the navbar section styles looks like:
    .navbar{
     .navbar-inner{
      background:#eee;
      border-bottom:solid 1px #ccc;
      .nav{
       margin-left:20px;
       li{
        a{
         padding:5px;
         margin:5px 5px 0 0;
         @include border-radius(5px);
         &:hover{
          background:#000;
         };
        }
       }
      }
      .brand{
       text-indent:-999px;
       width:169px;
       height:26px;
       padding:0;
       margin:5px 0 0 0;
       background:url(http://cdn1.1stwebdesigner.com/wp-content/themes/1stwd/img/1wd-logo-rd.png)
       no-repeat center center;
      }
     }
    }
    

Next is the hero unit

Here is a comparison of our current hero-unit and the customized one:

The key changes that we’ll be doing here are (the final code for this section is given towards the end of this bulleted section):

  1. Change the bg colors of the container and the form within
    Lets style the container ‘hero-unit’ by adding a different bg color-#464646 , and a text color-#fff (line no:2 )
  2. Style the header text and the call for action button
    For the text ‘Welcome’ to be in a separate color, we will have to wrap it inside a tag. Lets add it within a span tag, style it, and let’s apply a text-shadow for the whole H1 header.(line no: 4 to 8)
  3. Style the form with the login fields
    Let’s add a border radius of 10px to the form using CSS3 mixin (line no: 15), a bg-color #>6d6b6b (line no: 16), and style the label and the input fields (line no. 17 to 30).
  4. The CSS code for the hero-unit now looks like:
    .hero-unit{
     background:#464646;
     color:#fff;
      h1{
       @include text-shadow(#000 1px 5px  10px);
       span{
        color:#F5821F;
       }
      }
      .btn-info{
       padding:15px;
       font-size:1.2em;
       }
       form{
       @include border-radius(10px);
       background:#6d6b6b;
       label{
        font-weight:bold;
        font-size:1.2em;
        &.checkbox{
        font-weight:normal;
        font-size:1em;
        color:#2d2d2d;
        }
       }
       input{
       background:#464646;
       border:solid 1px #545252;
       @include box-shadow(inset #2d2d2d 1px 0px 3px);
       color:#8b7b6c;
       }
      }
     }
    

Now comes the thumbnail section

Here is a comparison of our current thumbnail section and the customized one:

The key changes that we’ll be doing here are (the final code for this section is given towards the end of this bulleted section):

  1. Style the thumbnail containers and add relevant images
    Let’s style give a border-radius of 10px to the thumbnail container (line no: 2), and a bg-color (line no: 3).
  2. Positioning the caption of each thumbnails above the thumbnails.
    Let’s using positioning and absolutely position the caption on top of the thumbnails. To achieve this we will have to apply ‘position:relative’ to the parent tag of the caption (line no: 5), and then position the header (h5) accordingly so that it is appearing just on top of the thumbnail and in line with the bottom-line of the image, and also lets add a text shadow to it (line no: 8 to 13).
  3. The code for this section now looks like
    .thumbnail{
     @include border-radius(10px);
     background:#55626B;
     .caption{
      position:relative;
      color:#ccc9c9;
      h5{
       position:absolute;
       top:-19px;
       left:10px;
       font-size:2em;
       color:#fff;
       @include text-shadow(#000 1px 5px 10px);
      }
     }
    }
    

Finally the footer

I am just adding a custom pattern to the footer, add a border-radius and will be increasing the padding of the container to 20px. Please refer to the code of footer below:

footer{
 padding:20px;
 margin-top:30px;
 @include border-radius(10px 10px 0 0);
 color:#fff;
 background:url(http://cdn1.1stwebdesigner.com/wp-content/themes/1stwd/img/bg_header.jpg) repeat left top;
}

Finally after all the customization and coding, here is how our customized page looks:

This is just an intro to the power of SASS and TBS together. In the CSS file that we have used we can make use of variables effectively by storing color values in them and then importing the variable CSS to the main stylesheet at the beginning. With the complexity of each page, all the features of SASS can be leveraged in a much better way. Mixins, Extend, Variables and much more are in store for us to explore and implement.

Get started with this if you are planning to plunge into the world of SASS and wait for more to come your way. I’d appreciate your feedback on my approach and on this tutorial to help me improve!

May 09 2012

13:00

Mastering CSS Gradients in Under an Hour

If this message appears to another site than 1stwebdesigner ,it has been stolen, please visit original source!

Have you refrained from using CSS Gradients because either you didn’t understand them, or thought the browser support for them wasn’t good enough to consider using them in your projects?

Well, it’s time to kill those 1px wide images, my friend.

If you’re just curious about how to use CSS Gradients, this is the place for you. We’ll start with the basics of syntax to very advanced effects with lots of tips and examples.

Remember, learning about CSS gradients is really important since browsers are getting better and better every day. Mobile browsers have good CSS3 support by default.

So, let’s rock!

Basic syntax

The first thing you must be aware of is browser support. For now you must keep the browser vendor prefixes AND use a custom filter for IE. So, we have at least 5 possible prefixes, each one with its own subtle variation and even multiple differences between browsers versions: Opera (presto), Firefox (gecko), Safari / Chrome (Webkit), Konqueror (KHTML), and IE (Trident), which has 2 different ways to do it (IE… go figure!).

We’ll focus on “standard” browser rules here (e.g. we won’t talk about old from() to() rules), and we’ll have a chapter on IE compatibility at the end (since its filters don’t allow all the effects we’ll see here).

This is the basic syntax:

#wd {
background: vendor-type-gradient( start / position , shape size, color 1, color2 [position] [, other colors / positions] );
/*** real example **/

background: -moz-linear-gradient( top left, red, #c10000, #ae0000 );

background: -webkit-linear-gradient( top left, red, #c10000, #ae0000 );

background: -o-linear-gradient( top left, red, #c10000, #ae0000 );

background: -khtml-linear-gradient( top left, red, #c10000, #ae0000 );

background: -ms-linear-gradient( top left, red, #c10000, #ae0000 );

background: linear-gradient( top left, red, #c10000, #ae0000 );
}

This CSS will get this result:

So, here are the items explained:

  • Background: Just like you set background image or colors you’ll set gradients as a separate item
  • vendor -: We can use “-o” for opera, “-moz” for Firefox, “-webkit” for safari and chrome, “-khtml” for Konqueror and “-ms” for IE
  • type: Here we can use “linear” or “radial”
  • start / position: This is a X/Y coordinate which tells the browser either the direction (top means that it’ll be top to bottom, and left that it’ll be left to right) or the exact start point (like 600px 300px will invert the example above because the start point will be the bottom right)
  • shape: If you use radial gradient you can set it as “circle” or leave it blank so the gradient will be ellipsis-shaped
  • size: If you are using radial gradients you can set where the gradient extends to. You can use: closest-side,  closest-corner, farthest-side, farthest-corner, contain, cover to set the gradient position.
  • Color1: This is the first color. It’ll be the color in the start point you set above
  • Colors 2,3,4..: You can add as many colors as you want and they’ll be evenly distributed in the element’s background unless you declare a position.
  • Position (for colors): If you don’t want an even distribution you can add your own rules for positioning colors.

Here is an example making use of color positions:


#wd {

background: -moz-linear-gradient( top left, white, black 25% );

background: -webkit-linear-gradient( top left, white, black 25% );

background: -o-linear-gradient( top left, white, black 25% );

background: -khtml-linear-gradient( top left, white, black 25% );

background: -ms-linear-gradient( top left, white, black 25% );

background: linear-gradient( top left, white, black 25% );
}

You can see the result and an outlined area, about those 25% / 75% portions so you can have a better idea on how the browser calculates those values:

Multiple gradients

Let’s dig a little deeper and see more cool stuff you can do. You can start doing advanced stuff and playing with shape combinations to create new effects.

The syntax is pretty simple, all you’ve got to do is separate multiple declarations with commas. Notice that the “z-index” of the gradients will be reversed and the first item will be at the top.

If you set the color to transparent, you can use a background color if you want. Otherwise the color of the top element will hide all the others.

Ok, let’s play with some code now:


#wd {

background:

-moz-linear-gradient( top left, white, transparent 25% ),

-moz-linear-gradient( bottom right, white, transparent 25% ),

-moz-radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

-moz-radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;

background:

-webkit-linear-gradient( top left, white, transparent 25% ),

-webkit-linear-gradient( bottom right, white, transparent 25% ),

-webkit-radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

-webkit-radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;

background:

-o-linear-gradient( top left, white, transparent 25% ),

-o-linear-gradient( bottom right, white, transparent 25% ),

-o-radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

-o-radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;

background:

-khtml-linear-gradient( top left, white, transparent 25% ),

-khtml-linear-gradient( bottom right, white, transparent 25% ),

-khtml-radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

-khtml-radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;

background:

-ms-linear-gradient( top left, white, transparent 25% ),

-ms-linear-gradient( bottom right, white, transparent 25% ),

-ms-radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

-ms-radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;

background:

linear-gradient( top left, white, transparent 25% ),

linear-gradient( bottom right, white, transparent 25% ),

radial-gradient( 25% 50%, circle, white, white 20%, transparent 25% ),

radial-gradient( 75% 50%, contain, white, white 20%, transparent 25% )

black;            }

And this will be your final result:

Cool Effects

As you can see, gradients combinations can lead to awesome results. Here we’ll see a few practical (ok, some of them quite experimental) examples that you can use and even make them better.

Subtle lighting effect

This effect is pretty easy to use, especially for featured images. It gives a subtle elliptical shadow for your elements without additional markup, you can just include it in your images. Oh, and it works pretty well for hovers also.

Here is the CSS to achieve the effect (and also correct positioning for elements):


img {

margin: 0 -60px;

padding: 25px 60px 40px;

background: -moz-radial-gradient( center center, contain, black, white 90% );

background: -webkit-radial-gradient( center center, contain, black, white 90% );

background: -o-radial-gradient( center center, contain, black, white 90% );

background: -khtml-radial-gradient( center center, contain, black, white 90% );

background: -ms-radial-gradient( center center, contain, black, white 90% );

background: radial-gradient( center center, contain, black, white 90% );
}

And this is the effect applied to one o four images:

CSS Background Patterns

There are quite a few highly experimental CSS patterns out there, but there are a few that you can actually use, especially the ones which rely on gradients that end smoothly.

Here is an example on how to apply a subtle background pattern that you can easily integrate in your site:


body {

background:

-moz-radial-gradient( center center, contain, #757575, transparent ),

black;

background:

-webkit-radial-gradient( center center, contain, #757575, transparent ),

black;

background:

-o-radial-gradient( center center, contain, #757575, transparent ),

black;

background:

-khtml-radial-gradient( center center, contain, #757575, transparent ),

black;

background:

-ms-radial-gradient( center center, contain, #757575, transparent ),

black;

background:

radial-gradient( center center, contain, #757575, transparent ),

black;
}

And this will be the rendered result:

It’ll Blow your mind – CSS Painting

If there’s one thing that impressed me since I started with this web stuff is CSS painting. It used to be so hard that you could need several lines of code (like hundreds or thousands) to get the simple ones.

Now with barely 10 lines and a single element you can do simple paintings. This is especially useful if you want to do CSS animations because CSS generated elements are much likely to apply CSS standard animations.

Here is the code I used to do a simple scared face to show to your IE users:


#wd {

position: relative;

width: 450px;

height: 400px;

margin: 20px auto;

background:

-moz-radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-moz-radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-moz-radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

-moz-radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

background:

-webkit-radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-webkit-radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-webkit-radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

-webkit-radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

background:

-o-radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-o-radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-o-radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

-o-radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

background:

-khtml-radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-khtml-radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-khtml-radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

-khtml-radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

background:

-ms-radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-ms-radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

-ms-radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

-ms-radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

background:

radial-gradient( 25% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

radial-gradient( 75% 30%, contain, black, black 4%, white 5%, white 24%, transparent 25% ),

radial-gradient( 50% 50%, contain, #e19b92, #e19b92 9%, transparent 10% ),

radial-gradient( 50% 75%, contain, black, black 24%, transparent 25% )

#f3c2bb;

border-radius: 50%;

}

#wd:after {

content: "Are you using IE??";

position: absolute;

top: 225px;

left: 315px;

padding: 5px 10px;

width: 150px;

font-family: "comic Sans MS",arial,verdana; /* I just couldn't help using comics! */

background: white;

border: 2px solid #E19B92;

border-radius: 4px 4px 4px 4px;

}

And this is the rendered result:

Compatibility notes

There are 2 important final notes on this. First is on old Webkit rules (which still in use for many old versions including mobile). They are slightly different than the ones presented here:

#wd {

background-image: -webkit-gradient(type, position, radius, xpos ypos, outer radius, from(startColor), to(endColor) [, color-stop(25%, middleColor)] );

/* example */

background-image: -webkit-gradient(radial, center center, 0, center center, 120, from(red), to(white), color-stop(10%, blue) );
}

And we have also Microsoft filters for IE. They are better explained in this Microsoft’s guide.

So, what do you think about it?

Can you think of new uses for those CSS gradients? Let us know using the comments section!

April 16 2012

15:21

Optimize Your CSS With RequireJS

In this lesson, we’ll review the awesome RequireJS optimizer to handle the process of merging and compressing our stylesheets. While preprocessors continue to become increasingly popular, there are still plenty of folks who stick with regular CSS. In these cases, a solid build tool/process is vital.

Choose 720p for the clearest video.

Closing Thoughts

If you don’t like the idea of using Require.js, alternatively you might consider Grunt (along with the Grunt-CSS plugin), or Jake.


April 11 2012

16:11

Toying With the HTML5 File System API

HTML5 provides us with a whole crop of new possibilities, such as drawing with canvas, implementing multimedia with the audio and video APIs, and so on. One of these tools, which is still relatively new, is the File System API. It gives us access to a sandboxed section of the user’s local file system, thus filling the gap between desktop and web applications even further! In today’s tutorial, we’ll go through the basics of this new and exciting API, exploring the most common filesystem tasks. Let’s get started!


Introduction

No longer do we need to download and install a given piece of software in order to use it. Simply a web browser and an internet connection gives us the ability to use any web application, anytime, anywhere, and on any platform.

In short, web apps are cool; but, compared to desktop apps, they still have one significant weakness: they don’t have a way to interact and organize data into a structured hierarchy of folders – a real filesystem. Fortunately, with the new Filesystem API, this can be changed. This API gives web applications controlled access to a private local filesystem “sandbox,” in which they can write and read files, create and list directories, and so on. Although at the time of this writing only Google’s Chrome browser supports the “full” implementation of the Filesystem API, it still deserves to be studied as a powerful and convenient form of local storage.

Can I Use Support}

The Filesystem API comes in two different versions. The asynchronous API, which is useful for normal applications, and the synchronous API, reserved for use with web workers. For the purposes of this tutorial, we will exclusively explore the asynchronous version of the API.


Step 1 – Getting Started

Your first step is to obtain access to the HTML5 Filesystem by requesting a LocalFile System object, using the window.requestFileSystem() global method:

window.requestFileSystem(type, size, successCallback, opt_errorCallback)

There’s no way for a web application to “break out” beyond the local root directory.

As the first two parameters, you specify the lifetime and size of the filesystem you want. A PERSISTENT filesystem is suitable for web apps that want to store user data permanently. The browser won’t delete it, except at the user’s explicit request. A TEMPORARY filesystem is appropriate for web apps that want to cache data, but can still operate if the web browser deletes the filesystem. The size of the filesystem is specified in bytes and should be a reasonable upper bound on the amount of data you need to store.

The third parameter is a callback function that is triggered when the user agent successfully provides a filesystem. Its argument is a FileSystem object. And, lastly, we can add an optional callback function, which is called when an error occurs, or the request for a filesystem is denied. Its argument is a FileError object. Although this parameter is optional, it’s always a good idea to catch errors for users, as there are a number of places where things can go wrong.

The filesystem obtained with these functions depends on the origin of the containing document. All documents or web apps from the same origin (host, port, and protocol) share a filesystem. Two documents or applications from different origins have completely distinct and disjoint filesystems. A filesystem is restricted to a single application and cannot access another application’s stored data. It’s also isolated from the rest of the files on the user’s hard drive, which is a good thing: there’s no way for a web application to “break out” beyond the local root directory or otherwise access arbitrary files.

Let’s review an example:

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;

window.requestFileSystem(window.TEMPORARY, 5*1024*1024, initFS, errorHandler);

function initFS(fs){
  alert("Welcome to Filesystem! It's showtime :)"); // Just to check if everything is OK :)
  // place the functions you will learn bellow here
}

function errorHandler(){
  console.log('An error occured');
}

This creates a temporary filesystem with 5MB of storage. It then provides a success callback function, which we will use to operate our filesystem. And, of course, an error handler is also added – just in case something goes wrong. Here, the errorHandler() function is too generic. So if you want, you can create a slightly optimized version, which gives the reader a more descriptive error message:

function errorHandler(err){
 var msg = 'An error occured: ';

  switch (err.code) {
    case FileError.NOT_FOUND_ERR:
      msg += 'File or directory not found';
      break;

    case FileError.NOT_READABLE_ERR:
      msg += 'File or directory not readable';
      break;

    case FileError.PATH_EXISTS_ERR:
      msg += 'File or directory already exists';
      break;

    case FileError.TYPE_MISMATCH_ERR:
      msg += 'Invalid filetype';
      break;

    default:
      msg += 'Unknown Error';
      break;
  };

 console.log(msg);
};

The filesystem object you obtain has a name (a unique name for the filesystem, assigned by the browser) and root property that refers to the root directory of the filesystem. This is a DirectoryEntry object, and it may have nested directories that are themselves represented by DirectoryEntry objects. Each directory in the file system may contain files, represented by FileEntry objects. The DirectoryEntry object defines methods for obtaining DirectoryEntry and FileEntry objects by pathname (they will optionally create new directories or files if you specify a name that doesn’t exist). DirectoryEntry also defines a createReader() factory method that returns a DirectoryReader object for listing the contents of a directory. The FileEntry class defines a method for obtaining the File object (a Blob) that represents the contents of a file. You can then use a FileReader object to read the file. FileEntry defines another method to return a FileWriter object that you can use to write content into a file.

Phhew…sounds complicated? Don’t worry. Everything will become clearer as we progress through the examples below.


Step 2 – Working With Directories

Obviously, the first thing you need to create in a filesystem is some buckets, or directories. Although the root directory already exists, you don’t want to place all of your files there. Directories are created by the DirectoryEntry object. In the following example, we create a directory, called Documents, within the root directory:

fs.root.getDirectory('Documents', {create: true}, function(dirEntry) {
  alert('You have just created the ' + dirEntry.name + ' directory.');
}, errorHandler);

The getDirectory() method is used both to read and create directories. As the first parameter, you can pass either a name or path as the directory to look up or create. We set the second argument to true, because we’re attempting to create a directory – not read an existing one. And at the end, we add an error callback.

So far, so good. We have a directory; let’s now add a subdirectory. The function is exactly the same with one difference: we change the first argument from ‘Documents’ to ‘Documents/Music’. Easy enough; but what if you want to create a subfolder, Sky, with two parent folders, Images and Nature, inside the Documents folder? If you type ‘Documents/Images/Nature/Sky‘ for the path argument, you will receive an error, because you can’t create a directory, when its immediate parent does not exist. A solution for this is to create each folder one by one: Images inside Documents, Nature inside Images, and then Sky inside Nature. But this is a very slow and inconvenient process. There is a better solution: to create a function which will create all necessary folders automatically.

function createDir(rootDir, folders) {
  rootDir.getDirectory(folders[0], {create: true}, function(dirEntry) {
    if (folders.length) {
      createDir(dirEntry, folders.slice(1));
    }
  }, errorHandler);
};

createDir(fs.root, 'Documents/Images/Nature/Sky/'.split('/'));

With this little trick, all we need to do is provide a full path representing the folders which we want to create. Now, the Sky directory is successfully created, and you can create other files or directories within it.

Now it’s time to check what we have in our filesystem. We’ll create a DirectoryReader object, and use the readEntries() method to read the content of the directory.

fs.root.getDirectory('Documents', {}, function(dirEntry){<br>
  var dirReader = dirEntry.createReader();
  dirReader.readEntries(function(entries) {<br>
    for(var i = 0; i < entries.length; i++) {
      var entry = entries[i];
      if (entry.isDirectory){
        console.log('Directory: ' + entry.fullPath);
      }
      else if (entry.isFile){
        console.log('File: ' + entry.fullPath);
      }
    }

  }, errorHandler);
}, errorHandler);

In the code above, the isDirectory and isFile properties are used in order to obtain a different output for directories and files, respectively. Additionally, we use the fullPath property in order to get the full path of the entry, instead of its name only.

There are two ways to remove a DirectoryEntry from the filesystem: remove() and removeRecursively(). The first one removes a given directory only if it is empty. Otherwise, you’ll receive an error.

fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
  dirEntry.remove(function(){
    console.log('Directory successfully removed.');
  }, errorHandler);
}, errorHandler);

If the Music folder has files within it, then you need to use the second method, which recursively deletes the directory and all of its contents.

fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
  dirEntry.removeRecursively(function(){
    console.log('Directory successufully removed.');
  }, errorHandler);
}, errorHandler);

Step 3 – Working With Files

Now that we know how to create directories, it’s time to populate them with files!

The following example creates an empty test.txt in the root directory:

fs.root.getFile('test.txt', {create: true, exclusive: true}, function(fileEntry) {
  alert('A file ' + fileEntry.name + ' was created successfully.');
}, errorHandler);

The first argument to getFile() can be an absolute or relative path, but it must be valid. For instance, it is an error to attempt to create a file, when its immediate parent does not exist. The second argument is an object literal, describing the function’s behavior if the file does not exist. In this example, create: true creates the file if it doesn’t exist and throws an error if it does (exclusive: true). Otherwise, if create: false, the file is simply fetched and returned.

Having an empty file is not very useful, though; so let’s add some content inside. We can use the FileWriter object for this.

fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
  fileEntry.createWriter(function(fileWriter) {
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
    var bb = new BlobBuilder();
    bb.append('Filesystem API is awesome!');
    fileWriter.write(bb.getBlob('text/plain'));
  }, errorHandler);
}, errorHandler);

Above, we retrieve the test.txt file, and create a FileWriter object for it. We then append content to it by creating a new BlobBuilder object and using the write() method of FileWriter.

Calling getFile() only retrieves a FileEntry. It does not return the contents of the file. So, if we want to read the content of the file, we need to use the File object and the FileReader object.

fs.root.getFile('test.txt', {}, function(fileEntry) {
  fileEntry.file(function(file) {
    var reader = new FileReader();
    reader.onloadend = function(e) {
      alert(this.result);
    };
    reader.readAsText(file);
  }, errorHandler);
}, errorHandler);

We have written some content to our file, but what if desire to add more at a later date? To append data to an existing file, the FileWriter is used once again. We can reposition the writer to the end of the file, using the seek() method. seek accepts a byte offset as an argument, and sets the file writer’s position to that offset.

fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
  fileEntry.createWriter(function(fileWriter) {
    fileWriter.seek(fileWriter.length);
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
    var bb = new BlobBuilder();
    bb.append('Yes, it is!');
    fileWriter.write(bb.getBlob('text/plain'));
  }, errorHandler);
}, errorHandler);

To remove a file from the filesystem, simply call entry.remove(). The first argument to this method is a zero-parameter callback function, which is called when the file is successfully deleted. The second is an optional error callback if any errors occur.

fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
  fileEntry.remove(function() {
    console.log('File successufully removed.');
  }, errorHandler);
}, errorHandler);

Step 4 – Manipulating Files and Directories

FileEntry and DirectoryEntry share the same API methods for copying, moving and renaming entries. There are two methods you can use for these operations: copyTo() and moveTo(). They both accept the exact same parameters:

copyTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);

moveTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);

The first parameter is the parent folder to move/copy the entry into. The second is an optional new name to give the moved/copied entry, which is actually required when you copy an entry in the same folder; otherwise you will get an error. The third and fourth parameters were explained previously.

Let’s review some simple examples. In the following one, we copy the file test.txt from the root to the Documents directory.

function copy(currDir, srcEntry, destDir) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    currDir.getDirectory(destDir, {}, function(dirEntry) {
      fileEntry.copyTo(dirEntry);
    }, errorHandler);
  }, errorHandler);
}

copy(fs.root, 'test.txt', 'Documents/');

This next example moves test.txt to Documents, instead of copying it:

function move(currDir, srcEntry, dirName) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    currDir.getDirectory(dirName, {}, function(dirEntry) {
      fileEntry.moveTo(dirEntry);
    }, errorHandler);
  }, errorHandler);
}

move(fs.root, 'test.txt', 'Documents/');

The following example renames test.txt to text.txt:

function rename(currDir, srcEntry, newName) {
  currDir.getFile(srcEntry, {}, function(fileEntry) {
    fileEntry.moveTo(currDir, newName);
  }, errorHandler);
}

rename(fs.root, 'test.txt', 'text.txt');

Learn More

In this introductory tutorial, we’ve only scratched the surface of the different filesystem interfaces. If you want to learn more and dig deeper into Filesystem API, you should refer to the W3C specifications specifications:

Now that you have a basic understanding of what the Filesystem API is, and how it can be used, it should be considerably easier to understand the API documentation, which can be a bit confusing at first sight.


Conclusion

The Filesystem API is a powerful and easy to use technology, which provides web developers with a whole crop of new possibilities when building web applications. Admittedly, it’s still quite new and not widely supported by all major browsers, but this will certainly change in the future. You might as well get a head start!


April 06 2012

13:56

CSS Refreshers: Borders

Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

Not only can CSS3 be used to create rounded corners, but plain-ole’ CSS can also be wrestled into displaying custom shapes. That’s right; in the past, before these techniques were discovered, we might have resorted to using absolutely positioned background images to display circles or arrows. Thankfully – as we gleefully take one more step away from Photoshop – this is no longer the case.


The Basics

You’re likely familiar with the most basic use of borders.

border: 1px solid black;

The above code will apply a 1px border to an element. Plain and simple; but we can also modify the syntax a bit.

border-width: thick;
border-style: solid;
border-color: black;

In addition to passing a specific value to border-width, three keywords may alternatively be used: thin, medium, and thick.

image

While it might initially seem unnecessary to ever make use of the long-hand form, there are a handful of cases when it’s advantageous, such as when you need to update some aspect of a border when a designated event occurs.

Perhaps you need to change the color of a border when the user hovers over a specific element. Using the shorthand form would require that you repeat the pixel values.

.box {
    border: 1px solid red;
}

.box:hover {
    border: 1px solid green;
}

A more elegant and DRY approach would be to specifically update the border-color property.

.box {
    border: 1px solid red;
}

.box:hover {
    border-color: green;
}

Additionally, as you’ll find shortly, this long-hand technique is helpful when creating custom shapes with CSS.


Border-Radius

border-radius is the golden child of CSS3 – the first new property to gain widespread use in the community. What this translates to is that, excluding Internet Explorer 8 and below, all browsers can display rounded corners.

Previously, it was necessary to use vendor prefixes for both Webkit and Mozilla, in order for the styling to be correctly applied.

-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;

These days, however, we can slice off the vendor versions without worry, and simply stick with the official form: border-radius.

image

As one might expect, we can also specify custom values for each side of a box.

image
border-top-left-radius: 20px;
border-top-right-radius: 0;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 0;

In the code above, setting border-top-right-radius and border-bottom-left-radius to zero would be superfluous, unless the element is inheriting values which need to be reset.

Much like margin or padding, these settings can be condensed into a single property, if necessary.

/* top left, top right, bottom right, bottom left */
border-radius: 20px 0 30px 0;

As an example (and as web designers do so often), the shape of a lemon can be reproduced with CSS and the border-radius property, like so:

.lemon {
   width: 200px; height: 200px; 

   background: #F5F240;
   border: 1px solid #F0D900;
   border-radius: 10px 150px 30px 150px;
}
image

Beyond the Basics

Many designers happily stick with the knowledge outlined thus far in this chapter; however, there’s a few ways we can push it further!


Multiple Borders

There’s a variety of techniques that we can refer to, when tasked with applying multiple borders to an element.

Border-Style

While solid, dashed, and dotted are the most frequent values for the border-style property, there’s also a few others that we can make use of, including groove and ridge.

border: 20px groove #e3e3e3;

Or, with the long-hand form:

border-color: #e3e3e3;
border-width: 20px;
border-style: groove;
image

While this is certainly helpful, a ridge or groove effect isn’t really multiple borders.

Outline

The most popular technique for creating two borders is to take advantage of the outline property.

.box {
   border: 5px solid #292929;
   outline: 5px solid #e3e3e3;
}
image

This method works wonderfully, however, it’s limited to two borders. Should you need to create a layered, gradient-esque, effect, a different approach will be necessary.

Pseudo Elements

When the outline technique doesn’t suffice, an alternate approach is to take advantage of the :before and :after pseudo elements, and apply any necessary additional borders to the generated content.

.box {
  width: 200px; height: 200px;
  background: #e3e3e3;
  position: relative;

  border: 10px solid green;
}

/* Create two boxes with the same width of the container */
.box:after, .box:before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

.box:after {
  border: 5px solid red;
  outline: 5px solid yellow;
}

.box:before {
  border: 10px solid blue;
}
image

This perhaps isn’t the most elegant approach, but it certainly gets the job. One caveat is that it’s easy to confuse the order in which the border colors will be applied. A certain level of “guess and check” is often required to apply the correct sequence.

Box-Shadow

The cool kids way to create an infinite number of borders is to take advantage of the spread parameter in the box-shadow CSS3 property.

.box {
    border: 5px solid red;
     box-shadow:
       0 0 0 5px green,
       0 0 0 10px yellow,
       0 0 0 15px orange;
}
image

In this case, we’re being clever and are using box-shadow in a way that might not necessarily have been intended when the specification was originally written.

By setting the x, y, and blur components to 0, we can instead use the spread value to create solid borders at the desired locations. Because box-shadows can be stacked, through the use of a comma, the number of possible levels is infinite.

This technique gracefully degrades quite nicely. In older browsers, which do not recognize the box-shadow property, this will simply render the single red 5px border.

Remember: designs needn’t be identical in all browsers. Write your CSS for the most modern of browsers, and then provide suitable fallbacks, accordingly.


Modifying Angles

In addition to passing a single value to border-radius, we can alternatively provide two – separated by a / – to specify unique values for both the horizontal and vertical radii.

For example…

border-radius: 50px / 100px; /* horizontal radius, vertical radius */

…is equivalent to:

border-top-left-radius: 50px 100px;
border-top-right-radius: 50px 100px;
border-bottom-right-radius: 50px 100px;
border-bottom-left-radius: 50px 100px;

This technique is particularly helpful when you need to mimic a subtle, lengthy curve, rather than a generic rounded corner. For instance, the following code allows us to slightly break away from a square shape, resulting in more of a curled, paper-like effect.

.box {
    width: 200px; height: 200px;
    background: #666;

    border-top-left-radius: 15em 1em;
    border-bottom-right-radius: 15em 1em;

}
image

CSS Shapes

Perhaps the neatest use of borders is when they’re cleverly applied to elements, which have a zero width and height. Confusing, huh? Let’s see a demonstration.

For the next several examples, assume the following markup…

<div class="box"></div>

…and the following base styling:

.box {
   width: 200px;
   height: 200px;
   background: black;
}

The most frequently referenced example, when demonstrating how CSS shapes might be used in a project, is to create the obligatory arrow.

The key to understanding how an arrow might be formed with CSS is to set a unique border-color to each side, and then reduce both the width and height values for the container to 0.

Assuming a div with a class of arrow as the container:

.arrow {
  width: 0; height: 0;

  border-top: 100px solid red;
  border-right: 100px solid green;
  border-bottom: 100px solid blue;
  border-left: 100px solid yellow;
}

As demonstrated at the beginning of this chapter, a cleaner syntax would be to not use the all-encompassing short-hand version:

.arrow {
  width: 0; height: 0;

  border: 100px solid;
  border-top-color: red;
  border-right-color: green;
  border-bottom-color: blue;
  border-left-color: yellow;
}

We can even reduce this further, by grouping the color values.

.arrow {
  width: 0; height: 0;

  border: 100px solid;
  border-color: red green blue yellow;
}
image

Interesting, right? It makes perfect sense, though, when we take a step back. That’s the only possible way that the colors could align, assuming a width and height of zero for the container. Now, what if we set all of the border-colors to transparent, except for the blue side?

.arrow {
  width: 0; height: 0;

  border: 100px solid;
  border-bottom-color: blue;
}
image

Excellent! But it doesn’t seem too semantic to create an .arrow div, all for the purpose of adding an arrow to the page. Instead, pseudo elements can be used to apply the arrow after or before the associated element.

Creating a Speech Bubble

To create a 100% CSS speech bubble, we begin with the markup.

<div class="speech-bubble">Hi there!</div>

Next, some base styling should be applied.

.speech-bubble {
    position: relative;
    background-color: #292929;

    width: 200px;
    height: 150px;
    line-height: 150px; /* vertically center */

    color: white;
    text-align: center;
}
image

The arrow will be applied using the after psuedo-element.

.speech-bubble:after {
    content: '';
}

The :before and :after psuedo elements can be used to insert generated content either before or after an element’s content.

At this point, it’s simply a matter of reproducing the arrow, and positioning it in the proper location. We start by absolutely positioning the content, resetting the width and height, and applying the border colors.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 10px solid;
  border-color: red green blue yellow;
}
image

Because we know that we want the arrow to point downward, the image above demonstrates that all but the red (or top) border should either be omitted, or set to transparent.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 10px solid;
  border-top-color: red;
}
image

When creating CSS shapes, because we can’t use the width property to specify how wide the arrow should be, the border-width property should be used instead. In this case, the arrow should be slightly larger; so the border-width can be increased to 15px. We’ll also position the arrow at the bottom and center of the container, by using the top and left properties, respectively.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
  border-top-color: red;

  top: 100%;
  left: 50%;
}
image

Almost there; the final step is to update the color of the arrow to be the same as the container’s background. The positioning also needs to be modified to account for the width of the borders (15px). While we’re here, we’ll also apply a subtle border-radius to make the container appear to be more bubble-like.

.speech-bubble {
   /* … other styles */
   border-radius: 10px;
}

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
  border-top-color: #292929;

  top: 100%;
  left: 50%;
  margin-left: -15px; /* adjust for border width */
}
image

Not bad, ay? Abstract this code away to a few reusable classes, and you’re good to go for all future projects.

/*
   Speech Bubbles
   Usage: Apply a class of .speech-bubble and .speech-bubble-DIRECTION
   <div class="speech-bubble speech-bubble-top">Hi there</div>
*/

.speech-bubble {
  position: relative;
  background-color: #292929;

  width: 200px;
  height: 150px;
  line-height: 150px; /* vertically center */

  color: white;
  text-align: center;
  border-radius: 10px;

  font-family: sans-serif;
}

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
}

/* Position the Arrow */

.speech-bubble-top:after {
  border-bottom-color: #292929;

  left: 50%;
  bottom: 100%;
  margin-left: -15px;
}
.speech-bubble-right:after {
  border-left-color: #292929;

  left: 100%;
  top: 50%;
  margin-top: -15px;
}

.speech-bubble-bottom:after {
  border-top-color: #292929;

  top: 100%;
  left: 50%;
  margin-left: -15px;
}

.speech-bubble-left:after {
  border-right-color: #292929;

  top: 50%;
  right: 100%;
  margin-top: -15px;
}
image

Bonus: Better Vertical Centering

One downside to using line-height to vertically center text is that you’re limited to a single line. Should the text require two or more lines, each line height will be far too large. A clever solution is to set a display of table to the speech bubble, and a display of table-cell to the paragraph that wraps the text. This then allows us to align the text to the middle, accordingly.

<div class="speech-bubble speech-bubble-top">
    <p>Text goes here.</p>
</div>

Next, the modified CSS.

.speech-bubble {
 /* other styles */

  display: table;
}

.speech-bubble p {
  display: table-cell;
  vertical-align: middle;
}
image

If references to display: table bring back terrible memories of old-fashioned, table-based layouts, don’t worry. These properties merely refer to the style in which an element should display.

We’re not limited to triangles; CSS is capable of producing all sorts of shapes – even hearts and biohazard signs!

image
.biohazard {
  width: 0; height: 0;

  border: 60px solid;
  border-radius: 50%;

  border-top-color: black;
  border-bottom-color: black;
  border-left-color: yellow;
  border-right-color: yellow;
}

Summary

Though it’s true that the simple border: 1px solid black syntax goes a long way, if we’re clever, we can create a variety of helpful effects, icons, and shapes. Who would have thought that borders could be so powerful? The key is to remember that the styling for common shapes or speech bubbles should only be created once, and then abstracted away to utility classes for future usage.


Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.

Don't be the product, buy the product!

Schweinderl