Skip to content

Elisabeth Robson

Writing, programming, enjoying life

Eric and I recently completed the second edition of Head First HTML and CSS. Along with a slew of small changes to bring the book up to date with the latest standards, we also removed the chapter on XHTML and added a new chapter on HTML5. It’s still quite mind boggling to see how much the direction in web development changed from the first time we wrote the book to now! The web is much less about “documents” and much more about “web applications,” and this “application-in-the-browser” view of the web has enabled everything from online banking to Facebook and Twitter.

In any case, along with the transition from XHTML to HTML5 in our book, I am getting questions about transitioning to HTML5 from readers. This question is from Bernie, and he asks about the border attribute on the <img> element. The border attribute is a stylistic attribute that was actually phased out in HTML4.01 (along with other stylistic attributes and elements, like <font>). Many browsers still support the border attribute, but if you use it, your HTML will not validate! And it’s best practice to replace all stylistic HTML attributes and elements with CSS equivalents.

In this case, the CSS equivalent is the border property. You can set different aspects of a border using border-width, border-style, and border-color, or you can combine these three into one border property, like this:

border: width style color;

However, Bernie doesn’t just want to set the border of an image; he wants a linked image to have no border when the user’s mouse isn’t hovering over the image, and a border when the mouse is hovering over the image. Like this:

html5 logo

Fortunately, this is easy to do with CSS! First, you need the HTML for an image; I’ll use the HTML5 logo from the web site:

<a href="">
    <img src="" alt="html5 logo">

To style this image correctly, we need two rules: one to select the image when the mouse is not hovering over it, and one to select the image when the mouse is hovering over it. Fortunately, the :hover pseudo-class is supported on many elements, not just the <a> element, so this is easy to do.

a > img {
    border: 2px solid transparent;

a > img:hover {
    border: 2px solid black;

In the first rule, we’re selecting an image, with no hover state, that’s nested in an <a> element. We need to go ahead and set a transparent border on the image when it’s not in the hover state, so we set the border to a 2px, solid, transparent border. Why do we need to do this? Because when you add a border to an image, it changes the width (and height) of the element. Remember, the CSS box model determines the width of an element to include the margin, border, and padding along with the width of the content. So if you add a border only when you’re in the hover state, the image will appear to shift over by the width of the border, producing a jarring visual effect.

So with an invisible border in place for the non-hover state of the image, we can now add the hover state selector to add the border when the user mouses over the image. We add the same width and style border as before (so the total width of the element remains the same), but now we change the color to black so the border is visible. When the user mouses over the image, the border changes to black and becomes visible.

There are many different ways you could do this, but this is simple, works well in all modern browsers, and validates as HTML5.