Home / Style the HTML hr tag with CSS

Style the HTML hr tag with CSS

In the past I’ve fallen into the trap of creating a special class for rendering lines or separators in an HTML document and assigning the class to a div, ending up with something like <div class="line"></div> or something along those lines. Not only is this not semantic, it’s a whole bunch of extra unecessary HTML code which can be simplified by styling and using the often forgotten <hr> tag.

Default style for the hr tag

The default browser styling for the <hr> tag is this:


It’s usually something like a 1px high transparent part with a border around it making it appear somewhat 3-dimensional. And yes, it’s ugly.

Making hr look better with some CSS styling

To make a single pixel height line with none of the 3D looking effects simply set the height, remove the borders and assign a background-color. Because of a quirk in IE6 and IE7, the same color needs to be assigned to the color attribute otherwise it will use a default.

hr {
    border: none;
    background-color: #ccc;
    color: #ccc;
    height: 1px;
}

And here’s that hr rendered in the browser:


Using the borders and background color to make a gradient

Using the border-top and border-bottom along with a background color, it’s possible to create a three color gradient effect without using an image.

hr {
    border: none;
    /* top    */ border-top: 1px solid #ccc;
    /* middle */ background-color: #ddd; color: #ddd;
    /* bottom */ border-bottom: 1px solid #eee;
    height: 1px;
    *height: 3px; /* IE6+7 need the total height */
}

The *star hack makes the height setting 3px for just IE6 and IE7. It needs to be set to the total height of the hr for those two browsers, including the height you want in the middle and the height of the borders. Alternatively you can set it in a browser specific stylesheet.

Here it is rendered in the browser.


The three step gradient isn’t particularly wonderful looking and not much better than the default, but it gives you the idea that you can do quite a bit with the hr tag. Playing around with different color and shade combinations would probably make a better effect.

Having just a two step gradient instead probably looks better, as shown below:

hr {
    border: none;
    /* top    */ border-top: 1px solid #ccc;
    /* middle */ background-color: #ddd; color: #ddd;
    height: 1px;
    *height: 2px; /* IE6+7 need the total height */
}

And the rendered hr:


Using a background image

Instead of coloring the borders and background, assign a background image to the hr tag if you want complete control over how the line looks.

hr {
    background: url(/path/to/background.jpg);
    border: none;
    height: 5px;
}

There is also a quirk in IE6 and and IE7 which will render a border around the image no matter what; there appears to be no way of removing it or controlling the colors it uses. However, as these browsers are now finally almost disappeared completely it’s not worth worrying about.

Setting the width

Finally, to prevent the hr element from being 100% wide, it’s possible to set the width. It will always be center aligned but setting the margins to 0 will make it align to the left. Alternatively set the margins to some other value to set them in the desired position.

hr {
    margin: 0;
    width: 100px;
}

Once again, IE6 and IE7 are quirky and will align it to the center regardless of the margin setting. If the width is set to less than 100% and you actually care about these browsers, you’d need to set the deprecated align property of the hr element.

Conclusion

Why use a non-semantic div tag for rendering a line or separator in an HTML document when you can use the hr tag instead? That’s what it’s for and it’s really easy to style and make it look better than the default, barring a couple of IE6 and IE7 quirks.