Snook’s Resizable Underlines
31st October 2005
After much head-scratching over the CSS Challenge, finally a combination of methods from Ian Lloyd and Simon Willison (plus the input of quite a few other luminaries) led Jonathan Snook to get closer than anyone else. It’s not quite perfect yet, but today readers, I give you Snook’s Resizable Underlines.

The Challenge
The aim is to apply underlines to paragraph text that stretch the whole width of the column (without using justified text), regardless of the lengths of the paragraph text itself. Whilst this can be achieved with background images, this will be useless when the user resizes the text, as the text will break out of the lines and look a right mess (see dark blue area of otherwise ace site The Big Noob and many other sites).
So, we almost have a solution. Here is a working example (try resizing text).
The JavaScript
The JS is unobtrusive, and if JS is disabled, you just get a standard, line-less paragraph. Here imaginary spans are being pulled under the lines of the paragraph to tell the browser where to draw the underlines. This was the only method that created the right number of spans - others created too few or too many.
window.onload = function()
{
var el = document.getElementById("a2");
var dup = el.cloneNode(true);
dup.id = “a1”;
el.parentNode.appendChild(dup);
}The CSS
Note that we justify text in the paragraph, although this will only apply to the underlines, as the imaginary spans will reset the text to align left over the justified underlines. Most of the remaining CSS is just for styling the underlines etc.
body {background-color:#FFF;}
p { width:300px; position:relative; text-align:justify; }
span#a1 { color:#FFF; border-bottom:1px solid black; }
span#a1 a { color:#FFF; }
span#a2 { position:absolute; left:0; top:0; text-align:left;}The XHTML
Simply add the unique span to the text inside the paragraph, and Bob should be your Uncle. Note that links work because the paragraph is the top “layer” over the imaginary spans.
<p><span id="a2">Paragraph waffle here.</span></p>
Caveats and Cautions
Says Jonathan Snook:
I duplicate the node and make the text the same colour as the background. So, if you have a patterned background then it wouldn’t really work. And IE isn’t redrawing the border on the last line.
He’s right. No browsers are re-drawing the last line - it only extends to the length of the words of that final line, just as a standard underline would. Also, if you resize text so big that there is only one word on the line, I find that the line will only extend the length of that word.
The major problem is re-using paragraphs, or positioning them anywhere but top left in the window. The method needs more flexibility to be honest. Otherwise, it rocks. Here’s the working example again.
Can anyone better the Snook method?
So, a couple of problems with line lengths on the last line, or lines with just one word. And it’s a bugger to apply the formatting to other paragraphs on the page. Anyone able to tweak those problems away? It could still be useful as it is, but as always there has to be a better way…
Simon Collison published this on 31/10/05, at 11:57 AM
Comments
Well, this is a no-brainer, but I’ve re-written the script to be less obtrusive and to work with multiple paragraphs.
31/10 at 15:14 from Blair
If you want the text to span the whole of the bottom line try this for size:
span#a2 { position:absolute; left:0; top:-1px; width:100%; text-align:left; border-bottom:1px solid orange; }
This suffers from a rounding error (I reckon) with those one word lines in FF but it’s fine in IE6… Not ideal but maybe someone can see a way round.
31/10 at 16:59 from Mike Stenhouse
Also, while I did span#a2 a { color:#FFF; }, it may be more appropriate to do span#a2 * { color:#FFF }. Because I’m duplicating the node, any fancy formatting on inner elements could get moved as well.
31/10 at 17:54 from Jonathan Snook
Its amazing what you can do today with just a bit of css, a slice of JS and a light spark of XHTML…
BUT
when I select the text, it looks like poo… and when I select the whole page (ctrl-a for PC, whatever for mac) and copy-paste, I get 2 identical paragraphs instead of one…
otherwise: nice!
02/11 at 16:16 from Henrik
You should probably loop through all the child nodes of the node you’re duplicating and change them to text nodes so that you don’t have random invisible hyperlinks and such.
In the example, if you move all the way to the end of the first underline, you can select the CSS Challenge link even though visually you don’t know you’re over the cloned version.
02/11 at 18:24 from Steven Ametjan
just add border-bottom attribute to the paragraph tag and that will complete the border on the last line
02/11 at 19:32 from jason
Stunningly bizarre selection behaviour on Firefox 1.5 RC1. Select text starting from the last line moving up (everything works fine); go past the top of the paragraph (suddenly things begin to go awry); while up there, head directly to the left corner and go back down the margin (whoa).
03/11 at 15:41 from Rahul
Better late than never…
Here are 3 variations on a simple CSS theme. Tested in IE6, Opera 8.5, FF 1.07, Mozilla 1.5.
The problem is that it is so simple that it is probably not what you want. But it might come in handy for some situations.
08/11 at 18:40 from Peter
Peter: I thought “Lines 1” from your list was absolutely perfect - it is on Safari and IE Mac. But then I tried it on IE 6 and the text sizes were really erratic when resizing smaller (going a size smaller resulted in really tiny text), plus some of the lines wouldn’t show, or I got extra lines below the text. Maybe just my machine…
Shame, as it was bloody perfect on the Macs. Thanks for sharing your methods.
I think somewhere in all of this is the perfect answer.
09/11 at 10:08 from Simon Collison
Yes, I noticed the problem with it going smaller on IE. There’s also a problem if you use links in the text. You can’t click them! I haven’t spent much time on it and will try starting with a smaller font size to start with so everything goes larger and can’t go smaller. There might be a way to make it work, but don’t think there will be a way to make the links work.
09/11 at 19:32 from Peter
Getting nearer! But how can anything be perfect with IE in the picture? I doubt whether I can improve on this.
Re links, you could have one link working by faking it and putting the link on the lines image.
10/11 at 15:08 from Peter
Did I stun everybody into silence with the simplicity of my method? I thought you’d all be discussing it and coming up with better solutions! Or perhaps you are all fed up with getting so many lines ;-)
Anyway, I have improved it and written an article and put examples on my website should anyone be interested.
Btw, does this make me a boffin :-)
Do I get a prize!!??:-)
14/11 at 00:24 from Peter
Peter: Go here.
14/11 at 09:38 from Simon Collison
Note that comments are disabled 30 days after articles are published, or sooner if spammers target a particular post. Sorry...
















