How do I create tabbed navigation with CSS?

Navigation that appears as tabs across the top of the page is a popular navigation choice. Many sites create tabs using images. However, this can be less accessible and also problematic if your navigation is created using a Content Management System, with users of that system being able to add tabs or change the text in the tabs. However, it’s possible to create a tab effect by combining background images and text styled with CSS.SolutionThe tabbed navigation shown below can be created by styling a horizontal list.Building button-like navigation with CSSHere’s the HTML and CSS that creates this effect:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"""><html xmlns="" lang="en-US"><head><title>Lists as navigation</title><meta http-equiv="content-type"content="text/html; charset=utf-8" /><link rel="stylesheet" type="text/css" href="tabs.css" /></head><body id="recipes"><div id="header"><ul><li class="recipes"><a href="#">Recipes</a></li><li class="contact"><a href="#">Contact Us</a></li><li class="articles"><a href="#">Articles</a></li><li class="buy"><a href="#">Buy Online</a></li></ul></div><div id="content"><h1>Recipes</h1><p>Lorem ipsum dolor sit amet, ... </p></div></body></html>body {font: .8em/1.8em verdana, arial, sans-serif;background-color: #FFFFFF;color: #000000;margin: 0 10% 0 10%;}#header {float: left;width: 100%;border-bottom: 1px solid #8DA5FF;margin-bottom: 2em;}#header ul {margin: 0;padding: 2em 0 0 0;list-style: none;}#header li {float: left;background-image: url("images/tab_left.gif");background-repeat: no-repeat;margin: 0 1px 0 0;padding: 0 0 0 8px;}#header a {float: left;display: block;background-image: url("images/tab_right.gif");background-repeat: no-repeat;background-position: right top;padding: 0.2em 10px 0.2em 0;text-decoration: none;font-weight: bold;color: #333366;}#recipes #header,#contact #header,#articles #header li.articles,#buy #header {background-image: url("images/tab_active_left.gif");}#recipes #header a,#contact #header a,#articles #header li.articles a,#buy #header a {background-image: url("images/tab_active_right.gif");background-color: transparent;color:#FFFFFF;}


The tabbed navigation approach I’ve used here is a basic version of Douglas Bowman’s Sliding Doors of CSS method, which is a tried and tested technique for creating a tabbed interface. The structure that I’ve given to the navigation menu is the same kind of simple unordered list that we’ve worked with throughout this chapter, except that each list item is assigned a class attribute that describes the link it contains. We’ve also wrapped the entire list in a div with an id of header. The technique takes its name from the two images used to implement it – one overlaps the other, and the images slide apart as the text size increases.You’ll need four images to create this effect: two to create the regular tab color, and two to use when the tab is the currently selected (highlighted) tab. The images I’ve used in this example are shown below. As you can see, they’re far wider and taller than would generally be necessary for a tab – this provides plenty of space for the tab to grow if the user’s browser is configured to display text at a very large size.The image files used to create the tabsHere’s the basic list of navigation items:<div id="header"><ul><li class="recipes"><a href="#">Recipes</a></li><li class="contact"><a href="#">Contact Us</a></li><li class="articles"><a href="#">Articles</a></li><li class="buy"><a href="#">Buy Online</a></li></ul></div>The first step is to style the container that surrounds the navigation. We’re going to give our header a simple bottom border for the purposes of this exercise, but on a real, live web site this container may hold other elements in addition to our tabs (such as a logo or search field):#header {float: left;width: 100%;border-bottom: 1px solid #8DA5FF;margin-bottom: 2em;}As you’ll have noticed, we float the header to the left. We’ll also float the individual list items; floating the container that houses them ensures that they remain contained once they’re floated, and that the border will display below them.Next, we create a style rule for the ul element inside the header:#header ul {margin: 0;padding: 2em 0 0 0;list-style: none;}This rule removes the bullets and alters the margin and padding on our list – we’ve added two ems of padding to the top of the ul element. The figure below shows the results of our work so far.Displaying the navigation after styling the ul elementNow we need to style the list items:#header li {float: left;background-image: url("images/tab_left.gif");background-repeat: no-repeat;margin: 0 1px 0 0;padding: 0 0 0 8px;}This rule uses the float property to position the list items horizontally while maintaining the block-level status of each. We then add the first of our sliding door images – the thin left-hand side of the tab – as a background image. A single-pixel right margin on the list item creates a gap between one tab and the next. The figure below shows that the left-hand tab image now appears for each tab.The navigation tabs reflecting the new stylesNext, we style the links, completing the look of our tabs in their unselected state. The image that forms the right-hand side of the tab is applied to each link, completing the tab effect:#header a {float: left;display: block;background-image: url("images/tab_right.gif");background-repeat: no-repeat;background-position: right top;padding: 0.2em 10px 0.2em 0;text-decoration: none;font-weight: bold;color: #333366;}The results are shown in the figure below.Styling the navigation linksIf you increase the text size in the browser, you can see that the tabs neatly increase in size too. In fact, they do so without overlapping and without the text protruding out of the tab – this is because we have used images that allow plenty of room for growth.To complete the tab navigation, we need to highlight the tab that corresponds to the currently displayed page. You’ll recall that each list item has been assigned a unique class name. If we assign to the body element an ID that has a value equal to the value of each list item class, CSS can do the rest of the work:<body id="recipes">Although it looks like a lot of code, the CSS code that styles the tab matching the body ID is relatively straightforward. The images I’ve used are exact copies of the left and right images that we applied to the tabs, but they’re a different color, which produces the effect of one tab appearing to be highlighted.Here’s the CSS:#recipes #header,#contact #header,#articles #header li.articles,#buy #header {background-image: url("images/tab_active_left.gif");}#recipes #header a,#contact #header a,#articles #header li.articles a,#buy #header a {background-image: url("images/tab_active_right.gif");background-color: transparent;color: #FFFFFF;}With these rules in place, specifying an ID of recipes to our body will cause the Recipes tab to be highlighted, specifying contact will cause the Contact Us tab to be highlighted, and so on. The results of this work are shown in the figure below.Identifying a Useful TechniqueThe technique of adding an ID to the body element can be very useful. For example, you may have various color schemes for different sections of your site to help the user identify which section they’re using. You can simply add the section name to the body element and make use of it within the style sheet, as we did in this example.Highlighting the Contact Us tab by specifying contact as the ID of the body element

How can I visually indicate which links are external to my site?

When linking to other content it’s a nice touch to visually demonstrate to users when a link is to another site. We can do this using CSS without needing to add anything to our markup.


We can use a CSS3 selector that’s supported in many modern browsers to select the external links. The first link in the paragraph below is to a page on our own site, the second to an external web site (Google):<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"""><html xmlns="" lang="en-US"><head><title>Chapter 4 - Show external links</title><meta http-equiv="content-type" content="text/html;charset=utf-8" /><link rel="stylesheet" type="text/css"href="external_links.css" /></head><body><p>Lorem ipsum dolor sit amet, <a href="page2.html">consecteturadipiscing elit</a>. Aenean porta. Donec eget quam. Morbilibero.Curabitur ut justo vehicula elit feugiat lacinia. Morbiac quam. <a href="">Sed venenatis</a>,lectus quis porta viverra, lectus sapien tempus odio, acvolutpat mi dolor ac elit.</p></body></html>We can use a CSS3 selector to target the link that starts with http: and add an icon to it:a[href ^="http:"] {padding-left: 20px;background-image: url(link_icon_external.gif);background-repeat: no-repeat;}The external link displays with an iconAny links on our page that start with http: (which should be external as it is unnecessary to link to pages on our own site like that) will display with the world icon.


This CSS3 attribute selector is widely supported in modern browsers, although it will be ignored in Internet Explorer 6. In browsers that lack support for this selector the link will just display as normal; so, it’s a nice enhancement for browsers with support but leaves the experience unchanged for those with older browsers.Let’s take a closer look at that selector: a[href ^="http:"].The attribute that we’re selecting is the href attribute, and we want our selector to match when it finds the text http: at the beginning of the attribute value. The ^= operator means “begins with”. You could use a similar selector to match all email links, for example, a[href ^="mailto:"].Another useful attribute selector is to select on the file extension of a link. This means you can add a small icon to show that a document is a PDF or other document type, depending on the extension. The selector a[href $=".pdf"] will match any link that has a file extension of .pdf. The $= operator means “ends with”, so this selector will match when an href attribute value ends with .pdf. The example below shows all three types in action:<ul class="links"><li><a href="">Go somewhere else</a></li><li><a href="/files/example.pdf">Download a PDF</a></li><li><a href="">Email someone</a></li></ul>a[href ^="http:"] {padding-left: 20px;background-image: url(link_icon_external.gif);background-repeat: no-repeat;}a[href ^="mailto:"] {padding-left: 20px;background-image: url(link_icon_email.gif);background-repeat: no-repeat;}a[href $=".pdf"] {padding-left: 20px;background-image: url(link_icon_pdf.gif);background-repeat: no-repeat;}Links with icons for external and email links, and PDF files(The icons you can see above are from selectors are a very useful part of CSS and you can safely use them in this kind of situation where you’re just adding an enhancement to your design.

How do I change the cursor type?

It’s common for the cursor to change to a hand icon when the cursor’s moved over a link on any part of the page. Occasionally – perhaps to fit in with a particular interface – you might want to change the cursor to represent a different action.


We change the cursor using the CSS cursor property. For example, if we wanted to change the cursor on anchor elements that link to help documentation we can specify the style like {cursor: help;}The figure below identifies the properties that are available in CSS 2.1, and how they appear in Internet Explorer 8.The CSS 2.1 Standard Cursors in IE8


The cursor property can take a range of values. Changing the cursor display can be a useful way for web applications with friendly interfaces to provide valuable user feedback. For example, you might decide to use a question mark cursor for indicating help text.Changing the Cursor Can Cause Confusion!You should use this effect with care, and keep in mind that people are generally used to standard browser behavior. For instance, users are familiar with the cursor representing a pointing hand icon when hovered over a link.The figure above the various properties that are available in the CSS standard; these are supported by most modern browsers, including Internet Explorer 6 and above, Safari, Opera, Firefox, and Chrome. Browser support for the complete range of values varies so make sure to test.CSS3 increases the range of cursor values available, as shown below, but browser support for these values varies. They’re well supported by Safari, Firefox, and Chrome, and IE8 supports most of them; however, Opera, as of the time of writing, only supports CSS 2.1 cursor values.New CSS3 Cursors

Go to page: 1 | 2 | 3 | 4
Rachel is the Director of, a Web solutions company in the UK. She has worked on a number of books as a co-author, and is a member of the Web Standards Project, serving on the Dreamweaver Task force. Rachel is the author of SitePoint's The CSS Anthology and Build Your Own Standards Compliant Website Using Dreamweaver 8.

Free Guide:

How to Choose the Right Charting Library for Your Application

How do you make sure that the charting library you choose has everything you need? Sign up to receive this detailed guide from FusionCharts, which explores all the factors you need to consider before making the decision.

No Reader comments

Special Offer
Free course!

Git into it! Bonus course Introduction to Git is yours when you take up a free 14 day SitePoint Premium trial.