Post #306

Flexible floats

26th March 2004, mid-afternoon | Comments (36)

Code information
Code usage No longer in use on this blog
Updates Available
Demo Available
Downloads Available

In my newly styled reading section I’m using das wundervoll float model to maximise the use of space on the page. I’m quite pleased with the result, so I thought I’d share how I’ve done it.

(It's worth pointing out here that I no longer use this code on the reading page, but you can see it in action on a demo page. It's worth taking a look there if you get confused.)

The basic layout

Each book/author and its accompanying information is laid out using a definition list. These <dl>s are each given a fixed width (in pixels) and floated left, so they wrap around to form rows and columns.

1.0 The reading page

When the window is wide

When the browser window is nice and wide, the width of the main content div, div#left (shown below with a red border), is sufficient to let these floated <dl>s (shown below with black borders) wrap two or more to a line.

1.1 With a wide window the <dl>s wrap around, two to a line

When the window is narrow

But when the browser window narrows, (and div#left with it), these floated <dl>s ‘unwrap’ and sit one to a line.

1.2 Narrow windows force the <dl>s onto separate lines

Wasted space

The only problem is that when the floated <dl>s unwrap, there’s an awful lot of wasted space on the right hand side of div#left.

1.3 Narrow windows leave a lot of wasted, white space

There’s plenty of content to fill that white space (look at the amount of text in the Phillip Pullman entry), but it’s unable to spread out. Why? Because it’s contained within the fixed-width <dl>s.

Wouldn’t it be nice if there was a way of saying to the page, Excuse me, have you seen all that white space over there? It’s just that if you <dl>s would stop being fixed width for a bit, relax, and spread out across the page, things would look a lot nicer.

Now, how would you do that?…

From fixed to liquid

Enter Stuart Langridge, and his Big Book Of Doing Things In Javascript:

1.4 As if by magic, the floated <dl>s resize to take advantage of the white space

Javascript, oh lovely Javascript, you are the solution to all my problems, come here and let me hug you…

How the Javascript actually works

Put simply, the script checks the width of div#left and asks itself: “is div#left wide enough to allow two 150px-wide <dl>s, plus padding and margins, to float side-by-side?”

If the answer is Yes, then the <dl>s are set to width: 150px, and they wrap around, two to a line.

If the answer is No, then the <dl>s are set to the-width-of-div#left-minus-150px, and sit one to a line. (Using the width of div#left as a starting point ensures that the <dl>s will never overflow their container.)

This way there will never be unused white space; both wide and narrow screens (and everything in between) are provided for.

Neat, eh?

Here’s the Javascript code:

  2. // Event Listener
  3. // by Scott Andrew -
  4. function addEvent(obj, evType, fn)
  5. {
  6. if (obj.addEventListener)
  7. {
  8. obj.addEventListener(evType, fn, false);
  9. return true;
  10. }
  11. else if (obj.attachEvent)
  12. {
  13. var r = obj.attachEvent('on'+evType, fn);
  14. return r;
  15. }
  16. else
  17. {
  18. return false;
  19. }
  20. }
  22. // from your man at
  23. addEvent(window, "load", resizeBooks);
  24. addEvent(window, "resize", resizeBooks);
  26. function resizeBooks(e)
  27. {
  28. // check this browser can cope with what we want to do
  29. if (!document.getElementById) return;
  30. var bd = document.getElementById('rec-books-lists');
  31. if (!bd) return;
  32. var ad = document.getElementById('rec-authors-lists');
  33. if (!ad) return;
  34. var lf = document.getElementById('left');
  35. if (!lf) return;
  36. if (!lf.offsetWidth) return;
  37. cnbd = bd.childNodes;
  38. cnad = ad.childNodes;
  40. // if div#left is wide enough to accept two or more floated <dl>s
  41. if (lf.offsetWidth >= 621)
  42. {
  43. // loop through all the dls in div#rec-books-lists and resize them to 150px
  44. for (var i=0;i<cnbd.length;i++)
  45. {
  46. if (cnbd[i].nodeName.toLowerCase() == 'dl')
  47. {
  48. cnbd[i].style.width = '150px';
  49. }
  50. }
  51. // loop through all the dls in div#rec-authors-lists and resize them to 150px
  52. for (var i=0;i<cnad.length;i++)
  53. {
  54. if (cnad[i].nodeName.toLowerCase() == 'dl')
  55. {
  56. cnad[i].style.width = '150px';
  57. }
  58. }
  59. }
  61. // if div#left is too narrow to accept two or more floated <dl>s
  62. else
  63. {
  64. // loop through all the dls in div#rec-books-lists and resize them to the-width-of-div#left-minus-150px
  65. for (var i=0;i<cnbd.length;i++)
  66. {
  67. if (cnbd[i].nodeName.toLowerCase() == 'dl')
  68. {
  69. cnbd[i].style.width = (lf.offsetWidth - 150) + 'px';
  70. }
  71. }
  72. // loop through all the dls in div#rec-authors-lists and resize them to the-width-of-div#left-minus-150px
  73. for (var i=0;i<cnad.length;i++)
  74. {
  75. if (cnad[i].nodeName.toLowerCase() == 'dl')
  76. {
  77. cnad[i].style.width = (lf.offsetWidth - 150) + 'px';
  78. }
  79. }
  80. }
  81. }
  82. Download this code: 306a.txt

Browser issues

The only blot on the landscape here is that some browsers (Opera and Safari 1.0.2) become confused at the idea of absolutely positioning an element within a floated container, consequently this sort of thing happens:

1.5 Opera and Safari 1.0.2 get confused

To get around this I’ve had to mess with the CSS and introduce a couple of annoying extra rules. Firstly I code everything as normal, so IE gets the nice layout. Then I remove the float using a Child combinator so Opera displays the page in an acceptable format, and then finally I use an Attribute selector to re-re-set the float for FireFox.

Bit of a laugh, eh?

Here’s some of the CSS, to illustrate that:

  1. /* lay everything out for browsers like IE */
  2. body#reading dl {
  3. border-bottom: 1px solid #ddd;
  4. float: left;
  5. height: 170px;
  6. margin: 0 25px 20px 0;
  7. padding: 0 0 0 113px;
  8. position: relative;
  9. width: 150px;
  10. }
  12. body#reading dl dd div {
  13. background: url('/blog/commonpics/bg_image.gif') no-repeat bottom right;
  14. left: 5px;
  15. position: absolute;
  16. top: 5px;
  17. }
  20. /* reset float for Opera */
  21. html > body#reading dl {
  22. float: none;
  23. }
  25. /* reset float for FF */
  26. html[xmlns] body#reading dl {
  27. float: left;
  28. }
  29. Download this code: 306b.txt

And there you have it. If you find any browser bugs, then please let me know.

Thanks to Stuart for writing the initial Javascript code, and to Marc Blessington, Rimantas Liubertas and Douglas Bowman for trying to help with the Opera issue.

Jump up to the start of the post

Comments (36)

Jump down to the comment form ↓

  1. Tony Crockford:

    Bad news I'm afraid.

    In Opera 7.5 (preview3) I just get the thin view - text expanded - no matter what width my window.

    Doesn't double up, sorry.


    Posted 26 minutes after the fact
    Inspired: ↓ Dunstan
  2. Tony Crockford:

    Oh, maybe I didn't understand - is that how you fixed it for Opera?

    sorry... confused today - must be Friday

    Posted 28 minutes after the fact
    Inspired: ↓ Dunstan
  3. Dunstan:

    That's right - I had to remove the float for Opera (that's what the extra CSS rules were for).

    So what you're seeing is what I meant you to see :o)

    Posted 30 minutes after the fact
    Inspired by: ↑ Tony Crockford, ↑ Tony Crockford
  4. Addie:

    nevermind the java (although the layout is lovely)...i am delighted to see that you have three men in a boat on your list! hello, by the way!

    Posted 1 hour, 3 minutes after the fact
    Inspired: ↓ Dunstan
  5. Geof:

    Why, that's spifftacular.

    Posted 1 hour, 16 minutes after the fact
  6. Dunstan:

    I love that book, and I like the audio tape even more - Hugh Laurie reads it, and he's just perfect :o)

    Posted 1 hour, 19 minutes after the fact
    Inspired by: ↑ Addie
  7. Hans Hyttinen:

    Hey, good thing you posted this. I might finally find a solution to get my photos page working! (in all browsers)

    Posted 1 hour, 37 minutes after the fact
  8. Karen:

    You always have our aesthetic interests at heart, don't you? Looks great, and thanks for including American Psycho. I find myself having to defend this brilliant book (and movie!) more often than I'd like. :-)

    Posted 1 hour, 43 minutes after the fact
  9. Andreas:

    Bad news here: Firefox 0.8 does not display two columns even if I resize the window to 1600 pixels wide; and IE 6 crashed on me when I tried to resize the browser window - I'm on Win2000.

    Posted 1 hour, 53 minutes after the fact
    Inspired: ↓ Dunstan, ↓ Doug
  10. Dunstan:


    I'm on XP Pro, and both FF 0.8 and IE 6.0 work perfectly.

    Can anyone else confirm or deny this problem on Win2000?
    I'm not so worried about FF, but I'd rather IE didn't die :o)

    Posted 1 hour, 57 minutes after the fact
    Inspired by: ↑ Andreas
    Inspired: ↓ Andreas, ↓ Doug, ↓ Nicole
  11. Justin:

    I was confused for a moment when I set my preference for Chapters and, after the refresh, Collins was selected. Pretty minor, but it threw me off for a sec.

    To see your Opera trick I tried it using v7.23 and it looks very good. I think for anyone who uses Opera all the time, they wouldn't think twice about it.

    A great reading list, displayed with impeccable technique.

    Posted 2 hours, 3 minutes after the fact
    Inspired: ↓ Dunstan
  12. Dunstan:

    Ooh, well spotted, Justin, I've fixed that bug now :o)

    It's amazing how bugs sneak in isn't it? I must have tried that page 20 times before I put it live, and the moment I do, two people (one privately) point out bugs with it. Sneaky little things!

    Posted 2 hours, 10 minutes after the fact
    Inspired by: ↑ Justin
  13. Andreas:

    Dunstan, it seems that IE tries to reload all the images of that page when I resize. It says it's fetching 46 page elements but never get any further. CPU at 100%.

    Posted 2 hours, 21 minutes after the fact
    Inspired by: ↑ Dunstan
    Inspired: ↓ Dunstan
  14. Mark Wubben:

    Nice job, Dunstan.

    I have some comments on the JavaScript, though:

    * Clarity is far more important than easy-to-type-names and obscurity: bd becomes bookList.

    * In the loop through the childNodes of the list, do a check for node.nodeType. For element nodes this should be 1. For text nodes node.nodeName returns #text, which of course does not equal dl, so it won't break your code. Again this is about clearity, somebody reading your code can see the loop is only meant to run on element nodes.

    (the following two are really nitpicking, oh well)

    * Instead of using the square brackets to access items in the NodeList (returned by document.getElementsByTagName and node.childNodes) use nodeList.item(n).

    * Changing the CSS rules inside using JavaScript will be faster than the loop method you use now, especially when the list of books grows even more.

    Off-topic: Wilbur Smith rules supreme, been reading his books for some months now. The two Courtney books about Hal and Tom are the best.. great atmosphere in them.

    Posted 2 hours, 24 minutes after the fact
    Inspired: ↓ Dunstan, ↓ Dunstan
  15. Dunstan:

    That's great, thanks Mark. I'll go through and try to make those changes :o)

    Posted 2 hours, 28 minutes after the fact
    Inspired by: ↑ Mark Wubben
  16. Doug:

    Yep: IE 6.0 on Win2000 dies before it even finishes loading for me. No chance to resize. But Moz 1.5 works fine. I would have expected FF 0.8 to do the same as Moz, but I don't have it installed to check.

    Nice effect. Too bad there were so many hoops to jump through just to get it to work.

    The only gripe I have about the layout (and trust me, it's very minor) is that the double column only appears once I've resized to at least 924px wide. My rule of thumb is that a maximized browser on an 800x600 screen should show the default/preferred layout, which in this case I assume to be the two-column layout. Granted it looks fine either way.

    Posted 2 hours, 32 minutes after the fact
    Inspired by: ↑ Andreas, ↑ Dunstan
    Inspired: ↓ Dunstan
  17. Dunstan:

    Bugger me, _my_ version of IE is dying now as well!

    Hmm, well, I'll make the changes that Mark suggests and see if that has any effect.

    Posted 2 hours, 40 minutes after the fact
    Inspired by: ↑ Andreas
  18. Dunstan:

    "Nice effect. Too bad there were so many hoops to jump through just to get it to work."

    Yes. The two little CSS rules aren't so bad, but any kind of 'hack' is a pain.

    "The only gripe I have about the layout (and trust me, it's very minor) is that the double column only appears once I've resized to at least 924px wide."

    You're right, it'd be nice to see the two cols before that, but space just doesn't allow it. I can't make the <dl>s any smaller because I have to give enough room for the text to grow for those with larger default font sizes.

    And I think that any reduction in the padding and margins would spoil the layout. The balance is nice right now.

    " 800x600 screen should show the default/preferred layout, which in this case I assume to be the two-column layout..."

    There's not really any default layout - I like to think that it gracefully adapts rather than gracefully fails. That's the intention any way.

    Posted 2 hours, 49 minutes after the fact
    Inspired by: ↑ Doug
  19. Mark Wubben:

    The code is pretty straight forward, it shouldn't crash anything. Perhaps it's something in the loop. Let's hope my suggestions will fix it :)

    Posted 3 hours, 23 minutes after the fact
  20. Taylor:

    Yeah, when I load the book page and try to resize the window in IE6/XP it freezes my browser.

    Great thinking and effect, but if you cant get it to not kill IE are you going to keep it? I think it would be a bad decesion, causing harm to a large part of your audience (I'm so not *cool* because I actually prefer IE over moz...well MyIE2)

    Posted 3 hours, 53 minutes after the fact
  21. Nicole:

    I can also confirm that IE 6.0 (SP 1) crashes when I resize the browser window. Firefox 0.8 works like a breeze, however. I'm running Windows 2000.

    Posted 4 hours, 19 minutes after the fact
    Inspired by: ↑ Dunstan
  22. Oliver:

    Moz 1.2 displays the page like Opera did before you made the changes to the CSS, on Win XP Home. But then again, Moz 1.2 isn't the latest.

    Posted 4 hours, 39 minutes after the fact
  23. Dunstan:

    Okay, thanks for everyone's testing - I just wanted to say that Mark's comments (see above) have made me rethink how I'm doing this, and I now have a much better method.

    I'll post it here when I've double-checked with Mark that I haven't missed anything.


    Posted 4 hours, 50 minutes after the fact
    Inspired by: ↑ Mark Wubben
    Inspired: ↓ Dunstan
  24. Dunstan:

    Right, I've uploaded the new code to the Reading page, and it should work on everything except that older version of Moz that Oliver mentions.

    I'll write up a revised post after Mark gets back to me and assures me I couldn't have improved it further.

    Posted 5 hours, 14 minutes after the fact
    Inspired by: ↑ Dunstan
  25. Brahm:

    Nice work. An odd quirk I've noticed is that the footer that contains the copyright, accessibility, etc. does not consistently get drawn when resizing the page on IE6/Win2K. I've been able to reproduce it most consistently when at the bottom of the page and resize from the 1 column layout to the 2 column, though it doesn't seem to always happen.

    Posted 5 hours, 31 minutes after the fact
    Inspired: ↓ Hans Hyttinen, ↓ Dunstan
  26. Hans Hyttinen:

    Oooooooooh! Aaaaaaaah! I checked out the Reading page in IE6 and now the books are in rows of 3's! This must be the first time IE produces something that looks better!

    However, the shadows aren't working correctly in IE6. How could you let this happen, Dunstan? They work perfectly in IE6 at my site:

    Oh, and on most of the pages, there's a big fat grey strip on the left of the sidebar. Oh, and the tabs are broken. Ok, I take back what I said about IE earlier. Microsoft stills sucks.

    Posted 5 hours, 35 minutes after the fact
    Inspired: ↓ Waylman, ↓ Dunstan
  27. Waylman:

    IE6 now works for me. Very nice.

    I was about to post and say that IE6 died for me too (on Win98SE) but I saw you were about to make changes. So I figured I'de wait. Looks like you solved the problem.

    Note: Also works great in Firefox - but you already new that.

    Posted 5 hours, 37 minutes after the fact
  28. Hans Hyttinen:

    Testing out with IE6/winXP, I don't see that. A few solutions: demand that Dunstan fixes everything, or damn Microsoft to hell and hug the penguin.

    Posted 5 hours, 38 minutes after the fact
    Inspired by: ↑ Brahm
  29. Waylman:

    Your right, the shadows only display on bottom but not sides and the tabs have a small break between the left side and the top border in IE. Didn't notice that till you pointed it out.

    However, I don't see and big fat grey strip. And I don't get 3 across (which would be cool). Must be you have a bigger screen and/or res than me.

    Posted 5 hours, 46 minutes after the fact
    Inspired by: ↑ Hans Hyttinen
    Inspired: ↓ Dunstan
  30. Dunstan:

    Hmm, you're right, Brahm. I'll have to look into that at some point in the future... thanks for the bug report.

    Posted 6 hours, 16 minutes after the fact
    Inspired by: ↑ Brahm
  31. Dunstan:

    Hans - the three rows appear because IE doesn't support max-width. It's the only page on the site that does look better in IE, you're absolutely right.

    However, the shitty behaviour it exhibits as regards your other bug reports rather overshadows that.

    The tabs - I have no idea, and can't be bothered to waste the time figuring it out (sad, but true).

    The grey strip - is an utter mystery to me. I spent ages trying to figure this out out a while back and in the end I gave up, it's really very odd indeed.

    And the shadows - yeah, I know, I know, but once again it's a case of "IE gets whatever I have time to give it". I'm sure I could fix the bug, but unless the solution is slapping me in the face, I don't have time right now to sort it out.

    I wish I could give everyone a beautiful site, but I'm afraid it's just not possible. I just run out of time.

    Thanks for pointing out the problems though, I'll pop your comment into my 'Bugs' folder.

    Posted 6 hours, 24 minutes after the fact
    Inspired by: ↑ Hans Hyttinen, ↑ Waylman
  32. Dunstan:

    Okay, new code posted here:

    Posted 7 hours, 24 minutes after the fact
  33. Paul:

    Mozilla 1.6 (on Win2K) shows just one column, no matter how wide the window is ... :(

    Posted 7 hours, 44 minutes after the fact
  34. Hans Hyttinen:

    Ok, the grey strip has myteriously disappeared (on all browsers).
    However, on Netscape 7.1 (what? you didn't know it still exists?) all the book cover images are on top of each other, as explained in your post about the same bug in Opera. That's all, besides the tabs in IE.

    Posted 11 hours, 18 minutes after the fact
  35. Chris Hester:

    Man, this sucks. In Opera 7.23 on Windows XP, I see one column only of books, needing a lot of scrolling, and a complete waste of white space on the right. Why can't I have it like the first screenshot?

    So I tried this page in IE6, only to see the side menu pushed over to the right, a quite big grey stripe down the left side of it, which then emerges at the bottom of the side menu to become the whole right edge. That's on THIS page.

    On the book page, I see two columns of books - much nicer.

    I would bring back the fixed width!

    I use floated images on some pages of my site (see the Artwork and Photography intro pages) and they float perfectly to fit the screen width. But then I'm not using definiton lists.

    Posted 2 days, 22 hours after the fact
  36. Dunstan:

    Comments are now closed for this entry, please leave any remarks relating to this stuff over at 'Flexible Floats 3'

    Thanks - Dunstan

    Posted 3 days, 1 hour after the fact

Jump up to the start of the post

Add your comment

I'm sorry, but comments can no longer be posted to this blog.