Building Accessible Static Navigation with CSS
Overview
When building a navigation menu for a web site, steps should be taken to ensure that it is accessible, and degrades gracefully in older browsers with lesser CSS support. In this article we will explore one such implementation. The navigation menu you see in this example is built with valid, semantic HTML and CSS - no JavaScript is involved, as I felt this was unnecessary. The static (non-expanding/collapsing) nature of the example suits a web site comprised of twenty or less target pages.
This article is divided into the following sections.
- Nav Container - The
nav
container (<div id="nav"></div>
) contains the following three areas of the navigation, and is placed in each web page of the document collection.- Skip to content styled button - This is placed directly at the top of the nav container, and is an accessibility feature for users with visual impairments.
- Area headings - This defines the structure and presentation of the area headings that separate each section of the navigation container.
- Link state symbols area - This is a legend consisting of symbols that define the state of a hyperlink as a user traverses the document collection. It is an accessibility feature for users that are visually impaired, color blind, or suffer from short term memory loss or dyslexia.
- Topics area - As it says, here is where all topic web pages are listed and hyperlinked for surfing through the document collection.
- Currently open page - Here I discuss another aspect of my navigation which you may find useful, namely the "Currently open page" feature.
Each topic will be explained, and accompanied by the markup and css used to create it. You can download the complete code example here.
Nav container
The nav div
container acts as a wrapper for and defines the overall position of the navigation areas. It is absolutely positioned at the top and left sides of the web page by a rule in the external style sheet.
Nav container markup
<div id="nav"> <h4 class="skip"> <a href="#a1">skip to content</a></h4> <hr /> <h4>link state symbols</h4> <ul class="linkstate"> <li><img alt="Ball symbol." class="state" src="images/hover.gif" width="16" height="16" /><span class="focus">Focus/Hover</span></li> <li class="unvisited"><img alt="Chain link symbol." class="state" src="images/link.gif" width="16" height="16" />Unvisited</li> <li class="visited"><img alt="Check mark symbol." class="state" src="images/visited.gif" width="16" height="16" />Visited</li> <li class="currently"><img alt="Star symbol." class="state" src="images/star.gif" width="16" height="16" />Currently Open</li> </ul> <hr /> <h4>topics</h4> <ul class="linkstate" <li><a href="home.htm">Home</a> <ul> <li><a href="Topic1.htm">Topic 1</a></li> <li class="topic2"><a href="Topic2.htm" title="This page is currently open.">Topic 2</a></span> <ul> <li><a href="Topic2a.htm">Topic 2a</a></li> <li><a href="Topic2b.htm">Topic 2b</a></li> <li><a href="Topic2c.htm">Topic 2c</a></li> <li><a href="Topic2d.htm">Topic 2d</a></li> <li><a href="Topic2e.htm">Topic 2e</a></li> <li><a href="Topic2f.htm">Topic 2f</a></li> </ul> </li> <li><a href="Topic3.htm">Topic 3</a></li> <li><a href="Topic4.htm">Topic 4</a></li> <li><a href="Topic5.htm">Topic 5</a></li> </ul> </li> </ul> </div>
Nav container CSS
Here we define the presentation code used to position and style the Navigation container div in the browser window:
#nav {
-
width: 23em;
- gives the navigationdiv
container a relative horizontal size -
position: absolute;
- removes the navigationdiv
container from the natural flow of the document. -
top: 1em;
- sets the distance from the top of the browser window -
left: 1em;
- sets the distance from the left side of the browser window -
margin: 0em;
- shorthand for themargin
property - removes all margins in the order of top, right, bottom and left -
padding: 0em 0.5em 1em 0.5em;
- shorthand for thepadding
property - sets the padding in the order of top, right, bottom and left: -
border: 1px solid #ffd505; }
- shorthand code for theborder
property - defines the width, type, and color of the border surrounding the nav container:
#nav ul {
-
margin: 0em;
- shorthand for themargin
property - removes all margins in the order of top, right, bottom and left -
padding: 0em;
- shorthand for thepadding
property - removes all padding in the order of top, right, bottom and left -
list-style-type: none;
- removes thelist-style
s: discs, squares, circles, etc. -
color: #fff;
- sets the color of white to the text characters -
background: inherit }
- sets the list to inherit the container background color
#nav ul li {
-
margin: 0em;
- shorthand for themargin
property - removes all margins in the order of top, right, bottom and left -
padding: 0.4em 0em 0em 0.5em;
- shorthand for thepadding
property - sets padding in the order of top, right, bottom, and left: -
list-style-type: none; }
- removes thelist-style
s: discs, squares, circles, etc.
#nav ul ul li {
-
padding: 0em;
- shorthand for thepadding
property - removes all padding in the order of top, right, bottom and left -
margin-left: 2em;
- sets the left margin padding to 2em -
list-style-type: none; }
- removes thelist-style
s: discs, squares, circles, etc.
#nav ul ul ul li {
-
padding: 0em;
- shorthand for thepadding
property - removes all padding in the order of top, right, bottom and left -
margin-left: 1.4em;
- sets the left margin padding to 1.4em -
list-style-type: none; }
- removes thelist-style
s: discs, squares, circles, etc.
Skip to Content area
Following accessibility guidelines, I have included a "skip to content" link (styled button) on each web page to allow users to bypass the navigation section and skip to the beginning of the page content. I have designed the button using CSS to be visible
to all users by default, making them aware that this accessibility tool is available. It is made fairly small, and in line with the design of the web page so as not to be too obtrusive to the page design. If a client specified it should not be visible,
it could be moved off the visible page using CSS absolute positioning (Important Note: visibility: hidden;
should not be used as this makes it invisible to assistive technologies.) This way, it wouldn't be seen at all by sighted users, and
users employing screenreaders (or other assistive technologies) could activate it through the keyboard. This eliminates the repetitive spatial navigation or tab key actions needed to manually bypass the navigation and arrive at the first section of content.
Skip to content area markup
As shown in the following code sample, the markup of the styled button (h4 class="skip"
) links the anchor element and its href attribute value (a href="#a1"
) with the id attribute value of the first content
heading (h2 id="a1"
). I do not employ any access keys/character keys to achieve this because the majority have already been pre-assigned by the operating system, the user agent/browser, and any assistive device which may be installed,
notwithstanding those few available which a user may have assigned themselves.
<h4 class="skip"> <a href="#a1">skip to content</a> </h4>
Skip to content area CSS
I have defined the following styles in an external style sheet to style and position the "Skip to Content" button hyperlink just how I want it:
#nav h4.skip {
-
font-size: 1.1em;
- sets thefont-size
to a relative size of 1.1em -
font-weight: bold;
- sets thefont-weight
tobold
-
font-variant: small-caps;
- sets thefont-variant
tosmall-caps
-
margin: 1.8em 0em 0em 0em;
- shorthand for themargin
property in the order of top, right, bottom and left -
padding: 0.5em;
- sets all padding (top, right, bottom, and left) to 0.5em -
color: #fff;
- sets the font color towhite
-
background: none;
- removes any background and image attached to the anchor hyperlink -
text-decoration: none; }
- removes the default underline from the anchor hyperlink
#nav h4.skip a:link, #nav h4.skip a:visited {
-
color: #000;
- sets the font color toblack
-
background: #ccc;
- sets the background color of the button -
padding: 0.2em 1em;
- shorthand code for padding in the order of top and bottom, then right and left -
border-top: 0.15em solid #fff;
- top border shorthand: sets the thickness, type and color for the unvisited and visited state of the top border of the button -
border-left: 0.15em solid #fff;
- left border shorthand: sets the thickness, type and color for the unvisited and visited state of the left border of the button -
border-bottom: 0.15em solid #aaa;
- bottom border shorthand: sets the thickness, type and color for the unvisited and visited state of the bottom border of the button -
border-right: 0.15em solid #aaa; }
- right border shorthand: sets the thickness, type and color for the unvisited and visited state of the right border of the button
#nav h4.skip a:hover, #nav h4.skip a:active, #nav h4.skip a:focus {
-
color: #fff;
- sets the font color towhite
-
background: #454545;
- sets the background color of the button -
padding: 0.2em 1em;
- shorthand code forpadding
in the order of top and bottom, then right and left -
border-top: 0.15em solid #fff;
- top border shorthand: sets the thickness, type and color for the hover, active and focus states of the top border of the button -
border-left: 0.15em solid #fff;
- left border shorthand: sets the thickness, type and color for the hover, active and focus states of the left border of the button -
border-bottom: 0.15em solid #aaa;
- bottom border shorthand: sets the thickness, type and color for the hover, active and focus states of the bottom border of the button -
border-right: 0.15em solid #aaa; }
- right border shorthand: sets the thickness, type and color for the hover, active and focus states of the right border of the button
Area headings
Each area of the navigation <div></div>
container begins with a heading using the <h4></h4>
element.
The Area Headings markup
<h4>Area Name</h4>
The Area headings CSS
#nav h4 { font-size: 1.5em; font-variant: small-caps; text-align: center; margin: 0em; padding-bottom: 0.3em; color: #fff; background: inherit; }
Link state symbols area
This legend defines the current state of all hyperlinks. In the Topics area of the navigation container, the current state of each link is represented by a different symbol positioned to the right of the hyperlink text - these are summarized in the table below. This is important to users that are color blind, visually impaired, or suffer from short term memory deficiency. It eliminates link state color, gives them the ability to identify if they have or have not visited a topic, and also allows them to identify a hyperlink by keyboard or mouse navigation.
State | Symbol | Description |
---|---|---|
Focus/Hover |
Ball - signifies the focus, hover and active pseudo-classes |
|
Unvisited |
Chain link - signifies an unvisited link, the link pseudo-class |
|
Visited |
Check mark - signifies a visited link, the visited pseudo-class |
|
Currently Open | Star - signifies a topic web page which is currently open and being viewed |
Link state symbols area markup
The legend is constructed using a simple unordered list, containing image elements with relative paths to the symbol graphics. alt
attributes give a short description of the symbols. Please note that this legend gives a static rendering
of the symbols - purely for identification purposes. The symbols will become dynamic through CSS image replacement in the Topics area hyperlinks, when the linkstate class
attribute is added to the opening tag of the root unordered list element.
<h4>link state symbols</h4> <ul class="linkstate"> <li class="focus"><img alt="Ball symbol." class="state" src="images/hover.gif" width="16" height="16" />Focus/Hover</li> <li class="unvisited"><img alt="Chain link symbol." class="state" src="images/link.gif" width="16" height="16" />Unvisited</li> <li class="visited"><img alt="Check mark symbol." class="state" src="images/visited.gif" width="16" height="16" />Visited</li> <li class="currently"><img alt="Star symbol." class="state" src="images/star.gif" width="16" height="16" />Currently Open</li> </ul>
Link state symbols area CSS
The Link State Symbols area presentation code is defined as follows:
#nav .linkstate {
-
font-weight: bold; }
- sets all characters tobold
#nav .state {
-
padding-right: 1em;
- sets the symbol image space to the right of the text -
vertical-align: top; }
- sets the symbol image to the top of the text baseline
#nav .focus {
-
color: #fff;
- sets the text color towhite
-
background: transparent;
- sets the background color totransparent
-
text-decoration: underline; }
- sets the underline beneath the hyperlink
#nav .link {
-
color: #a4d3ee;
- sets the text color to light blue -
background: transparent; }
- sets the background color totransparent
#nav .visited {
-
color: orange;
- sets the text color toorange
-
background: transparent; }
#nav .currently {
-
color: yellow;
- sets the text color toyellow
-
background: transparent; }
- sets the background color totransparent
Topics area
The Topics area contains the global navigation for the pages in the web site. Each topic is hyperlinked to its individual web page and is activated either by spatial keyboard navigation, tab key or mouse.
In this code I have dynamically employed the symbols I identified earlier in the Link state symbols area legend. Identification of the current state of any link in the Topics area is achieved by inserting a class
attribute with its value
of linkstate
in the root unordered list element opening tag (<ul class="linkstate">)
. The link state symbols, as previously defined in the legend, now become dynamic though image replacement using external CSS.
All hyperlinks in the Topics area now show their current link state via the symbol at the end of their link text. Links that are not in the hover
, active
or focus
state will show the unvisited chain link symbol,
the visited check mark symbol, or the star symbol which signifies that the page is currently open and being viewed.
In addition, as a user navigates through the Topics area hyperlink list via keyboard or mouse and gains focus on each link, the link will become underlined, and a ball symbol will replace either the chain link (unvisited) or check mark (visited) symbols.
This ball symbol represents the hover
, active
, and focus
pseudo-classes of the anchor link element. Please note that the star symbol which signifies a currently open page, will remain static and not change
(this is an optional feature which I'll describe later in the article).
Topics area markup
<h4>topics</h4> <ul class="linkstate"> <li><a href="home.htm">Home</a> <ul> <li><a href="topic1.htm">Topic 1</a></li> <li><a href="topic2.htm">Topic 2</a> <ul> <li><a href="subtopic2a.htm">Subtopic 2A</a></li> <li><a href="subtopic2b.htm">Subtopic 2B</a></li> <li><a href="subtopic2c.htm">Subtopic 2C</a></li> <li class="subtopic2d"><a href="subtopic2d.htm" title="This page is currently open.">Subtopic 2D</a></li> <li><a href="subtopic2e.htm">Subtopic 2E</a></li> <li><a href="subtopic2f.htm">Subtopic 2F</a></li> </ul> </li> <li><a href="topic3.htm">Topic 3</a></li> <li><a href="topic4.htm">Topic 4</a></li> <li><a href="topic5.htm">Topic 5</a></li> </ul> </li> </ul>
Topics area CSS
The presentation code for the Topics area is defined in the following manner:
#nav .linkstate {
-
font-weight: bold; }
- sets all link characters tobold
.
#nav .linkstate a:link {
-
text-decoration: none;
- removes underlining from hyperlinks -
color: #a4d3ee;
- sets the font color to a light blue -
padding-right: 1.7em;
- creates space on the right side of the Topic for the linkstate image - vertical-align: bottom; - positions the image at the bottom of the text line
-
background: #000 url(images/link.gif) no-repeat right; }
- shorthand for the background property, defined as follows:#000
- sets the background color to blackurl(images/link.gif)
- sets the relative path to the images folder containing the link icon imageno-repeat
- sets the image to a single and not a multiple renderingright;
- positions the image to the right of the hyperlink
#nav .linkstate a:visited {
-
text-decoration: none;
- removes underlining from hyperlinks -
color: orange;
- sets the font color toorange
-
padding-right: 1.7em;
- makes space on the right side of the Topic for the linkstate image -
vertical-align: bottom;
- positions the image at the bottom of the text line -
background: #000 url(images/visited.gif) no-repeat right; }
- shorthand for the background property, defined as follows:#000
- sets the background color to blackurl(images/visited.gif)
- sets the relative path to the images folder containing the link icon imageno-repeat
- sets the image to a single and not a multiple renderingright;
- positions the image to the right of the hyperlink
#nav .linkstate a:hover {
-
text-decoration: none;
- removes underlining from hyperlinks -
color: #fff;
- sets the font color to white -
padding-right: 1.7em;
- makes space on the right side of the Topic for the linkstate image -
vertical-align: bottom;
- positions the image at the bottom of the text line -
background: #000 url(images/hover.gif) no-repeat right; }
- shorthand for the background property, defined as follows:#000
- sets the background color to blackurl(images/hover.gif)
- sets the relative path to the images folder containing the link icon imageno-repeat
- sets the image to a single and not a multiple renderingright;
- positions the image to the right of the hyperlink
#nav .linkstate a:active {
-
text-decoration: none;
- removes underlining from hyperlinks -
color: #fff;
- sets the font color to white -
padding-right: 1.7em;
- makes space on the right side of the Topic for the linkstate image -
vertical-align: bottom;
- positions the image at the bottom of the text line -
background: #000 url(images/hover.gif) no-repeat right; }
- shorthand for the background property, defined as follows:#000
- sets the background color to blackurl(images/hover.gif)
- sets the relative path to the images folder containing the link icon imageno-repeat
- sets the image to a single and not a multiple renderingright;
- positions the image to the right of the hyperlink
#nav .linkstate a:focus {
-
text-decoration: none;
- removes underlining from hyperlinks -
color: #fff;
- sets the font color to white -
padding-right: 1.7em;
- makes space on the right side of the Topic for the linkstate image -
vertical-align: bottom;
- positions the image at the bottom of the text line -
background: #000 url(images/hover.gif) no-repeat right; }
- shorthand for the background property, defined as follows:#000
- sets the background color to blackurl(images/hover.gif)
- sets the relative path to the images folder containing the link icon imageno-repeat
- sets the image to a single and not a multiple renderingright;
- positions the image to the right of the hyperlink
Currently open page feature
This is an accessibility navigation feature I've found to be helpful to some users, and which I believe enhances their experience. Sometimes, a user may forget which page they have open and are viewing. Unwittingly, they may go to this specific page in the Topics area navigation and activate it, causing a page refresh. Some confusion may follow until they realize that this is the page they have open and are currently viewing.
To eliminate the possibility of this happening, you need to identify the hyperlink in the Topics area nav list of the page that is currently open. I do this by dynamically attaching a star symbol to the end of the link text and color the link text bold yellow, visually identifying this topic link as the page that is currently open. This feature can be employed in both static and dynamic navigation lists.
Currently open page feature markup
The first step is to open each page in a text editor and assign an id
to the <body>
element of each web page in the document collection (if one is not already present). For example:
- home.htm web page:
<body id="home">
- topic1.htm web page:
<body id="topic1">
- topic2.htm web page:
<body id="topic2">
- etc.
The second step is to find that same page listed in the Topics area unordered list (in that page), and add a class
attribute and value to the list item containing its hyperlink. The value of this class
attribute can be exactly
the same as the one used for the id
attribute in the opening <body>
element. For example:
- home.htm web page, Topics area unordered list:
<li class="home">
- topic1.htm web page, Topics area unordered list:
<li class="topic1">
- topic2.htm web page, Topics area unordered list:
<li class="topic2">
- etc.
The following markup sample of the site's home page illustrates both the <body>
element id
of "home", and the Topics area unordered list item class of "home" being added to the markup. This is one rare
occasion where I will add a title
attribute and value of "This page is currently open." to the anchor element.
<body id="home"> <div id="nav"> <ul class="linkstate"> <li class="home"> <a href="Home.htm" title="This page is currently open.">Home</a> </li> </ul> </div>
Currently open page feature CSS
Now that we have the markup of the home page adjusted to identify it as being currently open when a user is viewing it, the final step is to create the CSS to make this happen.
Each web page in the document collection will have its own group of four CSS type selectors in this specific order, in the external style sheet:
#home
:id
selector of the page<body>
element#nav
:id
selector of the Topics areanav div
element.home
:class
selector of the Topics area unordered list item elementa
: anchor element selector
An example of the collection of web pages and their selectors in the style sheet will look like the following:
#home #nav .home a,
#topic1 #nav .topic1 a,
#topic2 #nav .topic2 a,
#topic3 #nav .topic3 a,
- etc.
Remember to add a comma after each a
element type selector before starting the next group of selectors. The final group of selectors does not get a comma after the a
element type selector. Lastly, in the following CSS, we define
the appearance of the topic hyperlink when a topic web page is currently open.
#home #nav .home a, #topic1 #nav .topic1 a, #topic2 #nav .topic2 a, #topic3 #nav .topic3 a { color: yellow; background: transparent url(images/star.gif) no-repeat center right; cursor: default; padding-right: 1.7em; text-decoration: none; font-weight: bold; }
Summary
This article highlighted several techniques to add accessibility to a simple, static, navigation menu. It aims to enhance the user experience regardless of their (dis)ability through a Skip to Content facility, a Link State Symbol legend, and the dynamic employment of these link states through their associated symbols. Please feel free to add, change, and experiment with the code, according to your needs. Thanks for your time and attention!
This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.
Comments
The forum archive of this article is still available on My Opera.