Build a Tabbed Box with CSS and jQuery

Published January 18, 2009 by CSS Newbies.

tabbed box

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:

  • 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.

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. Read On…

Show/Hide Content with CSS and JavaScript

Published May 5, 2008 by CSS Newbies.

There are plenty of reasons why you might feel the urge to wax verbose on your website’s front page: to prevent your users from having to click through to a new page to find your information, to avoid having to reload the page, or even to improve your front page’s SEO. But just because your front page is text-heavy doesn’t mean it all needs to be visible at once.

Today’s tutorial will show you how to hide away extra bits of content using CSS and JavaScript, to be revealed at the click of a button. This is a great technique, because displaying the additional content doesn’t require a refresh or navigation to a new page and all your content is still visible to search engine bots that don’t pay any attention to CSS or JavaScript.

We’ll start with structuring our XHTML appropriately:

<p>...This is all visible content... 
<a href="#" id="example-show" class="showLink" 
onclick="showHide('example');return false;">See more.</a>
</p>
<div id="example" class="more">
	<p>...This content is hidden by default...</p>
	<p><a href="#" id="example-hide" class="hideLink" 
	onclick="showHide('example');return false;">Hide this content.</a></p>
</div>

There are three things of importance here: the “show” anchor, the “hide” anchor, and our “hidden” div. Each has been given an ID and a class. The IDs are used by our JavaScript to locate and style the items appropriately. I’m then using the classes to set our “default” CSS. Technically you could just use the IDs the set that CSS as well, but if you wanted more than one hidden section on your page, that could get messy.

You’ll notice in the code above that all of our IDs are fairly similar. This is a trick I’m using to simplify our JavaScript, as you’ll see later on down the road, so I suggest doing something similar. The class names have no relationship to the JavaScript whatsoever, and could really be whatever you wanted them to be.

It’s also important to note that we’re calling our JavaScript using the “onclick” call, and passing it the name of our hidden div. Our JavaScript will use that single variable to do the rest of the work.

Now that we have our XHTML in place, let’s put together our default CSS:

.more {
	display: none;
	border-top: 1px solid #666;
	border-bottom: 1px solid #666; }
a.showLink, a.hideLink {
	text-decoration: none;
	color: #36f;
	padding-left: 8px;
	background: transparent url('down.gif') no-repeat left; }
a.hideLink {
	background: transparent url('up.gif') no-repeat left; }
a.showLink:hover, a.hideLink:hover {
	border-bottom: 1px dotted #36f; }

I’m technically doing far more styling than is necessary here, mostly for aesthetic purposes. The only truly important style is the “display: none;” rule on our .more class. This hides our extra content by default. The rest of the CSS simply adds a border to our div (the border is hidden by the display rule, but becomes visible later) and fancied up our show/hide anchors by putting down/up arrows next to them and replacing the standard underline with a dotted border. You could style these yourself however you like, and everything would still work just fine.

Next comes the JavaScript, which looks far more complicated than it is:

function showHide(shID) {
	if (document.getElementById(shID)) {
		if (document.getElementById(shID+'-show').style.display != 'none') {
			document.getElementById(shID+'-show').style.display = 'none';
			document.getElementById(shID).style.display = 'block';
		}
		else {
			document.getElementById(shID+'-show').style.display = 'inline';
			document.getElementById(shID).style.display = 'none';
		}
	}
}

Our JavaScript is doing four things here:

  1. It checks to see if it can find an element with an ID that matches the variable we passed it.
  2. If so, it checks to see if our “show” link is visible (this is where the ID naming convention starts to matter).
  3. If the “show” link is visible, that means our content is still hidden. The JavaScript then hides the link and displays our hidden content.
  4. If the “show” link is hidden, that means our extra content is currently visible. So it just reverses course, displaying our link again and hiding our extra content.

And that’s it! You can see a working example in action here.

Our job has been made much simpler by a few tricksy tricks. First off, we’re using the same function to show and hide our content, which saves us a bit of coding time. Our function simply checks on the state of things: if things are hidden, it shows them, and vice-versa.

Second, by using a defined schema for our element IDs (“example,” “example-show,” and “example-hide,” in our example above), we only need to pass our JavaScript a single variable. It then uses that variable to find all of our other elements and style them appropriately.

And finally, we put our “hide this content” anchor inside the hidden div. This means that we never have to set its display property: it’s hidden when the container is hidden, and visible when the container is. That saves us two lines of JavaScript and at least one line of CSS.

This technique could be used in loads of situations. Say for example that you have a WordPress blog and the front page shows excerpts instead of the full article. You could use this technique to have the whole article on the front page for the search engines to find, visible to your users at the click of a button. Or maybe you have a complex form that could use some detailed in-page explanation, but you don’t always want the help content visible, eating up real estate when some users already know what to do. Or… well, anything, really. Let me know if you come up with any creative uses!

Perma-Closing Message Boxes with JavaScript + CSS

Published April 2, 2008 by CSS Newbies.

message box

Earlier this week I talked a bit about message boxes – how to style them and position them on your page to get them noticed. But a message that pops up every single time your website is loaded could get annoying. It’d be useful to give your users the ability to close those messages. For that, we’ll turn to our friend JavaScript.

We’ll start by building our message box in XHTML. Mine looks like this:

<div id="message-1" class="msgbox">
	<a href="#" id="close" title="Close This">X</a>
	<p>My uber-important message goes here!</p>
</div>

I’ve made a div with both an ID and a class. This will come in handy later when we need to reference our object in our JavaScript. Inside, I put an anchor tag with a class of “close.” This will become my close button later. And then I simply added a paragraph to hold my message.

Next up, we’ll want to style that message box. You can make it look pretty much however you want, and Woork has a nice article on styling message boxes, if you’re interested in discovering alternative styles. For my message box, I wrote this:

.msgbox {
	position: absolute;
	top: 15px;
	right: 20px;
	width: 20em;
	background-color: #b00;
	border: 1px solid #333;
	color: #fff;
	font-weight: bold; }
.msgbox p {
	margin: 0;
	padding: 5px 10px; }
.msgbox a.close {
	float: right;
	text-decoration: none;
	font-weight: bold;
	color: #333;
	background-color: #fff;
	border-left: 1px solid #333;
	border-bottom: 1px solid #333;
	padding: 0 4px;
	margin-left: 5px; }

Three rules are at play here. First, I’m styling the message box itself, using the class I gave it. I’m absolutely positioning the element and giving it a width. I’m also giving it a red background, bolding the text inside and turning it white, and applying a border. Then I’m applying a bit of styling to the paragraph inside to push it away from the side of the box.

Why didn’t I apply that padding to the message box itself? Because of the “close” link. I wanted to be able to float it to the right of the box and give it some styles to make it look more like a “close” button. After all of that CSS, this is what I have:

example message box

But so far, we just have a message box. That close button doesn’t do much of anything. For the rest, we’ll turn to JavaScript. All we need is a little function like this:

function closeBox(toClose) {
	document.getElementById(toClose).style.display = "none";
}

This function takes a single argument (toClose) which tells it the ID of the element we want to make disappear. We supply argument when we call the JavaScript. In this case, because we want it to happen when someone clicks our close box, we’d add it to our XHTML like this:

<a href="#" class="close" 
onclick="closeBox('message-1'); return false;" 
title="Close This">X</a>

We’ve added the “onclick” attribute to our “close” link tomake it fire a bit of JavaScript when the element is clicked. We’re telling it to call our closeBox function that we just wrote, and we’re giving it the ID of the message box we want to close. The “return false” part basically tells it to stop (that is, not to actually go to our specified href afterwards).

That’s all we need to create a message box that closes! However, if your users close the box and then refresh the page, the message box comes right back. What if we want it to close permanently? For that, we’ll need some more fancy JavaScript, because we’ll need to make use of cookies.

The cookie will act as a check that we can refer back to. When the user closes the message box, we’ll set a cookie. Then, when they come back to the page, we’ll check to see if the cookie is set. If there’s no cookie, we’ll show them the message. If there is a cookie, we’ll keep the message box hidden.

First, we’ll make a small change to our CSS:

.msgbox {
	display: none; /* Start out hidden. */
	position: absolute;
	top: 15px;
	right: 20px;
	width: 20em;
	background-color: #b00;
	border: 1px solid #333;
	color: #fff;
	font-weight: bold; }

All we’re doing is adding a “display: none” to the top of the element. By default, we don’t want our message box to show up. Instead, we’ll use JavaScript to display it if we want to see it. Why? It’s a usability thing: this way, if a user doesn’t have JavaScript enabled, they don’t see the message box. That may seem like a bad thing, but consider the alternative: if we didn’t set this rule, then anyone without JavaScript couldn’t get rid of your message box. And depending on its placement, that could be a big usability problem.

So now we need two extra functions in our JavaScript: one to set the cookie when we close the box, and another to check to see if the cookie exists when the user comes back. Our JavaScript now looks like this:

function closeBox(toClose) {
	document.getElementById(toClose).style.display = "none";
	setCookie(toClose, "closed", 365);
}
function setCookie(cName, value, expiredays) {
	var expDate = new Date();
	expDate.setDate(expDate.getDate()+expiredays);
	document.cookie=cName + "=" + escape(value) + 
	";expires=" + expDate.toGMTString();
}
function loadMsg(msgClass) {
	msg = document.getElementsByTagName("div");
	for (i=0; i<msg.length; i++) {
		if(msg[i].className == msgClass) {
			if(document.cookie.indexOf(msg[i].id) == -1) {
				msg[i].style.display = "block";
			}
		}
	}
}

First off, we modified our closeBox() function to make a call to the setCookie() function after it’s hidden the message box.

Next comes the setCookie() function. It takes three arguments: the name of the cookie, the value to be set, and how long the cookie should last before it expires (in days). We could have hard-coded some of this stuff to save time and space, but this way you can reuse this same function to set cookies all over your site – not just for this purpose.

Also, note that we’re using the toClose variable for our cookie name in setCookie()… which you might also remember is the ID of the message box itself. This is a useful trick, because this means you could theoretically have multiple message boxes with different IDs (all with the same .msgbox class) on your page, and you could open and close them separately, because each of their states would be set in a unique cookie.

Next comes the loadMsg() function. It takes one argument: msgClass. This variable represents the class you’ve set on all your message boxes. Our loadMsg() function cycles through all the <div> tags on your website and checks to see if they have the “msgClass” class set (whatever that happens to be… in my document, that was “msgbox”). If it finds such a div, it checks to see if it can find a cookie with a name that matches the ID set on that div – in our example it would be looking for “message-1.” If it doesn’t find a match (meaning the user hasn’t closed the box), then it sets that div to “display: block,” meaning it will show up normally. Otherwise, the message box stays hidden.

Now, all we need to do is ensure the loadMsg() function runs when the page first loads. To do that, I just modified my body tag like so:

<body onload="loadMsg('msgbox');">

The “onload” attribute fires when the page has finished loading, and it will call the loadMsg() function for us, displaying our message boxes as needed. And that’s all there is to it! You can see a functioning example here.

Now, I did want to mention a couple of things before you try this on your own:

  • I’ve built this example specifically to make it work with multiple message boxes. Otherwise, it would have been easier and faster to reference our message box by its ID in our loadMsg() function.
  • This obviously only works if your users have JavaScript and cookies enabled. If they have JavaScript turned off, they won’t see a message box. If they have cookies turned off, they won’t be able to get rid of your message box. And I don’t know of a good way around this usability problem. That’s just the way the cookie crumbles.
  • You could achieve this same functionality in about half the space using a JavaScript framework. I have nothing against frameworks generally, but I do have something against forcing your users to download 50KB+ of JavaScript if you’re only going to use 1KB (or less) of it. For some things, frameworks make sense. For others, it’s better to just write it by hand.

But enough from me… I want to hear what you have to say about this technique. Leave me a comment!