CSS Challenge: Come on, boffins!

28th October 2005

Today a colleague set me a CSS challenge that I just can’t meet. I can sort of achieve the desired effect with appalling markup and combined paragraph and unordered list styles, but that’s awful. Maybe one of you boffins out there can make it work, or maybe it’s just plain impossible. Here’s the skinny…

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.

What we don’t want is this

Here is the easy way, but not what we want. Applying a bottom border to the paragraph would only give us one border underneath the paragraph, so inside the paragraph, a span is used to apply the bottom border to the text. That’s fairly easy, but the lines do not stretch to the full width of the column:

So that is no good. We need to make the lines stretch, and also have them resize with the text.

How it should work

OK, here is how I want it to look. See that the horizontal lines stretch the full width of the container, regardless of the text:

Why can’t we use background images?

Yes, it’d be easy to create a background image of horizontal lines and combine that with line-height in the paragraph to achieve the effect, but if you resize the text with the browser, the background image is not gonna resize with it. Check out the dark blue area on The Big Noob. A lovely site, and they’ve carefully combined the background image with the text. However, if you resize the browser, the text breaks out of the lines and it looks a bit wrong.

Can you help?

Make it happen first, and I’ll send you a little prize. Link to a working example on your server, with explanatory text if possible, or leave tips in the comments. Ensure the text resizes on all important browsers, and that the lines adjust accordingly. If you crack it, and your code is lean and valid, you’ll win something as yet undecided, and get bigged-up on these here pages. Alternatively, do you think it’s impossible?

I can’t keep banging my head against a brick wall here, so it’s TEAM time (Together Everybody Achieves More). Go web, go!

I believe it really is impossible; but then again, things that are impossible just take longer. The problem is that the only way to make each line box the same width in order to apply underlines or borders of the same length is to use ‘text-align: justify;’, but you’ve already decided against justified text.

There is also no supported method of spacing out the background image and it looks like the proposed ‘background-spacing’ property has been removed from the latest CSS3 backgrounds draft.

Here’s my effort. I use a span to get the width right across and a background image on the p to fill in the bottom line. It’s not perfect but I can’t see how this can be done with just the paragraph element.

Firefox works, IE mainly works but there’s a bit of the line missing on the top right. Opera needs a 1px bottom-padding on the p which needs to be applied using a hack or some other method. I’m still working on it.

I hope that there’s no tight deadlines on this. Whats more the prize on this is better be good Mr Colly, but if it’s something as great as a giant box of Mini Rolls I may reconsider and give it some time. The solution is going to have to involve some extreme geekery beyond my ‘thinking in pictures’ mindset.

I like Lachlans definition of impossible.

Another way of looking at this is ‘It’s Friday afternoon and I think I’ll have a cup of tea’.

Simon: “The way mine works is that the div full of spans that generates the lines is absolutely positioned inside the container div, and has overflow: hidden to make sure only exactly the right number of lines is visible. The container div stretches with the paragraph.”

Okay, now I’m just spamming these comments but here’s my entry. Downfall: 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.

Jonathan: Still love it, but noticed that if you go way high on text size, any lines with just one word have shortened underlines, and in all cases the last line is short no matter how many words there are on it.

Sorry about the bloody mess I’d made earlier, Colly. Thanks for putting it into an actual HTML file and posting it. Considering how much better Jon’s is, though, I’ll no bother trying to complete the JS for it…

Ah well, I know that there were neater versions offered, but I managed to get the multiple paragraph thing sorted, and as for the big fat white border, that was contained in the outer div to some extent. I’m bailing out now with this version which needs tidying on a whole heap of areas - I think Jonathan’s version wins out on simplicity alone!

Gotta say, though, this was an excellent head-scratcher of a challenge that forced me to try out some unobtrusive Dom stuff (which I really need to get some practice in!)

Here is my try - it doesnt work but there may be something I’m missing or I may just be missing a few brain cells.

My idea was to use a background image of an underline that is the same width of the paragraph and has some white space built into it. (above the underline)
Then in the paragraph’s background image have the underline repeat-x and position it using ems - 0 1.8em.
1.8 em being 180%, the same line height I made for my image.
The part I thought might work was, because ems are relative units, an image sized with ems sizes relatively with the font size adjustment.
So positioning the background image at 1.8ems should resize the image with text resize.

Give me a day or two, and time to iron out tiny issues with Snook’s example, and I’ll document the final winning technique, name it after him and the others whose code he added to, and try and add a few examples also.

Well Joram, the thing is that when you resize text, it wraps onto the the next line, but with <hr /> you can’t be sure where the line will wrap and the horizontal line will not re-flow with the text. Besides, the hr element is presentational - almost as bad as using reams of font tags - if you wanted to remove underlines later you’d have to remove many instances in that page (and any others that used it). CSS is the preferred option every time, but it will not achieve the exact effect Simon was after, hence the challenge.