Runnin' the rails
“...if you're looking to separate content sections with a milky grey line, you're in luck!”

Handling the HR

The table below shows a cross-section of browsers and their madly creative interpretations of CSS applied to HRs.

As you can see, the encouraging news is, if you're looking to separate content sections with a milky grey line you're in luck! All browsers come to a relatively amicable agreement on what the default <hr / > should look like.

Unfortunately, after that, the discussion degenerates into a petty squabble with lots of snipey accusations and walkout threats. Nasty.


CSS Render
unstyled Default - unstyled
{color:red} color:red
{background:red} background:red
{background:red; color:red} background:red
{color:red; background:red; border-top:1px blue dashed} color:red; background:red; border-top:1px blue dashed;
{height:10px; color:red; background:red; border-top:5px blue dashed} background:red
{height:30px; border:0px none; border-top:5px blue dashed;background: #f3f3ff url(hr-3.gif) repeat-x center center;} background:#f3f3ff url(hr-3.gif) repeat-x center center; border:0px none;border-top:5px blue dashed;height:30px;

Safari, Opera, Mozilla and Firefox all actually support the 'background-image' property beautifully. Ultimately, this is of little use to us, since all versions of IE that render the background at all also surround it with a thin grey 'pseudo border'. No-one seems to have discovered a method of removing this border, rendering the HR's background entirely useless to us.


Fortifying the HR

It seems the best way of propping up our poor old HR is to wrap it in a DIV. This allows us to retain the HR's structural value to the document, while allowing us to control the look and feel via the DIV instead.

XHTML

<div class="line"><hr /></div>

CSS

div.line hr{ /* take out the troublemaking HR */
display:none;
}
div.line { /* DIV that wraps and replaces the HR */
background: transparent url(hr-3.gif) no-repeat center center;
height: 30px;
}


Although this does give us back control, we now have the issue of ensuring our HR is always wrapped. We can use a little JavaScript help to us here. Rather than wrapping every HR in the XHTML, we send the markup as a stock <hr />. This means in a worst case scenario it at least renders our default grey line.

Instead, our wrapping DIV is created and applied by the browser itself via a set of JavaScript instructions that we provide. This wrapping DIV only exists for the time that the page is onscreen and is, in essense, nothing more than a figment of your browser's runtime imagination. Simpler devices are oblivious to these instructions and stick with their familiar, old default HR.


JavaScript:

 function fancyRules() { 
if (!document.getElementsByTagName) return; var hr = document.getElementsByTagName("hr"); for (var i=0; i<hr.length; i++) { var newhr = hr[i]; var wrapdiv = document.createElement('div'); wrapdiv.className = 'line'; newhr.parentNode.replaceChild(wrapdiv, newhr); wrapdiv.appendChild(newhr); }
} window.onload = fancyRules;

The only other point to consider when using this method is the 'onload' event. Most sites of any size will most likely already have scripts set to run when the page loads. There can only be one onload event on each page, and competing scripts can sometimes squish each other.

Again, Simon provides a great solution in his 'addLoadEvent' function which is explained here, should you need it.

Good Luck.

Alex


Archives

Credits