Don’t forget about :active
Don’t forget about :active
|
|
Every once in a while I remember some functionality of CSS that we have had access too for ages yet is rarely taken advantage of in creative ways. The last time I really wrote about this is when I had discovered a way to make other menu items change when you hovered on just one of them, as you can see here in the Advanced CSS Menu Trick article.
Sometimes rediscovering these capabilities are valuable for creating new ways to add creative touches, such as the parallax scrolling effect. Other times they can greatly improve the usability and user experience of our sites. In some cases they do both.
I was recently reading through “The Elements of User Experience
,” which opens with a compelling story describing why things going wrong in your day could be the fault of poor design in regards to usability. Interestingly enough one of the points covered in this section is the use of feedback as a way to notify a user that something has occurred.
Most Web Designers Fail to Take Advantage of :active
In the case in the book they mention a coffee pot beeping so you know that it was switched on. This same principal of offering a user basic feedback applies to the web, yet we rarely see it used in all instances it can.
We have had the ability to style a links :active pseudo selector since CSS1, yet when was the last time you actually used it? I will admit that I am a grand offender as well, as I couldn’t tell you. However the value of such a subtle detail can have large benefits to a users experience of the site. Not to mention it does give another avenue to enrich the interactivity of our interfaces.
An Common Example
If you have ever done any usability studies you will have probably run into a situation where things that seem incredibly simple end up taking significant amount of time. One of the most basic of these situations is that of clicking on a simple link. I have many times in my “behavior observing” career seen a user who thinks they have click on a link, despite having missed it slightly.
What follows is a long pause while they wait for the page to change, before getting frustrated and either blaming the internet, the site, or swirling the mouse to ensure the computer hasn’t locked up.
This could all be solved by simply giving the user feedback when a button is clicked. Interestingly enough flash based websites have done a better job through out history of accomplishing this than most HTML sites, done so by adding a subtle “clicking” noise as a link is clicked.
Of course I am not advocating the use of sound (as it fails on several accessibility levels among other issues), however it wouldn’t be hard to give the user some feedback to let them know the link was successfully clicked on.
What We Can Do
By using the :active selector in CSS we can give the user some feedback that a link has in fact been clicked. This way if there is any sort of delay the user knows that it is successful loading and they don’t have to reclick the link. This will make the site more usable and as more developers and designers begin to adopt this process the web itself will become more usable.
Additionally it opens up a new area for us designers to work our creativity. We can now think about what subtle design elements we can give links and buttons to indicate to the user that they have been clicked. In my example, a beveled button appears to be pushed inward.
It Isn’t Perfect
Despite the fact that it is a dramatic improvement over not having any feedback and it does give us more room to express our creativity, the functionality isn’t perfect. You may notice in the demo that if you click on a button quickly it changes so fast you might not even notice. You may not realize that there is even an effect giving you feedback.
Regardless, using :active will still enhance the user experience. Even if only 10% of your users notice it is worth the time and effort put into it. Additionally users who are less familiar with computers and the internet will be more likely to hold the mouse button down longer and thus notice the effect.
Consider Adopting it as a Regular Practice
I really advocate the adoption of it as normal standards based markup. If it becomes a convention than users will expect some sort of notification that a link was clicked and even it happens to fast on the pages that load right away, they know to look for it.
Similar Posts
- Making a post about them every once in a while
- Having a top commenters widget
- Use gravitars
- Giving the top commenters a dofollow link
- Giving top commenters profile/link on the home page
- Giving top commenters a special design when they do comment, do occasional giveaways, etc…
- Use the dofollow plugin, so high quality commenters can get some SEO value from contributing.
- Show the user where they can go, and
- Show the user where they currently are.
- There is not enough attention in making them usable. This could be poor validation, improper labeling of required fields, making them too long or poor form layout.
- There is not enough attention to what information is asked from the user.
- The Web Content Style Guide: The Essential Reference for Online Writers, Editors and Managers
- Quality Web Content
- Related pages / articles / posts
- Links to rich media
- Latest news / updates
- Previously viewed pages
- A contact form
- Ways to save / share the page
- Newsletter sign up
- Turning off unnecessary items such as the header, footer, navigation, search box etc…
- Changing the font to serif, increase the font size and space out the line height to make the print version more legible
- Adjust the columns or remove sidebars so that only the primary content prints out
- Are users leaving a specific page more than others? Maybe they are not finding what they are looking for and that page can bet altered
- Do you have a page where a lot of people are entering the site other than the homepage? You need to start thinking of those pages as landing pages
- Are there important pages that don’t get a lot of traffic? Figure out how you can make those pages more prominent
- You want to offer a “stylish” low-contrast and an easy-to-read high-contrast version of your site.
- You have many low-vision readers and want to give them easy access to a customized stylesheet with a larger typeface.
- Your site is schizophrenic and you want to be able to change the look quickly.
- Is easily customized to fit the size and color scheme of your website.
- Is either fixed or variable height.
- Can automatically rotate through the tabs to draw interest.
- Pauses its rotation when the user interacts with it.
- Make your tabs all the same height
- Automatically rotate through your tabbed content
- Stop the rotation when the user is interacting with the content
- rotateSpeed is the number of milliseconds to wait before switching tabs.
- numTabs is a variable that will contain the total number of tabs in our box. We’re initializing it at the beginning so we can use it in all our functions.
- autoRotate is a variable we’ll use later.
- Where am I?
- Where can I go?
- Where have I been?
Engaging Readers, Design Your Way to More Blog Comments
You have probably read the studies that claim on average, 1% of online users actually contribute and create content on a given website. The rest are perfectly happy reading your posts, forming their own opinions, and moving on to the next blog with out ever actually leaving any sort of feedback. This makes sense of course, we don’t always have time to leave our thoughts on blogs, or many times it doesn’t even seem worth the effort. After all you have to formalize your thoughts, actually write them out, review, edit, post, and then monitor for responses.
It actually is a lot more involved than we probably realize.
It is also a lot more important to get this type of reader interaction than we probably realize. The amount of interaction generated through a blog is an easy indicator of it’s success. Not only for the blog owner, but also to other readers. Consider looking at two blogs with similar content, one with an average of 10 – 20 responses where the other only has 1 – 3.
I hate to say it, but most people would subscribe to the blog that is generating more interest and response, even if the content was of similar quality.
How Design Can Encourage More Blog Commenting
When people blog about “design” in regards to websites many times they are primarily referring to the asthetic quality of a site. While the aesthetic quality of a site can have a large impact on how many people put in the effort to comment on a blog, I want to approach the situation at a higher level.
Consider that the definition of design is “to assign in thought or intention; purpose.”
Design is not just making pretty visuals, but to craft your site with specific thought, intention and purpose. So the question then becomes, how can we build the site with the intention of encouraging users to leave comments.
Create an Incentive or Reward
The primary reason anyone is going to leave a comment on a blog is they believe that their will be some pay off that is worth their time to formulate their response, edit it, etc… In most cases it is because they have a feeling about the content to the point where they feel the need to get their thoughts off of their chest, or maybe the author is well known enough where the idea of talking with them would be the reward.
However not all blog posts will have content compelling enough, or an author well known enough to create the incentive and reward with those elements alone.
Highlight Your Commenters
Smart marketers have found that the higher that you can appeal on Maslow’s hierarchy of needs, the better success you will have reaching your audience. By highlighting those who really participate you are appealing to the need of “esteem.”
You could do this by:
Give Your Commenters a Bonus
I have seen great response to giving the top commenters some sort of bonus. Widgets that keep track of who has commented the most make this an easy endeavor to track and monitor.
Some of the more common methods could be:
Use Design and Visuals to Engage Users
While I have talked about “design” in terms of designing an experience or functionality, I haven’t addressed the actual visuals of a design and how it can improve the amount of user interaction.
If you pay enough attention to the design and visuals of your comments, you can catch the attention of users and encourage them to leave a comment.
Make Your Comment Area Eye Catching and Interesting
As a users gets closer to the bottom of an article or post, you can bet that they have either scrolled past or lost focus of most of the visual elements on the page. This presents an excellent opportunity to draw their eye to the comment area by just adding a little bit of flair, tension, or contrast to develop some visual interest.
Want to really get some attention? Consider using custom designed form fields (not too custom as to hinder user experience).
Be Suggestive
Suggest that a user leave a comment where ever you can! At the start of the comments create a link to add a comment. You could even go so far as adding a “reply” button/link at every comment in the list.
Additionally this will make it easy to comment, as users won’t have to hunt for the add comment link.
Highlight the Commenters
People leave comments because they want people to read their opinion (even if it is just the author). Make sure that the users name/link has enough visual emphasis. This will help establish that the commenter will get the recognition that they are seaking.
Again, use Gravitars. Users who have gone so far as creating a gravitar will appreciate being able to show their branding on another blog and are more likely to comment because of it.
Any Experiences or Tips?
These are some of the best methods I have come across, if you have any experiences, tips, or other ideas on how to encourage more users to participate through the design of your blog/website feel free to leave a comment with your thoughts.
ClickTale: Watch what your visitors are doing
Analytic services provide valuable stats to web site owners and can be the only way of determining if a design is really working or not with real users. ClickTale hopes to up the ante by recording user actions so you can see every mouse movement, every click, and every scroll. Then the service lets you, the owner, see exactly what the user did. Perfect for testing usability. Currently ClickTale is a closed beta but you can sign up for updates by email. A web 2.0 site that is plum purple? I like it.Read | Permalink | Email this | Linking Blogs | CommentsUsing JavaScript to Style Active Navigation Elements

I’m all about efficiency when I’m writing web code. Any time I find myself writing the same functionality more than once or twice, I try to consider whether my repeated code could be wrapped into a function of some sort.
Navigation is often one of those areas where I try to improve my efficiency. I like my navigation elements to pull double duty. I want them to:
In other words, I want some sort of visual indication in my navigation that shows my user which section of my site they’re in. You can see this on the CSS Newbie site: if you click on the TOC (Table of Contents) link in the bar at the top of the page, you’ll see that link gets special styling when the table of content loads.
Now, I could manually set this on every page using a CSS class. But that’s inefficient — depending on the size of my site, I could end up writing dozens or hundreds of lines of one-off code. And why go to all that work, when you could just wrap it all up into a nice JavaScript function?
First, I’ll explain the logic behind my functions — because they won’t work equally well for every site. Then I’ll walk you through a few examples of the code that makes it all happen.
The Logic
All of my functions assume a very clean, straightforward directory structure. For example, if you have an About section, a Blog section, and a Contact section on your site, a logical directory structure might be:
/ /about/ /blog/ /contact/
And if you had several blog entries inside your blog directory, your structure might grow like this:
/ /about/ /blog/ /blog/post-one/ /blog/post-two/ /blog/post-three/ /contact/
And therefore, a function could logically assume that anything inside the blog directory should be considered a part of the blog section of your site, and mark the blog link as active for those pages. This makes our job a lot easier. And luckily, most CMS platforms make this sort of directory structure pretty easy to create.
The functions also assume that you have either a fairly shallow directory structure, or that you’re not linking to too many similarly nested directories. What I mean by this is, if you have this sort of a structure:
/ /contact/ /contact/me/ /contact/me/here/
And you wanted to link to both /contact/ and /contact/me/here/ in your navigation bar, you might run into problems distinguishing between the two. There are ways to increase precision, but they come at the cost of flexibility.
But enough of that. Let’s get to the good stuff!
A JavaScript Solution
I’ve written about this method before, when I previously talked about building intelligent navigation bars. This technique is nice because it doesn’t rely on any JS frameworks, so you can add it to older sites without needing jQuery or the like. The basic function looks like this:
function setActive() {
aObj = document.getElementById('nav').getElementsByTagName('a');
for(i=0;i<aObj.length;i++) {
if(document.location.href.indexOf(aObj[i].href)>=0) {
aObj[i].className='active';
}
}
}
This function looks for an element with an id of “nav” (presumably your navigation bar), then looks at each of the anchor tags inside it. It then compares the anchor tag’s href tag with the page’s URL. If the href tag is contained within the URL anywhere, it gives that link a class of “active,” which I can then style specially in my CSS.
As an example of what I mean by all that, if I had an anchor tag in my navigation bar that linked to “/blog/” and the page I was on was “/blog/this-is-a-post.html”, my blog link would be styled as active, because “/blog/” is contained within “/blog/this-is-a-post.html”.
As a final note, you wouldn’t want to call this function until the page was finished loading: if you call it too soon, your links won’t exist yet! So you can either call it at the very end of your document, or dynamically call it when your page is done loading, with something like this:
window.onload = setActive;
A jQuery Solution
If you are already loading a framework like jQuery (like I do on almost every site I work on these days), this sort of functionality could be written even more succinctly. And like I said earlier, I’m a sucker for efficiency. Here’s a jQuery solution that does essentially the same thing in a much smaller space:
$(document).ready(function() {
$('#nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
});
This function is making use of both native JavaScript and jQuery tricks to reach a whole new level of brevity. First, the whole thing is wrapped in a “document ready” function, which means it won’t fire until the page is loaded and our links are in place. Next, we’re looking for anchor tags inside our “nav” ID. And really, we’re looking for a very specific anchor tag: one whose href starts with (^=) a slash, followed by a part of our page’s location (location.pathname). Specifically, we’re looking for the first directory in our page’s URL.
We’re doing this by making use of the JavaScript split() method, which lets us take any string (for example, “/blog/this-is-a-post.html”) and break it into an array based on a substring (in our case, the forward slash). If you’re familiar with PHP, it’s similar to the explode() function. In our example, we’d end up with a three-part array that looked like this:
["","blog","this-is-a-post.html"]
Which means that if we look at the second value of our array (arrays start counting at zero, so [1] is the second value), that should give our first-level directory (”blog”, in our example). This lets us match any subsequent child directories with our parent in the navigation bar.
Tweaking for Home Links
Our jQuery function works great in most scenarios, but it fails if you have a “home” link where you’re just pointing to the root directory, like this:
<a href="/">Home</a>
And because I tend to have a link like that, I needed a workaround. Here’s a way to get around that with just a little more code to account for our special case:
$(document).ready(function() {
if(location.pathname != "/") {
$('#nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
} else $('#nav a:eq(0)').addClass('active');
});
Here, we’re checking to see if we’re in the root directory. If so, we’re skipping the loop through our anchor tags and just making a specific anchor tag active. In this case, I’m giving the active class to the first anchor in our list (which is the most common location for a home link).
And that’s that. If you know of even more efficient or fool-proof ways to accomplish this task, I’d love to hear about them in the comments section. Or if you’re skilled in a framework other than jQuery, feel free to share the equivalent code!
Note: I apologize for the long gap between articles. I had some problems while rebuilding my PC (DOA motherboard) and was without my computer for several weeks.
Five commonly neglected parts of a website that deserve detail
There are some great websites out there. They are well planned, well executed, well designed and simply effective. For every great website there are three that are could be great, but fall short due to a few small areas of neglect.
We as a community and as an industry have become very good at most aspects of building websites. Just looking through a few CSS Galleries clearly shows the quality of design that is being produced and how much it has improved in just a few years. If you look a layer deeper and view the source of these websites you will see beautiful and semantic XHTML/CSS. It seems the days of table based layouts is finally gone.
The amount of functionality and rich experience that sites have now day are creative, impressive and engaging. Powerful javascript libraries such as jQuery, MooTools and prototype make it easy to produce these experiences rapidly and effortlessly.
But a website is more than the design, code and effects/functionality. Sometimes we have to rethink our approach and find out what is really important. What are the sites objectives and what are our users objectives? More often than not you will find that you could improve the following areas of your websites:
1. Web forms
While they are far from the sexiest part of web design, web forms are arguably one of the most important. In almost all cases a web form also functions as a conversion point (a point where a user performs an action that accomplishes a site objective).
Here a user is going to enter in some of their personal information so that they can get something in return. This establishes interest and provides the site owner with some valuable information.
Web forms are often neglected in two ways:
You have a real opportunity to learn more about the people who use your website. That information can not only help you build a better website but also a better business. This marketing information could easily lead to R&D improvements and better products.
Do some research and learn how you can make more effective forms. Your clients, bosses and website owners will thank you many times over.
Resources
2. The Content
Content is king. In a recent study 25% of users noted that the number one reason they were to leave a website was due to “weak web copy.” The only reason anyone ever goes to any website is because of the content, yet so many website owners neglect the content. Despite it’s importance content becomes an afterthought. Appearance, search rankings and conversions tend to be the focal point of most web design projects. What we may forget is that with out great content you still have a poor appearance, you won’t rank high and no one will convert.
Rather than trying to write all of the content yourself, hire someone. It will be worth it, I promise you. If nothing else write the bulk of the copy and hire someone to make it consistent with the proper voice and tone.
Resources
3. The Footer
With a little thought it becomes painfully obvious, most website footers are absolutely useless. A user takes the time and effort to read (or scan) through an entire page, and when they reach the bottom they are rewarded with links that don’t fit anywhere else, a copyright notice and maybe an address and phone number.
The point where page content ends is a very high action zone. That means that users who get to that point have a high probability of clicking on any link that comes below it. Rather than some meaningless legal links and an address create a footer that gives the user a place to find additional content that may interest them.
This could be:
Resources
4. The Print Version
Many designers fail to realize how many people still prefer to print off websites rather than try and read them on screen. There are two significant benefits to paying attention to the print version.
The most obvious benefit is that it can improve the user experience of the site. Users who visit your site and print it out will actually read the content and are more likely to revisit the site and make an action (or conversion). If the printed version is difficult to read and work with they are highly likely to simply recycle the paper and forget they ever visited your site in the first place.
The second benefit is it could be a real competitive advantage. If a user prints off two web sites, and yours clearly has more attention to detail in the print version, they are much more likely to use your product/services over the competitors.
You can improve the print version simply by:
Resources
5. Analytics
How users behave and use a website is one of the most important factors you could possibly focus on. Despite this fact it is so commonly neglected by both website owners and website designers. Businesses need to spend more money on the analysis of user behavior and web design companies need to promote the service more heavily.
Even a website that is built using an effective strategy, user testing and best practices is a best guess at what will be most effective.
If you actually pay attention to how users behave and analyize that behavior you can discover countless ways to continually improve your website.
Resources
A Simple jQuery Stylesheet Switcher
There are lots of reasons you might want to offer your users more than one CSS file for your website:
Whatever the reason, it’s amazingly easy to create a function that swaps between multiple stylesheets using jQuery.
The first step of course is to build several different CSS files, which we’ll then swap between. Once that is done, we can dive into the XHTML and jQuery that makes the magic happen.
The XHTML
First, we need to create a set of links that will allow the user to swap between CSS files. You can make this as simple or as fancy as you’d like. For the sake of brevity, my links are simple:
<ul id="nav"> <li><a href="#" rel="/path/to/style1.css">Default CSS</a></li> <li><a href="#" rel="/path/to/style2.css">Larger Text</a></li> <li><a href="#" rel="/path/to/style3.css">Something Different</a></li> </ul>
Here I have three links, each with a “rel” attribute indicating which CSS file the link will load. Technically, I could have just as easily put this information in the “href” attribute, but I didn’t want to for one specific reason: if the user has JavaScript disabled and the CSS file is listed in the href, then clicking the link will send the user to the CSS file directly (not loading it like we intended). But our way, if JS is disabled, the user gets nothing at all: which is certainly preferable to the less savory alternative.
The jQuery
Like I promised, the jQuery is really simple:
$(document).ready(function() {
$("#nav li a").click(function() {
$("link").attr("href",$(this).attr('rel'));
return false;
});
});
This function waits until the document is loaded (generally an important step when interacting with the DOM), then attaches a click function to each of our nav anchors. The function basically says, “when someone clicks on this link, replace the link (stylesheet) tag’s href attribute with the contents of this link’s rel attribute.” The “return false” at the end just stops the browser from trying to follow the link.
Of course, you might have to get more detailed if you have more than one link tag, for example, but that’s easily done by giving the link tag a class (”changeme,” for argument’s sake), and writing something like this:
$("link.changeme").attr("href",$(this).attr('rel'));
And while this stylesheet switcher is already complete, we might want to give it some memory: after all, your users might get annoyed if they have to switch their styles back to their preferences every time they visit your site. For that, we’ll need to set a cookie. And to make that easier, I’ll use the jQuery cookie plugin (which I’ve talked about previously when building a popout ad).
With the plugin loaded, we can modify our jQuery thusly:
$(document).ready(function() {
if($.cookie("css")) {
$("link").attr("href",$.cookie("css"));
}
$("#nav li a").click(function() {
$("link").attr("href",$(this).attr('rel'));
$.cookie("css",$(this).attr('rel'), {expires: 365, path: '/'});
return false;
});
});
Now we have two statements. The first one checks as soon as the page is done loading to see if a cookie called “css” has been set. If so, it sets the stylesheet to be the one indicated in that cookie. Otherwise, it does nothing.
Our click function is much the same, except after we set the stylesheet, we also set a cookie. This cookie doesn’t expire for an entire year (and each time the user changes their stylesheet preferences, it would reset this timer), giving them a good 365 of CSS bliss.
Fine Tuning
There is one minor annoyance with this stylesheet switcher: there’s generally a flash of the “default” CSS when the user loads the page. That’s because the script waits until the document is “ready” before switching the link’s href. There is a way around this: moving the first “if” statement outside of the document ready function, like so:
if($.cookie("css")) {
$("link").attr("href",$.cookie("css"));
}
$(document).ready(function() {
$("#nav li a").click(function() {
$("link").attr("href",$(this).attr('rel'));
$.cookie("css",$(this).attr('rel'), {expires: 365, path: '/'});
return false;
});
});
Generally speaking, you don’t want to run any jQuery until your document is ready. However, so long as your jQuery comes after your link tag in your document structure, like shown below, this shouldn’t be a major concern:
<link rel="stylesheet" type="text/css" href="style1.css" /> <script type="text/javascript" language="javascript" src="jquery.js"></script> <script type="text/javascript" language="javascript" src="jquery.cookie.js"></script> <script>... your jQuery goes here...</script>
This means your jQuery will run before the document is done loading, and thus your link tag’s href will be swapped before your CSS has been applied. As I said before, it’s generally a bad idea to manipulate the DOM before document ready, but because we know the exact tag we want to manipulate and can place our jQuery below it in the DOM, we should be safe in this one specific instance.
Here’s an example if you would like to see this technique in action.
Build a Tabbed Box with CSS and jQuery

The longer a site has been around, the more content it tends to accumulate. As website operators, we walk a fine line: too much content on every page and your site will look cluttered. Too little, and users won’t be able to find all your website has to offer. A tabbed box like the one pictured above is a nice bridge between the two extremes. It allows you to show off a large amount of content without cluttering up a lot of space. And this tabbed box has extra niceties that are sure to help your content get noticed.
What it Does
At the end of this two-article series, you’ll be able to build a tabbed content box of your own that:
This article will show you how to take the tabbed box from Photoshop to XHTML and CSS, and how to apply the basic jQuery functionality to make the tabs operate. The next article will show you some advanced jQuery techniques to make your tabbed box even more dynamic and eye-catching.
The Photoshop Mockup
Like most of my projects, this one started life as a drawing roughly sketched out on a piece of paper. Despite all the cool tools we web developers have at our disposal, paper and pencil are still by far the fastest way to rapidly prototype a new idea. Here’s a crappy iPhone photo of the drawing:

This is what I mean when I say I’m not a designer, people.
Once you have a good idea as to what you’re looking to do with your tabbed box, it’s time to move into Photoshop (or a similar editing tool). If you’re looking for an extremely barebones tabbed interface you can probably skip this step entirely, but I wanted my tabs to have a little pizzazz. Here’s a look at my Photoshop document:

It’s nothing fancy: just two layers with gradients, a layer creating my borders, and my text. Of course, your layout may be more complex than mine.
When I’m working in Photoshop, I like to stop and think about how I’m going to actually develop what I’m building (and I’d advocate you do the same!). In this case, I knew that I wanted gradients on both my unselected tabs as well as the content box and that my unselected tabs should appear faded. Once I had a pretty good mockup in place, I could start to visualize how my XHTML and CSS would work together to produce the result I was looking for.

The XHTML
Here’s the basic XHTML I decided on for my tabbed box:
<div class="tabbed-box"> <ul class="tabs"> <li><a href="#">Tab #1</a></li> <li><a href="#">Tab #2</a></li> <li><a href="#">Tab #3</a></li> </ul> <div class="tabbed-content"> <p>Here's my content for tab 1</p> </div> <div class="tabbed-content"> <p>Here's my content for tab 2</p> </div> <div class="tabbed-content"> <p>Here's my content for tab 3</p> </div> </div>
I wanted to keep my XHTML as simple as possible, so that if I ever wanted to update the content my tabbed box, I wouldn’t have to dig through a lot of extra code to do so. The box has three basic components: a wrapper div (tabbed-box) that holds my entire box together, an unordered list with links that will function as my tabs, and a series of divs (tabbed-content) to function as the containers for my tabbed content.
I decided early on to stay away from extra IDs on all my elements as much as possible, to keep the updating process as simple as possible. Of course, that meant my jQuery would have to work smarter to figure out how the box works… but we’ll get to that later.
The CSS
Developing the CSS for this box does take a little math and a good understanding of the box model, but it’s not overly complex. First we’ll style our container box:
.tabbed-box {
width: 302px;
background: #fff url(tabbed-body-bg.jpg) repeat-x bottom;
border: 1px solid #ddd; }
The width here is the most difficult number to determine. To come up with the number, I need to know two things: how much space I have to work with, and the number of tabs I plan to have. (I could probably calculate all this dynamically in jQuery, but I prefer to use CSS to accomplish as much as possible before turning to scripting.)
The space allotted is determined by the size of the tabbed box’s containing element: I built this box with CSS Newbie’s sidebar in mind, which gave me just over 300px of breathing room. Next up, I need to consider the number of tabs I’ll have. My box will have three tabs. If each of those tabs are 100px wide, they then use 3 * 100 (300) pixels of space. But don’t forget: according to our design, two of those tabs will need a border on one side to create the tabbed effect. This results in another two pixels added to our width, for a total of 100 * 3 + 2 (302) pixels. But remember, with the borders I added to my tabbed-box class, my final overall width is 100 * 3 + 2 + 2 (304) pixels.
Next up, we’ll style our tabs:
.tabbed-box .tabs li {
list-style: none;
float: left; }
.tabbed-box .tabs li a {
display: block;
width: 100px;
padding: 5px 0;
font-weight: bold;
text-align: center;
text-decoration: none;
color: #888;
background: #fff url(tabbed-tab-bg.jpg) repeat-x bottom;
border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;}
.tabbed-box .tabs li:first-child a {
border-left: none; }
First I’m removing the list style and floating my tabs to the left to get them lined up horizontally. Next I’m making them block-level, so the entire tab becomes clickable. Then I’m setting them to the appropriate width (100px in this case), giving them some padding, styling the text, applying my gradient background, and applying my borders to the left and bottom sides.
Next I have a rather specific rule: I’m removing the left border on the first-child element: this means that my very first tab won’t have a border on its left side, since the containing box has a border there and we don’t want to double up. Of course, first-child isn’t supported by Internet Explorer 6… but don’t worry, we’ll account for that in our jQuery.
Then all we have left to get our tabs in working order is to set how they behave in three states: hover, focus, and “active”:
.tabbed-box .tabs li a:hover {
color: #333; }
.tabbed-box .tabs li a:focus {
outline: none; }
.tabbed-box .tabs li a.active {
background: #fff;
color: #333;
border-bottom: 1px solid #fff; }
I’m giving my tabs a slightly darker text color in the hover state, to help the user see when they’re hovering. The focus state is there simply to remove the resulting outline in Firefox when the user clicks a tab: if you’re one of those who insist on having a focus state, feel free to leave this rule out. And finally, we have an active class. This class will be applied by our jQuery to the tab that is currently open. Here we’re removing the bottom border and changing the background color to give it the appearance of an open tab.
And last but not least, we need to apply some styles to our tabbed-content divs:
.tabbed-content {
padding: 3em 1em 1em 1em;
display: none; }
The padding simply pushes the content away from the edges of our box. You can set this to whatever you wish. And our display rule hides all our content, until it’s called upon by our jQuery.
The jQuery
Since we’re using the jQuery library to do most of our heavy lifting here, you’ll need to include the jQuery library somewhere above the following code.
Because I decided to write my XHTML without a lot of extra IDs and classes, my jQuery is going to have to be a lot smarter when it comes to figuring out which tabs display which content. My rationale is pretty straightforward: the first anchor in my unordered list should open the first tabbed-content div, the second one the second, and so on down the line. Because our logic is so straightfoward, I can rely on the jQuery index functionality to do a lot of the hard math.
var currentTab = 0;
function openTab(clickedTab) {
var thisTab = $(".tabbed-box .tabs a").index(clickedTab);
$(".tabbed-box .tabs li a").removeClass("active");
$(".tabbed-box .tabs li a:eq("+thisTab+")").addClass("active");
$(".tabbed-box .tabbed-content").hide();
$(".tabbed-box .tabbed-content:eq("+thisTab+")").show();
currentTab = thisTab;
}
I start out by declaring a global variable that I’ll use throughout the script: currentTab. The currentTab variable will hold the index (an internal counter, like in an array) of the tab we’re currently on. It will also serve later to decide which tab we open by default.
Our function looks more complicated than it is. It requires one variable to be passed it: the clickedTab variable, otherwise known as the tab the user just clicked on. It then calculates the index of that tab (if it was the 3rd tab, the index would be 2) and saves that number as thisTab.
Next, the script cycles through all our tabs and removes any instances of the “active” class if finds, before cycling through a second time and applying the active class to the tab that has the same index number as the tab that was clicked on (in other words, the same tab). This ensures we only ever have one active tab at a time. Then we cycle through our content boxes, hiding them all before cycling through again and showing only the one box that has the same index as our tab… meaning if the third tab was clicked, the third box will open. That bit of math is what saves us from having to apply IDs to all of our tabs and content boxes. Then we set the currentTab variable to our newly open tab’s index.
Now that our function is written, we can get our tabbed box ready for prime time:
$(document).ready(function() {
$(".tabs li:eq(0) a").css("border-left", "none");
$(".tabbed-box .tabs li a").click(function() {
openTab($(this)); return false;
});
$(".tabbed-box .tabs li a:eq("+currentTab+")").click()
});
The first line in our document ready function removes the left border of the first tab. Our CSS handled this for all browsers but IE6, but this bit of code takes care of IE6 as well.
Next, I’ve written a click function that will fire any time anyone clicks on any of our tabs. It only has two parts. First, it fires the openTab function, sending it a variable called “$(this)”. In jQuery, the $(this) variable in a function is always populated with the element on which the function was applied. So if the user clicks on the 2nd tab, our $(this) variable would contain that element. The “return false” after our function prevents the browser from trying to go to whatever we put in our anchor’s href.
And last but certainly not least, our final line forces a click on the tab with an ID that matches currentTab. In my example, that’s the first tab, but you can set currentTab to whatever you’d like to start, so long as currentTab is at least one less than the total number of tabs (since we start counting at zero).
And with that, we have a functioning tabbed box!
You can see this box in action here. The demo contains all the XHTML, CSS and jQuery you need to get this box up and running on your own site.
My next article will cover some advanced tricks you can do with this box, like getting it to cycle through automatically to catch the user’s eye… and how to stop the box from cycling once it has the user’s attention. To be sure to catch the article, you may want to subscribe to my newsfeed.
Advanced jQuery Tabbed Box Techniques
Last week’s article covered how to build a tabbed box interface, starting with Photoshop, and moving through XHTML and CSS to our basic jQuery functionality. If you missed it, I would highly recommend starting your reading there. This article will show you how to use jQuery to make your tabbed interface more attractive and interactive. Specifically, I’ll show you how to:
Equal Height Tabs
The tabbed interface we built last week was fully functional, but one nicety I’d like to add is the option to have all your tabs be the same height – a height that is determined by the content within the tabs, not any number I arbitrarily determine in advance.
While there are several ways to calculate and apply height in jQuery, the fastest and easiest means to our end would be to use the equalHeights jQuery plugin I developed and wrote about recently. By using that plugin, we’d only have to make a single addition to the “document ready” portion of our jQuery:
$(".tabbed-content").equalHeights();
This will cycle through all of our tabbed content divs and equalize their heights based on the height of the tallest div. The benefit of this is the content around our tabbed box won’t shift up or down each time the user switches tabs, resulting in a more pleasant visual experience.
Rotate Through Tabbed Content
While tabbed boxes like the one we’ve built are a great way to fit a large amount of content in a small space, they do have one drawback: many users never click through the tabs to see what all is offered, meaning they only ever see the content on the first tab. My proposed solution to this problem is to automatically rotate through the tabs.
This solution has two benefits: first, the movement is more likely to catch the users’ eyes, increasing the chances they’ll notice the tabbed box in the first place. Second, it allows your users to see all the content your box contains instead of just the first tab.
Making this adjustment to our jQuery requires edits in several areas, so I’ll show you the new code in its entirety before explaining what it all does:
var currentTab = 0;
var rotateSpeed = 5000;
var numTabs;.
var autoRotate;
function openTab(clickedTab) {
var thisTab = $(".tabbed-box .tabs a").index(clickedTab);
$(".tabbed-box .tabs li a").removeClass("active");
$(".tabbed-box .tabs li a:eq("+thisTab+")").addClass("active");
$(".tabbed-box .tabbed-content").hide();
$(".tabbed-box .tabbed-content:eq("+thisTab+")").show();
currentTab = thisTab;
}
function rotateTabs() {
var nextTab = (currentTab == (numTabs - 1)) ? 0 : currentTab + 1;
openTab($(".tabbed-box .tabs li a:eq("+nextTab+")"));
}
$(document).ready(function() {
$(".tabbed-content").equalHeights();
numTabs = $(".tabbed-box .tabs li a").length;
$(".tabbed-box .tabs li a").click(function() {
openTab($(this)); return false;
});
autoRotate = setInterval("rotateTabs()", rotateSpeed);
$(".tabbed-box .tabs li a:eq("+currentTab+")").click()
});
The first variable, currentTab, is unchanged from our first iteration. But then we’ve added three new variables:
Our openTab function hasn’t changed. If you’d like to understand how it works, please refer to the first article.
Next we’ve written a new function called rotateTabs. This function will handle the math required to determine which tab should be opened next. First we set a new variable, nextTab. What we set nextTab to depends on which tab we’re on currently. The function looks at currentTab: if currentTab is our last tab in the list, it starts back over at the beginning (the tab with an index of 0). Otherwise, nextTab is simply the next tab in the list. Once we’ve determined our next tab, we call the openTab function, which prevents us from having to duplicate all that heavy lifting.
We’ve added two lines to our document ready function. The first sets the numTabs variable to be the number of tabs in our box. We don’t populate this variable until the document is ready, because otherwise it will try to count the tabs before our tabs have loaded and will return a length of -1 (aka, none found).
The second bit we added is towards the end, where we set autoRotate. In autoRotate we’re calling the JavasScript setInterval function, which executes a piece of JavaScript on a regular interval. As we’ve written it, we will be calling our autoRotate function every “rotateSpeed” milliseconds. This means that when our document loads, it will wait that many milliseconds, then switch to the next tab, then pause again, then switch again infinitely.
Pretty neat, huh? You can see this functionality in action here.
Stopping the Rotation
Now, automatically rotating your tabs is a pretty awesome effect, but at some point you’re probably going to want that rotation to stop. Specifically, you don’t want your tabs switching when your users are interacting with them.
I tested several scenarios on when and how to stop the tabs from rotating before deciding on how I’m doing it here. It only requires editing a couple of lines from our document ready function:
$(document).ready(function() {
$(".tabbed-content").equalHeights();
numTabs = $(".tabbed-box .tabs li a").length;
$(".tabbed-box .tabs li a").click(function() {
openTab($(this)); return false;
});
$(".tabbed-box").mouseover(function(){clearInterval(autoRotate)})
.mouseout(function(){autoRotate = setInterval("rotateTabs()", rotateSpeed)});
$(".tabbed-box .tabs li a:eq("+currentTab+")").click()
$(".tabbed-box").mouseout();
});
Here we’ve replaced our setInterval function with something a little more complex. We’re now using both setInterval and clearInterval (which stops setInterval), and we’re applying them when the user’s mouse interacts with our tabbed box.
Specifically, we’re letting the box auto-rotate whenever the mouse is nowhere near the box, and stopping the box from rotating whenever the mouse is over the box. This means that as long as the user has the mouse over the box, as if they were reading, or clicking through the tabs, or clicking on something inside one of our tabs, the tabs wouldn’t switch on them. But as soon as they’re done interacting with the box, it’ll switch back to its regular rotation.
This does require one extra line at the end of the script, to force a “mouseout” event on the tabbed box, which gets things rotating by default.
You can see our fully functional tabbed interface here. Give it a try: watch it rotate through, and then try interacting with the box a bit. You’ll see that the tabs don’t automatically move, as long as you’re actively engaged with the box.
And that’s that! I hope you’ve found this mini-series helpful, and I’d love to see how you’ve implemented this idea on your own websites. Drop me a line in the comments below if you do.
Three timeless navigation tips
It’s 2006, and we’re still talking about site navigation? Yes, we are; and apparently we need all the reminders we can get, since so few sites seem to get it right. (Including, I’m well aware, CSS Insider. Don’t hate; I didn’t design it.)In his new A List Apart article (“Where Am I?”), Derek Powazek slaps us upside the head, again, with the cardinal rules of web site navigation. From any page on a site, a user should be able to easily answer these three questions:
Derek provides visual examples of great site navigation. Put your site to the test! Do you know where you are, where you’ve been, and where you’re going?Read | Permalink | Email this | Linking Blogs | Comments

