CSS/(X)HTML Tutorial: Hovering Accessibility Jump Menu

[ ~{*}~ ] Recently, a reader named Don asked about this theme’s accessibility (accesskey) jump menu located at the top of each page. Several people have commented that they like the way the jump menu “lights up” upon gaining focus. Whenever a user hovers their cursor over the region at the top of the page, all links in the jump menu change to a more visible color. Then, as the cursor moves over the various menu items, each jump link is further highlighted with an even brighter color and an underline. This progressive focusing is best seen in browsers that support the CSS :hover pseudo-class (e.g., Firefox, Opera, etc.), however the menu remains useful even in CSS-challenged browsers (e.g., Internet Explorer). In this article, I explain how the Perishable Press jump menu is built using Web standards via CSS and (X)HTML, and then provide the specific code required to emulate the jump menu as it appears here at Perishable Press.

Step 1: The Markup

For the markup, we want to adhere to the principles of standards-based Web-design and maintain a strict separation of structure ((X)HTML) and presentation (CSS). Structurally, the jump menu is comprised of a list of links, so let’s begin with something like this:

<ul>
	<li><a href="" title=""></a></li>
	<li><a href="" title=""></a></li>
	<li><a href="" title=""></a></li>
	<li><a href="" title=""></a></li>
	<li><a href="" title=""></a></li>
</ul>

For the first part of this tutorial, we will assume that all jump links target elements on the current page. For example, we want to target the content, comments, sidebar, footer, search, etc., which are all assumed to be present on the same page as the menu itself. Of course, it is trivial to add links to other pages (e.g., the home page, login page, etc.) as well, as we will see later in the article. For now, we need to “flesh out” our list with a few important details:

<ul id="jump">
	<li><a href="#content" title="Jump to main content">Content</a></li>
	<li><a href="#sidebar" title="Jump to sidebar menu">Sidebar</a></li>
	<li><a href="#explore" title="Jump to footer items">Footer</a></li>
	<li><a href="#discuss" title="Jump to comments">Comments</a></li>
	<li><a href="#search"  title="Jump to search">Search</a></li>
</ul>

Here, we have given our list an id="jump", which will serve as a hook for various CSS styles. We have also completed our links with the desired targets, titles, and link text. At this point, we have everything we need to begin styling with CSS, however, we also want to implement complete “AccessKey” functionality. AccessKeys enable users to quickly navigate your site using keyboard shortcuts. These predefined shortcut links are especially helpful for users of text-only browsers such as Lynx. Thus, to equip our menu with some AccessKey excellence, we modify our list as follows:

<ul id="jump" role="heading">
	<li><a href="#content" accesskey="1" title="AccessKey[1]: Jump to main content">Content</a></li>
	<li><a href="#sidebar" accesskey="2" title="AccessKey[2]: Jump to sidebar menu">Sidebar</a></li>
	<li><a href="#explore" accesskey="3" title="AccessKey[3]: Jump to footer items">Footer</a></li>
	<li><a href="#discuss" accesskey="4" title="AccessKey[4]: Jump to comments">Comments</a></li>
	<li><a href="#search"  accesskey="5" title="AccessKey[5]: Jump to search">Search</a></li>
</ul>

Okay, looking good. Notice the addition of the accesskey="#" attribute. This associates the specified shortcut key with the corresponding link target. Here we are using numbers for our accesskey values, however, other characters will also work 1. We have also indicated related AccessKey information in the title attribute of each link. This helps to inform users of associated AccessKey functionality. Update: to adhere to Accessibility guidelines, we have added the requisite role="heading" attribute (hat tip: H5N1). At this point, we are finished with the (X)HTML portion of the tutorial. Let’s have a look at how the list markup appears without any applied CSS:

[ Screenshot: Unstyled Jump Menu ]

Very nice. Now, before moving on to the CSS styling, keep in mind that the jump menu that we are building is intended to be placed at the top of your pages, before any other content. The whole point of an access menu is that it enables users to bypass unnecessary information and “jump” directly to the target location. Also, the links in our jump menu point to the following array of anchor elements [ Note: replace the name attributes with ids if you are using XHTML for markup (hat tip: Louis) ]:

<div><a name="content"></a></div>
<div><a name="sidebar"></a></div>
<div><a name="explore"></a></div>
<div><a name="discuss"></a></div>
<div><a name="search"></a></div>

Each of these anchor elements should be present at their associated target locations. For example, the <div><a name="content"></a></div> element should be placed directly before the main content of the page. Without the proper target elements in place, the menu links will point to nowhere!

Step 2: The Presentation

With our solid, standards-compliant list-markup in place, we are ready to begin styling with CSS. The first thing we want to do is format the list for horizontal presentation:

ul#jump {
	font-family: Verdana, sans-serif;
	text-align: center;
	font-size: 12px;
	padding: 7px 0;
	color: #999;
	margin: 0;
	}
ul#jump li {
	list-style: none;
	display: inline;
	padding: 0 3px;
	margin: 0;
	}

Hopefully, this CSS code is self-explanatory. Basically, we are styling the text, centering the menu, specifying spacing, removing list bullets, and displaying the list horizontally. After applying these rules, we get something similar to this (depending on browser, settings, etc.):

[ Screenshot: Jump Menu List Styles ]

Next, we want to style the menu links to replace the default browser styles with something a little less ugly. So, we add the following CSS to our previous code:

ul#jump a:link, ul#jump a:visited {
	text-decoration: none;
	color: #777;
	}
ul#jump a:hover, ul#jump a:active {
	text-decoration: underline;
	color: #333;
	}

Here is what our list looks like after adding these basic link styles:

[ Screenshot: Jump Menu List and Link Styles ]

Although our jump menu is looking great so far, unfortunately, that’s as far as we can go with our old friend, Internet Explorer. However, for browsers that understand the CSS :hover pseudo-class (e.g., Firefox, Opera, etc.), we can do much better. First, let’s add that spiffy “hovering” action to the menu bar:

ul#jump:hover, ul#jump:focus {
	background: #ffff33;
	cursor: pointer;
	color: #777;
	}

Adding that to our previous CSS, the jump menu will change color upon either hover or focus (depending on browser). The menu background will brighten to a light yellow, and any non-link text will appear darker and easier to read. Here is a screenshot:

[ Screenshot: Jump Menu when Hovered ]

Now let’s add similar hover styles for the menu links themselves:

ul#jump:hover a:link, ul#jump:focus a:link, 
ul#jump:hover a:visited, ul#jump:focus a:visited {
	text-decoration: none;
	color: #333;
	}
ul#jump:hover a:hover, ul#jump:focus a:hover, 
ul#jump:hover a:active, ul#jump:focus a:active {
	text-decoration: underline;
	background: #ffcc66;
	color: #990000;
	}

Now, whenever the menu is hovered or receives focus, links and visited links will appear darker and easier to read. Likewise, upon menu focus, hovered links and active links will change to a maroon color with an orange background. Of course, the colors and other aesthetic styles used in this tutorial were chosen for clarity, and should be customized as needed. Once in place, this code completes the progressive focusing of menu links. Here is a screenshot of the menu when a particular link is hovered:

[ Screenshot: Jump Menu with Hovered Link ]

Although we could call it done at this point, the magical functionality provided by CSS 2.1 and CSS 3.0 enables us to add visual spacing elements between each of the menu list items. We add this to our code to further style modern browsers:

ul#jump li:before {
	content: " | ";
	}
ul#jump li:first-child:before {
	content: " ";
	}

Here, we are using the :before pseudo-element (from CSS 2.1) to add a vertical bar ( | ) before each menu item. Then, to remove an unwanted vertical bar from appearing before the first menu item, we are using the pseudo-selector :first-child (from CSS 3.0) to replace the bar with an empty space. [ Note: IE 6 does not understand the :first-child pseudo-selector. ] Here is a screenshot showing the addition of the vertical bars:

[ Screenshot: Jump Menu with Vertical Bars ]

This step demonstrates perfectly why CSS is critical to designing with Web Standards in mind: it enables the strict separation of structure from presentation. To understand this, consider the first screenshot above showing the unstyled menu list. Without CSS, our menu presents as a well-structured list, appearing squeaky clean in any compatible browsing device. Users (and machines) without the pleasure of CSS support will be able to understand and use the menu as intended. The list itself includes no extraneous elements, inline styles, non-semantic markup, unnecessary text, or any of that. It’s just a list, plain and simple. Then, by applying our carefully designed CSS, we instantly and unobtrusively transform the presentation of the list markup to suit our needs. Thus, supportive browsers see the well-styled, aesthetic bliss provided by the CSS, which, when unavailable, degrades gracefully, leaving the pure, unadulterated (X)HTML markup. This is why I love designing with Web Standards! :)

The Finished Product

Now that we have completed both (X)HTML markup and CSS presentation, it’s time to put it all together and present the finished product. First, place the the markup at the top of the <body> element of your web page:

<ul id="jump" role="heading">
	<li><a href="#content" accesskey="1" title="AccessKey[1]: Jump to main content">Content</a></li>
	<li><a href="#sidebar" accesskey="2" title="AccessKey[2]: Jump to sidebar menu">Sidebar</a></li>
	<li><a href="#explore" accesskey="3" title="AccessKey[3]: Jump to footer items">Footer</a></li>
	<li><a href="#discuss" accesskey="4" title="AccessKey[4]: Jump to comments">Comments</a></li>
	<li><a href="#search"  accesskey="5" title="AccessKey[5]: Jump to search">Search</a></li>
</ul>

Then, make sure that you have the associated target anchor elements in place throughout the document [ Note: replace the name attributes with ids if you are using XHTML for markup (hat tip: Louis) ]:

<div><a name="content"></a></div>
<div><a name="sidebar"></a></div>
<div><a name="explore"></a></div>
<div><a name="discuss"></a></div>
<div><a name="search"></a></div>

And finally, place this code into your CSS file:

ul#jump {
	font-family: Verdana, sans-serif;
	text-align: center;
	font-size: 12px;
	padding: 7px 0;
	color: #999;
	margin: 0;
	}
ul#jump li {
	list-style: none;
	display: inline;
	padding: 0 3px;
	margin: 0;
	}
ul#jump a:link, ul#jump a:visited {
	text-decoration: none;
	color: #777;
	}
ul#jump a:hover, ul#jump a:active {
	text-decoration: underline;
	color: #333;
	}
ul#jump:hover, ul#jump:focus {
	background: #ffff33;
	cursor: pointer;
	color: #777;
	}
ul#jump:hover a:link, ul#jump:focus a:link, 
ul#jump:hover a:visited, ul#jump:focus a:visited {
	text-decoration: none;
	color: #333;
	}
ul#jump:hover a:hover, ul#jump:focus a:hover, 
ul#jump:hover a:active, ul#jump:focus a:active {
	text-decoration: underline;
	background: #ffcc66;
	color: #990000;
	}
ul#jump li:before {
	content: " | ";
	}
ul#jump li:first-child:before {
	content: " ";
	}

And that’s it! I highly encourage you to experiment with this code, play with different CSS styles, and even customize the (X)HTML markup as needed. For those of you looking for a “live” example of the jump menu, you may either look at the top menu of any page in the current theme, or else download an example page using the exact code used in this tutorial.

Download

Download the demo! Contains all the codez in zipped HTML file.

Demo - Access/Jump Menu – Version 1.0 (1,019 B zip)

Specific Example: Perishable Press Jump Menu

Having explained the process involved with designing this type of “hovering” jump menu, I feel comfortable sharing the code required to emulate the accessibility/jump menu used here at Perishable Press. As always, first the markup:

<div id="jump">
	<a href="http://perishablepress.com/cssxhtml-tutorial-hovering-accessibility-jump-menu/#top" accesskey="" rel="nofollow" title="Jump Menu [0]" id="top">Jump Menu</a> : 
	<a href="#content"                                   accesskey="1" rel="nofollow" title="Jump to Main Content [1]">Content</a> | 
	<a href="#explore"                                   accesskey="2" rel="nofollow" title="Jump to Explore Menu [2]">Explore</a> | 
	<a href="#search"                                    accesskey="4" rel="nofollow" title="Jump to Site Search [4]">Search</a> | 
	<a href="http://perishablepress.com/"                accesskey="5" rel="nofollow" title="Perishable Press Home [5]">Home</a> | 
	<a href="http://perishablepress.com/press/sitemap/"  accesskey="6" rel="nofollow" title="Perishable Sitemap [6]">Sitemap</a> | 
	<a href="http://perishablepress.com/press/contact/"  accesskey="7" rel="nofollow" title="Contact Perishable [7]">Contact</a> | 
	<a href="http://perishablepress.com/press/wp-admin/" accesskey="8" rel="nofollow" title="Login / Register Page [8]">Login</a> | 
	<a href="http://perishablepress.com/access/" accesskey="9" rel="nofollow" title="Accessibility Info [9]">Access.</a>
</div>

As you can see, there are several differences between my current implementation of the Jump/Access menu and the one created in the tutorial. These improvements were made while writing this article. The improvements are significant, and I will be using the tutorial version in my next redesign. A significant difference between the tutorial version and my implementation is the addition of a link to the Jump Menu itself. Labeled with an id="top", the Jump Menu anchor serves as a description of the menu links, while also serving as the target for all “top” links (e.g., “Return to Top”) throughout the remainder of the page. Also, I have given accesskey attribute a value of zero to further distinguish and establish it as a key link. Further, the vertical dividing bars are explicitly defined within the markup, rather than implicitly added via CSS. There are many arguments either for or against such handling, but I will defer them for a future post. And finally, the vertical bar otherwise appearing after this first link is replaced by a colon ( : ) to further emphasize its semantic purpose. Here is the associated CSS for this markup:

div#jump {
	text-align: center;
	overflow: hidden;
	font-size: 1.0em;
	color: #555;
}
div#jump:hover, div#jump:focus {
	cursor: pointer;
	color: #777;
}
div#jump a:link, div#jump a:visited {
	text-decoration: none;
	color: #555;
}
div#jump a:hover, div#jump a:active {
	text-decoration: underline;
	color: #eee;
}
div#jump:hover a:link, div#jump:focus a:link, 
div#jump:hover a:visited, div#jump:focus a:visited {
	text-decoration: none;
	color: #aaa;
}
div#jump:hover a:hover, div#jump:focus a:hover, 
div#jump:hover a:active, div#jump:focus a:active {
	text-decoration: underline;
	color: #eee;
}

Aside from expected differences in the design-specific aesthetic properties of the jump menu, the CSS used for the Perishable Press Jump Menu is essentially the same. The only major difference is the lack of the pseudo-element :before and the pseudo-selector :first-child, which are used in the tutorial version to unobtrusively add the vertical bar dividers. And of course, to see this CSS and (X)HTML code in action, refer to the source code of any page presented via the current theme.

As always, feel free to share your CSS and/or (X)HTML expertise with our growing community. I also welcome criticism, complaints, questions, and just about everything else that is useful and isn’t spam. Cheers!

Footnotes

  • 1 Valid AccessKey values include any alphanumeric character, plus perhaps a few others, but I honestly don’t know for sure. To be safe, stick with letters and numbers. Note: If you happen to have a good resource providing this information, I would be very grateful. Thanks!