Fun with links
27th May 2003
Yesterday we talked about the box model. Today we’re going to put a small part of it to work, by investigating ways of styling links. Before getting stuck in, we need to talk a bit about pseudo-selectors (also known as pseudo classes). The CSS specification defines pseudo classes as “characteristics that cannot be deduced from the document tree”, but in practise the only widely implemented psuedo selectors are those that apply to links. The key psuedo selectors for links are:
a:link
applies to normal links (but not to<a name="">
elements)a:visited
applies to visited linksa:active
applies to active links (links that are currently being clicked on)a:hover
applies to links that the mouse is currently positioned over
It is the last of these that we shall be focusing on. One of the first and most popular effects that emerged when Javascript became popular was the image rollover, where an image (generally used as part of a site’s navigation) would change when the mouse was positioned over it. a:hover
allows us to achieve a similar effect using just CSS. The most striking change is to alter the background colour, as shown in this example.
After yesterday’s discussion of the box model, it seems we would be able to achieve a lot more with this effect if links were block level elements. We can use the display: block;
property to “promote” a link to block level status, which allows us to achieve all kinds of groovy effects. Consider the following HTML:
<div id="menu">
<a href="/">Link 1</a>
<a href="/">Link 2</a>
<a href="/">Link 3</a>
<a href="/">Link 4</a>
</div>
Left to its own devices, this would display as a rather uninteresting line of links. Add some CSS and we can make it look much more interesting:
div#menu {
width: 5em;
border: 1px solid red;
border-bottom: none;
}
div#menu a {
display: block;
text-decoration: none;
border-bottom: 1px solid red;
background-color: white;
color: red;
padding: 0 0.2em;
}
div#menu a:hover {
background-color: red;
color: white;
}
A few things to note. Most importantly, the links inside the div are set to display: block
. This causes them to “stack up” on top of each other, and also causes them to expand to be as wide as their containing box (which is why we have restricted its width to 5 ems). The menu border is set to 1px all the way round, but then the bottom border is turned off. This means that when we set a bottom border on the links themselves the very bottom link does not end up with a double border. The result of the above can be seen here.
How about horizontal navigation? That can be achieved in a similar fashion, using the float property to position the links next to each other:
div#menu a {
display: block;
float: left;
width: 5em;
padding: 0 0.2em;
margin-right: 1em;
text-decoration: none;
border: 1px solid red;
background-color: white;
color: red;
}
div#menu a:hover {
background-color: red;
color: white;
}
Check out the result here. Now that the links are floated it is important they have an explicit width assigned to them. A margin-right is used to place a gap between the links. There is one caveat to this method: It is important that any following element (preferably one that spans the whole page) as clear: both;
applied to it, or any text in that element will flow around the menu rather than appearing below it. This is one of the most common upsets caused by using floats, and exactly the thing the clear property is designed to solve.
There is one problem with the technique described so far: accessibility. If you run the above examples through any accessibility checker they will flag up a warning that the links in the examples are seperated only by whitespace. Try disabling CSS or viewing the examples in a non-CSS browser and you’ll see that this could definitely cause confusion—the links are displayed on a single line with only a single space between each one. A solution is at hand in the form of the humble <span> element accompanied by the display: none
property:
div#menu span {
display: none;
}
<div id="menu">
<a href="/">Link 1</a><span> | </span>
<a href="/">Link 2</a><span> | </span>
<a href="/">Link 3</a><span> | </span>
<a href="/">Link 4</a>
</div>
Here’s a demonstration of the above. Note that it’s identical to the previous example in CSS browsers; the separating pipes only show up when the CSS is not applied.
More recent articles
- Notes from Bing Chat—Our First Encounter With Manipulative AI - 19th November 2024
- Project: Civic Band - scraping and searching PDF meeting minutes from hundreds of municipalities - 16th November 2024
- Qwen2.5-Coder-32B is an LLM that can code well that runs on my Mac - 12th November 2024