Home > CSS Blog > Advanced jQuery Tabbed Box Techniques

Advanced jQuery Tabbed Box Techniques

March 21st, 2009

Advanced jQuery Tabbed Box Techniques



animated tabbed box interface

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:

  • Make your tabs all the same height
  • Automatically rotate through your tabbed content
  • Stop the rotation when the user is interacting with the content

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:

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

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.

Read More


Similar Posts

    Build a Tabbed Box with CSS and jQuery

    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.

    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:

    drawing of a tabbed box

    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:

    tabbed box in photoshop

    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.

    tabbed box's outline of parts

    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.

    Read More

    Advanced jQuery Tabbed Box Techniques

    Take your XHTML + CSS tabbed box to the next level with these jQuery techniques. This tutorial explains how to add equal heights and auto-rotation to the mix.

    Source

    Build a Tabbed Box with CSS and jQuery

    This tutorial will walk you through building a tabbed box, perfect for sidebars and sites with too much clutter, using CSS and jQuery.

    Source

    A Simple jQuery Stylesheet Switcher

    jQuery stylesheeet switcher

    There are lots of reasons you might want to offer your users more than one CSS file for your website:

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

    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.

    Read More

    A List Apart: Articles: Sliding Doors of CSS

    … CSS layouts be flat and boxy? Nope! Bowman shows how to create slick tabbed navigation using CSS and … First we’ll set the existing rule to float the anchor. …

    Source

    CSS and Round Corners: Build Accessible Menu Tabs [CSS Tutorials]

    … to building an accessible tabbed navigation system with rounded corners in CSS. … text-decoration: none … text with the addition of padding to our CSS …

    Source

    A List Apart: Articles: Sliding Doors of CSS, Part II

    … the hit points of your Sliding Doors CSS-built tabbed interface elements. … an anchor element is changed to a block-level element (via CSS) and additional …

    Source

    DotNetNuke Marketplace – Mandeeps.com

    CSS Tabs w/AJAX + Content Rotator 2.0 – Standard Edition … CSS Content Rotator allows you to rotate Virtually Any Content within same space; …

    Source

    Running jQuery with Other Frameworks Via noConflict

    Photo "Chess" by Romainguy. Used under a Creative Commons license.

    While jQuery is certainly a popular JavaScript framework, it’s by no means the only game in town. Other frameworks such as Prototype, MooTools, Dojo and many others all have their own strengths, weaknesses, and devoted groupies.

    Generally speaking, these frameworks all play well together — you can mix and match framework functionality to your heart’s content, as long as you don’t mind the additional overhead of loading several libraries simultaneously. So you have a calendar widget in jQuery that you love, but you’re already using Prototype to animate your navigation bar? Don’t be shy… use both!

    Of course, every once in a while you can run in to problems when combining JS frameworks — particularly (in my experience) when combining jQuery and Prototype. Luckily, jQuery was kind enough to provide us with a workaround.

    The Problem: Sharing Syntax

    The most common compatibility problem stems from both jQuery and Prototype using the same shortcut syntax: namely, the $().doSomething syntax. Here’s a sample line of code in jQuery:

    $('#myelement').addClass('active');

    And the same functionality in Prototype:

    $('myelement').addClassName('active');

    Note the basic similarity? Both frameworks claim the dollar sign notation for themselves, which can wreak havoc on snippets of code dropped willy-nilly into a website. If your jQuery code is grabbed up by Prototype, things will stop working fast. And similarly, if your Prototype code is snagged by jQuery, not even the awesome power of jQuery will be enough to overcome the code confusion.

    The Solution: noConflict Mode

    But not to worry! jQuery has provided us with a workaround called “noConflict mode.”

    By default, there are two equally correct ways to call a jQuery function — the dollar sign notation, and “jQuery” notation:

    $('#myelement').show();
    jQuery('#myelement').show();

    Both of the lines above do exactly the same thing. However, most people use and prefer the dollar sign notation. Why? Probably because it’s shorter, and if web developers didn’t care about brevity in their code, they probably wouldn’t have used a framework in the first place.

    Of course, just using the longer jQuery notation isn’t enough. If jQuery has already claimed the dollar sign for itself, any Prototype functionality relying on that notation will still be grabbed by jQuery.

    This is where the noConflict function comes in handy. Simply run the following line after both Prototype and jQuery have been loaded:

    jQuery.noConflict();

    This will cause jQuery to give up the dollar-sign notation, allowing the other library to take it over. And you can still use your jQuery snippet, provided you change all instances of $() to jQuery().

    Keeping it Short

    The noConflict mode does have one other bit of functionality that I’ve found useful in some of my projects: you can select a different variable to use instead of the standard “jQuery”. The usage looks like this:

    var $j = jQuery.noConflict();

    Now in addition to using the default jQuery() notation, I can also use the shorter $j() notation. This allows me to avoid running into problems with other frameworks, while still enjoying almost the same conciseness in my code.

    Read More

    IE 7 Beta 3 available

    Internet Explorer 7 Beta 3 has been announced and is now available for download. Features include tabbed browsing, RSS integration, multiple search engines via the built-in search box, and more. Sure, these are all features that Firefox, Safari, etc. have had for a quite some time, but as the old saying goes, better late than pregnant. There are no new CSS features, however; Microsoft has stayed true to their promise that, for better or for worse, as of this March IE 7 was “layout complete.”
    Read | Permalink | Email this | Linking Blogs | Comments

    Read More