views:

2572

answers:

12

Puzzle Grinch

Part I

This layout can be done quite simply with 2 HTML tables, one nested inside the other, or even with a single table.

It can also be done with CSS, though it might involve a little more thinking.

This may not be a real world layout, but I have seen pages that are similar. Consider this a riddle; an exercise to buff up your CSS skills.

To make things a little more interesting, I have framed the question in a little 2 part web page called The Challenge. We will examine the code and the question: Layout with tables or CSS?, side-by-side, blow-by-blow, as our two opponents battle it out for code supremacy.

Part I lays out how The Challenge came to be. I hope you enjoy.

Part II is The Decision. You might be surprised.


Part II

I was amazed at how quickly really good answers appeared mere minutes after I posted. It was a humbling experience. Gentlemen, I have no desire to compete in time trials with you.

BUT, all that being said, upon close examination of the solutions offered, I came to realize that none of the CSS solutions (including my own at the time) worked as well as either of the table solutions offered. The Challenge was all about CSS being better than tables for any layout solution.

So I added 3 new rules (remember, one of the rules is that the rules can be changed). This annoyed some people. So then I added some colorful explanations about why the rules were changed. I think this annoyed them even more.

  1. Our garden is to have a fence around it; something to set it apart from whatever dreary surroundings it may find itself in; and not too expensive, but easy to keep clean. So I want a 1 pixel black border around the garden
  2. Inhabitants of each garden plot (the characters) must be either black or white, depending on which shows them the best in their garden. Also they are all of cursive descent. There are no italics amoung them. ;-)
  3. The garden is relocatable, that is, I can have this garden, anywhere on the page (no absolute positioning).

This is what the final output is to look like (background color optional):

alt text

My apologies for the capricious and last minute rule changes. I had it wrong. The inhabitants of each garden plot are artisans, hand crafted specialists. They are descendants of the cursive family, and owe their sense of style to the italics.

The garden has to be relocatable because both kinds of gardens (table and CSS) need to coexist on the same page. I may be wrong to say that position:absolute rules are not allowed. If you can get them to work in this context, then more power to you. They will certainly be accepted.

I asked for a fence around the plot because each garden type is going to be planted in a countryside with an orange background very similar to the color of the some of the flowers we grow.

I live in Holland now, and the Tulip season is fast approaching. If you fly over Holland in the next few weeks, and it's a clear day (kind of rare here) the landscape below you will look rather similar to this silly exercise.

I'm not crazy about orange but I do like and admire the Dutch, so that is why we have an orange background, a tribute to my host country. :-)


Part III

I have posted Ted's table answer from The Challenge below along with this image

alt text

because the occupants can be easily added to the garden plots without touching the CSS rules - everything is automatically centered.

Can you do this with CSS? Can you chop down the mightiest tree in the forest with... a herring?


Update: Charlie's answer is here.

+14  A: 

Here are three solutions.

The markup:

<div id="outer">
    <div id="a1">1</div>
    <div id="a2">2</div>
    <div id="a3">3</div>
    <div id="a4">4</div>
    <div id="a5">5</div>
    <div id="a6">6</div>
    <div id="a7">7</div>
    <div id="a8">8</div>
    <div id="a9">9</div>
</div>

The basic stylesheet (dimensions and color):

#outer {
    width: 20em;
    height: 20em;
}
#a1 {
    background-color: #C0C0C0;
    width: 80%;
    height: 20%;
}
#a2 {
    background-color: #800000;
    width: 20%;
    height: 80%;
}
#a3 {
    background-color: #000080;
    width: 20%;
    height: 80%;
}
#a4 {
    background-color: #FF0000;
    width: 40%;
    height: 20%;
}
#a5 {
    background-color: #0000FF;
    width: 20%;
    height: 40%;
}
#a6 {
    background-color: #FFFF00;
    width: 20%;
    height: 40%;
}
#a7 {
    background-color: #FFFFFF;
    width: 20%;
    height: 20%;
}
#a8 {
    background-color: #008000;
    width: 40%;
    height: 20%;
}
#a9 {
    background-color: #FFA500;
    height: 20%;
    width: 80%;
}

And now the positioning:

  • Using float:

    #a1 {
        float: left;
    }
    #a2 {
        float: right;
    }
    #a3 {
        float: left;
    }
    #a4 {
        float: left;
    }
    #a5 {
        float: right;
    }
    #a6 {
        float: left;
    }
    #a7 {
        float: left;
    }
    #a8 {
        float: right;
    }
    #a9 {
        float: right;
    }
    
  • Using position:

    #outer {
        position: relative;
    }
    #outer div {
        position: absolute;
    }
    #a1 {
        top: 0;
        left: 0;
    }
    #a2 {
        top: 0;
        right: 0;
    }
    #a3 {
        top: 20%;
        left: 0;
    }
    #a4 {
        top: 20%;
        left: 20%;
    }
    #a5 {
        top: 20%;
        right: 20%;
    }
    #a6 {
        top: 40%;
        left: 20%;
    }
    #a7 {
        top: 40%;
        left: 40%;
    }
    #a8 {
        bottom: 20%;
        right: 20%;
    }
    #a9 {
        bottom: 0;
        right: 0;
    }
    
  • Using margin:

    #a1 {
    }
    #a2 {
        margin: -20% -80% 0 80%;
    }
    #a3 {
        margin: -60% 0 0 0;
    }
    #a4 {
        margin: -80% -20% 0 20%;
    }
    #a5 {
        margin: -20% -60% 0 60%;
    }
    #a6 {
        margin: -20% -20% 0 20%;
    }
    #a7 {
        margin: -40% -40% 0 40%;
    }
    #a8 {
        margin: 0 -40% 0 40%;
    }
    #a9 {
        margin: 0 -20% 0 20%;
    }
    
Gumbo
text isn't vertically and horizontally centered. (nor is it italic, although that's a minor quibble.)
Sam Hasler
Technically it's also not to the correct size (the challenge page linked to in the question states that there is a 35px square in the center.)
Sam Hasler
Well I though it’s a layout question and not a pixel-by-pixel question.
Gumbo
It's both layout an pixel. I want it ALL.
Diogenes
Well then just replace 20em by 175px. The rest stays the same.
Gumbo
+12  A: 

This matches your table example exactly, including the vertically and horizontally centered text (which no one else has done so far).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

 <title>Boxy Boxes in a Box</title>

 <style type="text/css" media="screen">
  #container {position: relative; margin: 100px auto; height: 175px; width: 175px; font-style: italic; }

  .box {width: 35px; height: 35px; position: absolute; text-align: center; line-height: 35px;}

  #box_1 {top: 0; left: 0; width: 140px; background-color: silver;}
  #box_2 {top: 0; right: 0; height: 140px; background-color: maroon; line-height: 140px;}
  #box_3 {top: 35px; left: 0; height: 140px; background-color: navy; line-height: 140px;}
  #box_4 {top: 35px; left: 35px; width: 70px; background-color: red;}
  #box_5 {top: 35px; right: 35px; height: 70px; background-color: blue; line-height: 70px;}
  #box_6 {top: 70px; left: 35px; height: 70px; background-color: yellow; line-height: 70px;}
  #box_7 {top: 70px; left: 70px; background-color: white;}
  #box_8 {bottom: 35px; right: 35px; width: 70px; background-color: green;}
  #box_9 {bottom: 0; right: 0; width: 140px; background-color: orange;}
 </style>
</head>

<body>
 <div id="container">
  <div id="box_1" class="box">1</div>
  <div id="box_2" class="box">2</div>
  <div id="box_3" class="box">3</div>
  <div id="box_4" class="box">4</div>
  <div id="box_5" class="box">5</div>
  <div id="box_6" class="box">6</div>
  <div id="box_7" class="box">7</div>
  <div id="box_8" class="box">8</div>
  <div id="box_9" class="box">9</div>
 </div>
</body>
</html>
Tyson
Well done, you got there first. I've borrowed some ideas for my own answer. I've tried to make mine as concise as I can.
Sam Hasler
(In case you've moved on and haven't noticed the updates to the question) are you going to update to follow the new rules?
Sam Hasler
Eh, not really. I solved it as originally stated. I'm not going to blow 10 hours catering to random new rules every few hours. :) Your solution is better, anyways.
Tyson
Sorry about the new rules but they are really not random. I would like to put the table solution and css solution side-by-side on the same web page. I did try your code, looks great, but the position:absolute gave me problems. If I missed something, let me know.
Diogenes
+4  A: 

As long as the widths and heights are constant, one can always use absolute positioning to get the same effect. This should be obvious enough, so that I don't have to type it out (it's late here and I'm lazy :P)

Vilx-
+29  A: 

Update: Final edit. Switched to STRICT DTD, removed italic to match the image in the question, and reverted back to full colour names for ids to show intent as per OPs comment on question, and sorted the main column of id names in the css into the order they appear in the html.

I also opted not to reused the outer div as the white 7 square (it didn't have it's own div in previous edits), as it wouldn't have been practical if you wanted to use the layout, and felt a little like cheating (although from a brevity/pixel perfect standpoint I liked the cheekiness of it).

View here: http://jsbin.com/efidi
Edit here: http://jsbin.com/efidi/edit
Validates as XHTML strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>The Challenge</title>
<style type="text/css">
div     { text-align: center; width:175px; height:175px; line-height: 35px;}
div div {         float:left; width: 35px; height: 35px;}
#orange, #maroon,
#blue  , #green  {float:right;}

#orange, #silver {background-color:silver;  width:140px;}
#navy  , #maroon {background-color:maroon; height:140px; line-height:140px;}
         #navy   {background-color:navy  ;}
#green , #red    {background-color:red   ;  width: 70px;}
#yellow, #blue   {background-color:blue  ; height: 70px; line-height: 70px;}
         #yellow {background-color:yellow;}
         #white  {background-color:white ;}
         #green  {background-color:green ;}
         #orange {background-color:orange;}
</style> 
</head> 
<body> 
  <div> 
    <div id="silver">1</div> 
    <div id="maroon">2</div> 
    <div id="navy"  >3</div> 
    <div id="red"   >4</div> 
    <div id="blue"  >5</div> 
    <div id="yellow">6</div> 
    <div id="white" >7</div>
    <div id="green" >8</div> 
    <div id="orange">9</div> 
  </div>
</body></html>

Aside: I would perhaps put a little more whitespace in if I could, but this is at the limit before the code blocks here on SO starts getting scrollbars and I opted to have it all appear on screen.

Note: I borrowed the line-height fix from Tyson (who was first to get a correctly rendering answer).

Sam Hasler
This solution works in IE 5.5, IE7, and Firefox 3. It just needs the numbers and it's perfect.
attack
@attack, Thanks for pointing that out, fixed now.
Sam Hasler
Minified my answer and by my count it's 180 characters less than the table solution: 1042 (table) to 858 (mine) characters not counting body/head/style tags.
Sam Hasler
You forgot the right font “Comic Sans MS” and blue text color if you really want a pixel perfect solution. ;)
Gumbo
It does NOT render correctly in IE6.SP1 on Win2k. (but what does?)
Jacco
In the image above the text is black and non-italic, so I've decided to ignore the font now.
Sam Hasler
Sam, the rules specify xhtml STRICT, not Transitional... You're about to save your self 12 more characters!
Prestaul
@Prestaul: thanks for pointing that out. Totally overlooked that.
Sam Hasler
I tried this but I didn't get the smug martian next to it! :p
Chetan Sastry
Blast, rule change, looks like that's not going to be my final edit.
Sam Hasler
here's a version that obeys all the new rules http://jsbin.com/oqade/edit but I haven't been able to meet Ted's challenge. The only way to have extra characters is to manually set the height of the content in the css: http://jsbin.com/ohoci/edit but I don't think that's an acceptable solution.
Sam Hasler
Hey Sam, special thanks to you. LOL -I only got one vote for "Charlie's" answer, and I have no way of proving this, but my suspicions are it may have been you ;-)
Diogenes
Wow, That's awesome
ebattulga
+11  A: 

Here you go - less lines than any misuse of table tags can provide:

<img
    src="http://sontag.ca/TheChallenge/tiles.gif"
    alt="nine assorted coloured rectangles"
/>

:P

Peter Boughton
You can even fit it in just one line!
Gumbo
If necessary, yes, but this is more readable. :)
Peter Boughton
You forgot to use CSS... ;)
E Dominique
No, I specifically avoided it, to make a point.
Peter Boughton
that's _the_ correct solution from a developer!:)
boj
it's not funny at all
kavoir.com
+3  A: 

I took a slightly different approach than the "id everything" solutions I've seen so far. This comes in less than 100 chars more than the table based solution.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>The Challenge</title>
<style type="text/css">
div {
    position:absolute;
    width:35px;
    height:35px;
    text-align:center;
    line-height:35px
}

.spiral { width:175px; height:175px }

.t { top:0 }
.l { left:0 }
.r { right:0 }
.b { bottom:0 }
.w { width:140px }
.h { height:140px; line-height:140px }
.c {
    top:35px;
    left:35px;
    width:105px;
    height:105px
}

.c .w { width:70px }
.c .h { height:70px; line-height: 70px }
.c .c { width:35px; height: 35px }
</style>
</head>
<body>
<div class="spiral">
    <div class="t l w" style="background-color:silver">1</div>
    <div class="t r h" style="background-color:maroon">2</div>
    <div class="b l h" style="background-color:navy">3</div>
    <div class="c">
     <div class="t l w" style="background-color:red">4</div>
     <div class="t r h" style="background-color:blue">5</div>
     <div class="b l h" style="background-color:yellow">6</div>
     <div class="c">7</div>
     <div class="b r w" style="background-color:green">8</div>
    </div>
    <div class="b r w" style="background-color:orange">9</div>
</div>
</body>
</html>

Edit: Based on your modifications I'm posting a slightly more verbose but hopefully clearer solution that adds a black border, sets some text to white, and does not absolutely position the "garden".

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>The Challenge</title>
<style type="text/css">
div {
    position:absolute;
    width:35px;
    height:35px;
    text-align:center;
    line-height:35px
}

div.spiral {
    position:relative;
    width:175px;
    height:175px;
    border: 1px solid #000
}

.top { top:0 }
.left { left:0 }
.right { right:0 }
.bottom { bottom:0 }
.wide { width:140px }
.tall { height:140px; line-height:140px }
.center {
    top:35px;
    left:35px;
    width:105px;
    height:105px
}

.center .wide { width:70px }
.center .tall { height:70px; line-height: 70px }
.center .center { width:35px; height: 35px }
</style>
</head>
<body>
<div class="spiral">
    <div class="top left wide" style="background-color:silver">1</div>
    <div class="top right tall" style="background-color:maroon">2</div>
    <div class="bottom left tall" style="background-color:navy;color:#fff">3</div>
    <div class="center">
        <div class="top left wide" style="background-color:red">4</div>
        <div class="top right tall" style="background-color:blue">5</div>
        <div class="bottom left tall" style="background-color:yellow">6</div>
        <div class="center">7</div>
        <div class="bottom right wide" style="background-color:green">8</div>
    </div>
    <div class="bottom right wide" style="background-color:orange">9</div>
</div>
</body>
</html>
Prestaul
Minified my own answer and by my count it's 180 characters less than the table solution: 1042 (table) to 858 (mine) characters not counting body/head/style tags.
Sam Hasler
The floating solution is very elegant and compact, nice work Sam. I was going for something more in the spirit of css. This solution could be used to put multiple "tiles" on the same page without duplicating the css and I'm hoping that it is readable and easy to comprehend.
Prestaul
I like your JSBin link, so I've put a version of my code with two tiles out there if anyone wants to play with it: http://jsbin.com/avive
Prestaul
This is an interesting approach too, though I am having a little difficulty following it. Can you change your class names to something that better expresses intent? No penalty for the few extra characters but big points if the class names express intent and help in understanding.
Diogenes
Ok... I've update with a new version that has clearer class names and fulfills your other new requests. New version here: http://jsbin.com/uzaba
Prestaul
Sam Hasler
There are ways to get the cells to vertically align and still be content agnostic, but it isn't an easy undertaking in css unless you use display:cell-table and vertical-align. (Is that cheating?) Unfortunately cell-table is not supported in IE unless the element is a TD or TH...
Prestaul
I think that I'm done chasing Diogenes' whims. It should be a simple task to change the text color of the other plots. I posted this after he said "characters must be either black or white, depending on which shows them the best in their garden"... Pretty subjective. I preferred only one white.
Prestaul
+1  A: 

Brevity of markup....

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>The Challenge</title>
<style type="text/css">
 .garden {
  position: relative;
  width: 175px;
  height: 175px;
  font-family: 'Comic Sans MS', cursive;
  border: 1px solid;
  color: #000;
  }
 .garden div {
  position: absolute;
  width: 35px;
  height: 35px;
  line-height: 35px;
  text-align: center;
  }
 .garden div:first-child {
  width: 140px;
  background: silver;
  }
 .garden div:first-child + div {
  right: 0;
  height: 140px;
  line-height: 140px;
  color: #fff;
  background: maroon;
  }
 .garden div:first-child + div + div {
  top: 35px;
  height: 140px;
  line-height: 140px;
  color: #fff;
  background: navy;
  }
 .garden div:first-child + div + div + div {
  top: 35px;
  left: 35px;
  width: 70px;
  background: red;
  }
 .garden div:first-child + div + div + div + div {
  top: 35px;
  right: 35px;
  height: 70px;
  line-height: 70px;
  background: blue;
  }
 .garden div:first-child + div + div + div + div + div {
  top: 70px;
  left: 35px;
  height: 70px;
  line-height: 70px;
  background: yellow;
  }
 .garden div:first-child + div + div + div + div + div + div {
  top: 70px;
  left: 70px;
  background: white;
  }
 .garden div:first-child + div + div + div + div + div + div + div {
  top: 105px;
  left: 70px;
  width: 70px;
  background: green;
  }
 .garden div:first-child + div + div + div + div + div + div + div + div{
  bottom: 0;
  right: 0;
  width: 140px;
  background: orange;
  }

    </style> 
</head> 
<body> 
<div class="garden"> 
<div>1</div> 
<div>2</div> 
<div>3</div> 
<div>4</div> 
<div>5</div> 
<div>6</div> 
<div>7</div>
<div>8</div> 
<div>9</div> 
</div>
</body>
</html>

link

Andy Ford
Interesting approach, but this won't work in IE6...
Prestaul
Yeah, just wanted to spice things up a little
Andy Ford
You can shorten your markup even further by using the "content: '';" CSS rule, too.
Tyson
@Tyson - technically true, but presentation belongs in the CSS and content belongs in the HTML.@Presthaul - running with the 'garden' metaphor... I wouldn't want to plant my garden in such bad soil anyway
Andy Ford
+2  A: 

Single table solution.

Now don't down-vote me.

I know this is not an answer to the original question.
I posted this answer because the OP requested it in a comment to the original question.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="Content-language" content="en" />
        <title>The Challenge</title>
    </head>
    <body>

        <table cellspacing="0" cellpadding="0" border="0" summary="">
            <tr>
                <td colspan="4" height="35" align="center" bgcolor="silver"><i>1</i></td>
                <td rowspan="4" width="35" align="center" bgcolor="maroon"><i>2</i></td>
                <td rowspan="5" valign="bottom"><img src="http://sontag.ca/gif/grinch.gif" width="41" height="122" alt="Dr. Suess's Grinch"/></td>
            </tr><tr>
                <td rowspan="4" width="35" align="center" bgcolor="navy"><i>3</i></td>
                <td colspan="2" height="35" align="center" bgcolor="red"><i>4</i></td>
                <td rowspan="2" width="35" align="center" bgcolor="blue"><i>5</i></td>
            </tr><tr>
                <td rowspan="2" width="35" align="center" bgcolor="yellow"><i>6</i></td>
                <td width="35" height="35" align="center"><i>7</i></td>
            </tr><tr>
                <td colspan="2" height="35" align="center" bgcolor="green"><i>8</i></td>
            </tr><tr>
                <td colspan="4" height="35" align="center" bgcolor="orange"><i>9</i></td>
            </tr>
        </table>

    </body>
</html>

It is valid XHTML 1.0 Transitional and I've included Dr. Suess character :)

By stripping Dr. Suess character, the <?xml declaration, the meta-tags and the summary attribute you could cut it down to 929 characters and still be valid XHTML 1.0 Transitional.

Edit

As requested, XHTML 1.0 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>The Challenge</title>
        <style type="text/css">
            BODY {background: orange}
            #garden {border: 1px solid black; color: black}
            #garden TD {
                font: italic 100% 'Comic Sans MS', cursive;
                height: 35px;
                padding: 0;
                text-align: center;
                width: 35px
            }
            #c1 {background: silver}
            #c2 {background: maroon; color: white}
            #c3 {background: navy;   color: white}
            #c4 {background: red}
            #c5 {background: blue;   color: white}
            #c6 {background: yellow}
            #c7 {background: white}
            #c8 {background: green;  color: white}
            #c9 {background: orange}
        </style>
    </head>
    <body>

        <table id="garden" cellspacing="0">
            <tr>
                <td id="c1" colspan="4">1</td>
                <td id="c2" rowspan="4">2</td>
            </tr><tr>
                <td id="c3" rowspan="4">3</td>
                <td id="c4" colspan="2">4</td>
                <td id="c5" rowspan="2">5</td>
            </tr><tr>
                <td id="c6" rowspan="2">6</td>
                <td id="c7">7</td>
            </tr><tr>
                <td id="c8" colspan="2">8</td>
            </tr><tr>
                <td id="c9" colspan="4">9</td>
            </tr>
        </table>

    </body>
</html>

970 non-whitespace characters, orange background, Dr. Suess's Grinch removed.

Jacco
height, width and align attributes are not valid in XHTML. You need to specify these as separate CSS rules. It'll be a good exercise. See Ted's Table answer for tips on this.
Diogenes
I'm curious about a what single table solution might reduce to when done as XHTML strict.
Diogenes
Width and Height attributes are valid in Transitional. This one is not meant to be a solutions to your chalenge, but rather a single table example. That is why I did not use _any_ css. Others are free to work it into strict :)
Jacco
@Jacco - hey your new version cleaned up real good! So I concede to you on the table solution - yours is better. But I somehow think neither of our table solutions are going to win any votes here ;-)
Diogenes
The 'right' solution depends entirely on the nature of the data to be displayed, is it tabular or not. (if it is visual only, Peter Boughton solutions is hard to beat)
Jacco
+2  A: 
Diogenes
Sam Hasler
Yup - that qualifies as simple markup, right?
Diogenes
A: 
Diogenes
kudos for getting vertical-align: middle to work, I tried and failed.
Sam Hasler
Hmmm, using CSS to declare a DIV to be handled as if it was a table because you do not want to use a table... Feels like chasing your own tail.
Jacco
No, I wanted a DIV to center content vertically, a perfectly reasonable thing to ask for. My preference for using tables (or not) has nothing to do a with a need to center something in a box.
Diogenes
Those hacks for vertical align aren't working for me in IE7. (I'm on vista if that makes a difference)
Sam Hasler
The IE hacks won't automatically center content as the content changes and to be honest, I have no idea what how they work. If Vista is different, it would not be a big surprise.
Diogenes
I did a browser shot with IE6 and IE8. IE6 was messed up but IE8 looked good. It looks like IE8 even ignored the IE hack that was in there (though hard to tell from the SS). So the IE8 box model has some major improvements to it. That should make life easier for all of us.
Diogenes
I see what the problem is, the hacks have to be changed whenever the content does: http://jsbin.com/ogume that's really no better than the solution I posted in the comments to my answer.
Sam Hasler
Yes, this isn't really doing vertical centering in IE, it is manually positioning it to the center. Diogenes, it doesn't render correctly in IE6 because IE6 doesn't support descendant selectors.
Prestaul
@Sam - all right, I've removed my 'accepted answer' status (it was bad form to do that, but I had no votes and I could not vote for myself, and that is what I ended up doing. Still learning the ropes here.
Diogenes
@Sam - so my CSS soultion does not work for IE7, but I think it works for IE8. It seems to work on all other browsers. The Table solutionswork on everything. Which begs the question - Are tables really that bad? ;-)
Diogenes
Minimal action on this question now, even got down voted, so I am once again selecting Charlie's answer as my choice, even though it ain't the best possible. Thanks to all who helped with this!
Diogenes
@Diogenes, yes it was me that voted for this answer, although that was before I'd realised it didn't do the vertical centering automatically. It's also possible to simplify the markup and css using float right on 2 boxes instead of top:-35px on 5 boxes: http://jsbin.com/upabe/edit
Sam Hasler
A: 

I think we've proved that there's more than one way to do this. The table tag and CSS are both viable options.

Rather than add another way to complete the challenge I'd just like to say that, whether it's easier or harder, simpler or more complex: tables in HTML should be used for displaying tabular data.

  • Tables are made for tabular data.
  • CSS is made for styling/presentation.
T Pops
A: 

Here is an example that doesn't use absolute positioning, doesn't use table-cell, and is valid in IE6-8, FF, etc.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

<title>Terrible Ted's Table Layout</title>
<style type="text/css">
#box{border:1px solid #000; width:175px; height:175px; color:navy; font-family:"Comic Sans MS"; font-size:13px; font-style:italic; text-align:center;}

div {float:left}

#c1, #c3, #c4, #c7, #c8, #c9{height:35px; line-height:35px}
#c2, #c3{height:140px;line-height:140px}
#c5, #c6{height:70px; line-height:70px}

#c1, #c9{width:140px}
#c2, #c3, #c5, #c6, #c7{width:35px}
#c4, #c8{width:70px}

#c6, #c7 {margin-top:-35px}

#c1{background-color:silver}
#c2{background-color:maroon; float:right}
#c3{background-color:navy}
#c4{background-color:red}
#c5{background-color:blue}
#c6{background-color:yellow}
#c7{background-color:white}
#c8{background-color:green}
#c9{background-color:orange}

</style>
</head>
<body>
<div id="box">
<div id="c1">1</div>
<div id="c2">2</div>
<div id="c3">3</div>
<div id="c4">4</div>
<div id="c5">5</div>
<div id="c6">6</div>
<div id="c7">7</div>
<div id="c8">8</div>
<div id="c9">9</div>
</div>
</body>
</html>
pinxi