2

I want to style an HTML unordered list to look like a grid. The desired result is something like this:

Grid as rendnered by Firefox
(source: georgebrock.com)

I have the following HTML:

<ul class="grid">
  <li>First item. This is sometimes longer than the second item.</li>
  <li>2nd item</li>
  <li class="reset">Third item</li>
  <li>Fourth item</li>
</ul>

Styled by the following CSS:

ul.grid {
  /* Remove standard browser list styles */
  list-style:none;
  margin:0;
  padding:0;

  /* Add specific styles */
  width:13.5em; /* Clear internal floats (IE) */
  overflow:hidden; /* Clear internal floats (proper browsers) */
  background-color:#f00;
  border-bottom:0.5em solid #f00;
}

ul.grid li {
  display:inline; /* IE6 double margin float bug fix */
  width:5em;
  float:left;
  padding:0.5em;
  margin-left:0.5em;
  border-top:0.5em solid #f00;
  padding-bottom:1000.5em; /* } Balance height of items */
  margin-bottom:-1000em;   /* } */
  background-color:#fff;
}

ul.grid li.reset {
  clear:left;
}

In Firefox, Safari etc. this renders as required. In IE 6 however the clearing does not effect subsequent elements in the same way:

Grid as rendnered by Internet Explorer 6
(source: georgebrock.com)

You can see live example code here: http://georgebrock.com/misc/css-grid/

Any ideas?

Community
  • 1
  • 1
georgebrock
  • 28,393
  • 13
  • 77
  • 72
  • 1
    Ok I'll ask the obvious question: why not just use a table? – cletus Apr 05 '09 at 11:42
  • 2
    Tables are for tabular data, not for layout. – georgebrock Apr 05 '09 at 11:45
  • 1
    That would be true if you could do all layout without tables but you can't. Theres some pretty trivial examples that you simply can't do in a cross-browser way (back to IE6) without tables. – cletus Apr 05 '09 at 12:26
  • Using a table element communicates meaning about its content. If that meaning is not correct then there is a more fundamental problem with the page than the layout. I am yet to find a layout that cannot be done without tables, but in such a situation the layout (not the markup) should change. – georgebrock Apr 05 '09 at 12:46
  • Yet to find a layout that can't be done without tables eh? Well do this trivial layout that is supported back to IE6 then http://stackoverflow.com/questions/522928/can-you-do-this-html-layout-without-using-tables – cletus Apr 05 '09 at 23:10
  • Sorry but the layout of the page not the elements used conveys meaning. Are you also against the use of elements? Your views in this are naive bordering on the puritanical. – cletus Apr 05 '09 at 23:11
  • keep up the good fight george. Just had a go at this and it reminds me of problems I've had in the past and solved, but can't remember the solution... which doesn't help much, but at least I'm not having a go at YOU! – wheresrhys Apr 18 '09 at 09:42

2 Answers2

1

Question is old, but interesting. Could not find IE6, but same problem exists in IE7. There is no real solution for this, but visually in IE7 it can be achieved by playing with widths and using Adjacent Sibling (+) combinator. For IE6 each list element would have to have new class. So, not a real grid, but it looks like a grid:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>Test case: CSS grids</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <style type="text/css" media="screen">
            ul.grid {
                /* Remove standard browser list styles */
                list-style: none;
                margin: 0;
                padding: 0;

                /* Add specific styles */
                width: 220px; /* Clear internal floats (IE) */
                overflow: hidden; /* Clear internal floats (proper browsers) */
                border-bottom: 1px solid red;
            }

            ul.grid li {
                display: inline; /* IE6 double margin float bug fix */
                float: left;
                border: 1px solid red;
                padding: 5px;
                padding-bottom:1000.5em; /* } Balance height of items */
                margin-bottom:-1000em; /* } */
            }
            ul.grid li.reset {
                clear:left;
            }
            ul.grid li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
            ul.grid li + li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
            ul.grid li + li + li {
                width: 97px;
                border-left: 1px solid red;
                border-right: 0 none;
                padding-left: 5px;
            }
            ul.grid li + li + li + li {
                padding-left: 9px;
                border-left: 0 none;
                border-right: 1px solid red;
            }
            ul.grid li + li + li + li + li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
            ul.grid li + li + li + li + li + li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
            ul.grid li + li + li + li + li + li + li {
                width: 97px;
                border-left: 1px solid red;
                border-right: 0 none;
                padding-left: 5px;
            }
            ul.grid li + li + li + li + li + li + li + li {
                padding-left: 9px;
                border-left: 0 none;
                border-right: 1px solid red;
            }
            ul.grid li + li + li + li + li + li + li + li + li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
            ul.grid li + li + li + li + li + li + li + li + li + li {
                width: 98px;
                border-left: 1px solid red;
                border-right: 1px solid red;
                padding-left: 5px;
            }
        </style>
    </head>

    <body>

        <ul class="grid">
            <li class="reset">First item. This is sometimes longer than the second item.</li>
            <li>2nd item</li>
            <li class="reset">Third item</li>
            <li>Fourth item</li>
            <li class="reset">Fifth item</li>
            <li>Sixth item is maybe longer for a line.</li>
            <li class="reset">7th item</li>
            <li>Eight item is again longer</li>
            <li class="reset">9th item. This is sometimes longer than other.</li>
            <li>Tenth item</li>
        </ul>

    </body>
</html>
skobaljic
  • 9,379
  • 1
  • 25
  • 51
0

I would prefer to use tables for this, but if you can't (eg. a CMS or third party is pushing this markup to you).

If that's not an option I would try and use javascript to inspect the DOM to determine the maximum height of the 2 LIs, and then set the other one to that maximum.

Libraries such as jQuery can help with that.
See: Getting actual height of an auto-heighted element in IE

Community
  • 1
  • 1
Issa
  • 321
  • 2
  • 6