XHTML and Table Height

Album Cover: Vitalogy

"Wait for signs, believe in lies, to get by, it's divine."
Pearl Jam / Tremor Christ

Posted on December 12, 2003 10:04 PM in Web Development
Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.

As I've been tinkering around with XHTML 1.0 Strict this past week I've come across some very fine points that can mean a great deal to someone doing web development work. One example that I struggled with for quite a while was the old school method of using the table height attribute to center content vertically on a web page.

As it turns out, the table definition in the XHTML 1.0 Strict DTD does not allow for any specification of height. It was apparently decided that this keeps presentation separated from structure. However, this omission can make things a little hairy for developers who wish to vertically align content and not break their XHTML validity.

Now I've read plenty of opinions about just how important standards are when they hinder the task at hand in such a way, and they are definitely valid. In the case of table height, a developer merely has to rely on quirks mode to get the job done, using old HTML code that we used back in the old days of web design. To see what I mean, consider the following example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <body>
  <table style="height: 100%; width: 100%; background-color: #CCC;">
   <tr>
    <td>
     Centered Content
    </td>
   </tr>
  </table>
 </body>
</html>

It's as simple as this: without the red code, the table will do what you want it to – with it the table will not. So it comes down to whether valid XHTML means more to you, or whether the appropriate functionality means more to you. In this day and age, it's a toss-up for me and a hard decision to make, even though my older self would have never even flinched at the thought of using a dirty workaround. Back then I'd consider using the <marquee> tag though, so let's keep things in perspective.

Comments

Marc on August 23, 2004 at 2:05 PM:

That is excatly the dicision i have to make right now, for my upcomming update of my site to its new design, and my opion is that they should make it part of the standard just as the width attribute. They kinda go together logically as a pair i think, and if i cant find an elegant solution i will properly remove the document type and not obey the standard although it goes against my belief og good design.

Permalink

Jesse on October 03, 2004 at 1:43 AM:

The height attribute was depricated in HTML 4.01 I think (not 100% sure). In any case, it is giving me much pain right now. I've managed to be able to soften the blow a bit of not being able to use height in XHTML by defining the height in CSS. Unfortunately, CSS does not allow height to be a percentage. This stimulates, in me, many violent thoughts directed at the team who developed CSS for getting my hopes up.

I have a left menu that I want a roll over component for, but the thing is, the left menu height is governed by the height of the right side of the webpage (where all of the content is) so, I need a percentage to ensure that regardless of the page selected (PHP includes), the roll over will fit right.

Bah, solution is evading me. I go.

Permalink

John wood on October 30, 2004 at 5:33 AM:

Nope that's all wrong. i have a solution. Using your html above simply insert the following code between your head tags.

<style type='text/css'>
html, body {height: 100%;}
table {height: 100%; width: 100%; background-color: #CCC;}
</style>

and remove the styles from the table tag.

This should now validate as xhtml strict, and center your content just like the good old days of html 4

Permalink

Bernie Zimmermann on November 06, 2004 at 4:04 PM:

John, you're right on with that snippet. You (and anyone else visiting this particular blog entry) should see my updated entry for a full example of the standards-compliant XHTML source.

Permalink

Marc on June 02, 2005 at 5:26 AM:

Nice John, thanks.

Permalink

Rimian on June 19, 2005 at 10:48 PM:

it doesn't make any difference if you place the style inline or between style tags.

the solution john has there doesn't work on linux or firefox.

Permalink

Semaj on February 03, 2006 at 6:00 AM:

Thanks john - I'll remember that when I need to use it.
Which idiot decided that it would be a good idea to use "html, body" I dread to think ...

Permalink

Roger on March 01, 2006 at 8:29 PM:

That technique works in almost all browsers. The exception is Internet Explorer on the Mac.

Typical!

Permalink

Olivia on March 01, 2006 at 8:34 PM:

The only drawback with:

<style type='text/css'>
html, body {height: 100%;}
table {height: 100%; width: 100%; background-color: #CCC;}
</style>

is that it will apply it to all tables in the page. Better to create an id element and just apply that to the table you want to control.

Permalink

Bernie Zimmermann on March 01, 2006 at 11:00 PM:

Thanks for pointing that out, Olivia. You are right on.

Permalink

KEDO DesignArt on April 13, 2006 at 12:52 AM:

In my opinion the magic is in the line where you give the html & body tags the height of 100%.

Since the height-attribute of the tables refers to the parent tag , the body and html tags have to have the height of browser display area assigned (e.g.100%) to stretch the table in height.

But I appreciate that fix, since I was searching for a fix for months now. Didn't ever expect it was so simple.

Permalink

Andrew on June 21, 2006 at 2:57 PM:

<style type='text/css'>
html, body {height: 100%;}
table {height: 100%; width: 100%; background-color: #CCC;}
</style>

Removed the table definition (or this this case the 100% attribute to an ID instead as it's unique and won't affect other (horrid) tables and it works without... however, only in IE 6... not Mozilla (and I presume hence Firefox). Horrid to have to sacrifice such a large design feature to certain browsers. I am coding this design according to clients design, personally I like to factor into design a defnitive 'end' to the page at bottom, rather than this issue of scaling to fill up screen space.

Permalink

Gabriel Medina on July 13, 2006 at 8:47 AM:

Hi...

I know that relying on javascript for this shouldn't be relied on, but diving on a zillion lines of code (ZenCart), it's just a matter of guess, try and fail procedure.

After almost 3 days trying to get this to work, I used this javascript snippet, to make a table (not a top level one, but a very very deep-leveled one) go onto 100% height. Ugly, yes, but works.

I added this to the HEAD section



then assigned id's to both the container table/td/div/etc=PageBody, and to my target 100%-Should-Be-Table I assigned the PageTable ID.

In the body tag, I added the following:

onLoad="javascript:ResetHeight();"

Hope this helps somebody else on a deadline like I was.

Gabriel Medina

Permalink

eo on July 17, 2006 at 8:14 AM:

using this technique how does one get the contents of the table to the top rather than it being centered vertically?

Permalink

Lars on July 26, 2006 at 12:20 AM:

The thing with the html/body assignment was known to me already. But it does definitely not work in Firefox.

So, what is all the talk useful for, about not using tables for layout when divs for layout don't work? What is all the talk useful for, about using XHTML when neither div nor tables work? The better the standard, the more a pain in the a** webdesign becomes.

Conclusion: I do the webdesign "function-based". Means... it simply has to for the customer work. None of my customers pays me hundreds and hundreds of hours figuring out how to make his favored design accessible, compatible with a million different browsers, standards conformant, and so on. They want results... fast.

Permalink

Woody on September 01, 2006 at 5:57 AM:

Lovely!
Wonderful - I can sit back and relax after that wonderful fix!
I always thought 'body' was the parent of all parents when it came to visible elements!

what awonderful string od characters . . .

html {height: 100%;}

Woody :¬)

Permalink

MJS on September 03, 2006 at 5:42 AM:

I found solution on this site: http://www.apptools.com/examples/tableheight.php

Very helpfull

Permalink

MJS on September 03, 2006 at 6:44 AM:

And what about TD's?

If I want that one of td wil be 20px height, third, will be 50px height, and middle row will fill everythink else.. but it doesn happen..

<table border="0" cellpadding="0" style="height: 100%; width: 100%">
<tr>
<td style="text-align: center; height: 30px;" valign="top" bgcolor=red>firs</td>
</tr>
<tr >
<td style="text-align: center; height: 100%;" valign="top" bgcolor=blue>second</td>
</tr>
<tr>
<td style="text-align: center; height: 30px;" bgcolor=green>third</td>
</tr>
</table>


Somebody can help?

Permalink

Jarle on October 26, 2006 at 11:22 PM:

Here is the answer MJS. You must assign all parent tags (including html and body) a 100% height. Kind of stupid "bug" in xhtml.
(its a bug in my opinion, but there is possibly a logical explanation for this)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
html, body {height: 100%; margin: 0; padding: 0; }
</style>
</head>
<body>
<table border="0" cellpadding="0" style="height: 100%; width: 100%">
<tr>
<td style="text-align: center; height: 30px;" valign="top" bgcolor=red>firs</td>
</tr>
<tr >
<td style="text-align: center; height: 100%;" valign="top" bgcolor=blue>second</td>
</tr>
<tr>
<td style="text-align: center; height: 30px;" bgcolor=green>third</td>
</tr>
</table>
</body>
</html>

You should also clean up your html and put style attributes inside the style tag, or better in a stylesheet. F.example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
html, body {height: 100%; margin: 0; padding: 0; }
#layout { width: 100%; height: 100%; border: 0; }
#top { text-align: center; height: 30px; vertical-align:top; background-color:Red }
#content { text-align: center; height: auto; vertical-align:top; background-color:Blue }
#bottom { text-align: center; height: 30px; background-color:Green }
</style>
</head>
<body>
<table id="layout" cellpadding="0" cellspacing="0">
<tr>
<td id="top">first</td>
</tr>
<tr >
<td id="content">second</td>
</tr>
<tr>
<td id="bottom">third</td>
</tr>
</table>
</body>
</html>

Permalink

Witchman on January 28, 2007 at 1:34 AM:

The following XHTML code does not strech table 100% according browser dimensions. It's always more than 100% and vertical scrooler is activated. Would somebody please tell me where is the trick to strech the table 100%?
Content in table is not more than 400px and my resolution is 1152x864.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<style type='text/css'>
html, body {height: 100%; margin:0; padding:0;}
table {height: 100%;}
</style>

</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" width="770px">
<tr><td colspan="10" style="background-image:url(images/r2_c2.jpg); height:25px"></td></tr>
<tr>
<td style="background-image:url(images/r3_c2.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c3.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c4.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c5.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c6.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c7.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c8.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c9.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c10.jpg); height:118px;"></td>
<td style="background-image:url(images/r3_c11.jpg); height:118px;"></td>
</tr>
<tr>
<td style="background-image:url(images/r4_c2.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c3.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c4.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c5.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c6.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c7.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c8.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c9.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c10.jpg); height:7px;"></td>
<td style="background-image:url(images/r4_c11.jpg); height:7px;"></td>
</tr>
<tr>
<td style="background-image:url(images/r5_c2.jpg); height:40px;"></td>
<td style="background-image:url(images/r5_c3.jpg); height:40px;"></td>
<td colspan="2" rowspan="2"></td>
<td style="background-image:url(images/r5_c6.jpg); height:40px;"></td>
<td rowspan="2"></td>
<td style="background-image:url(images/r5_c8.jpg); height:40px;"></td>
<td style="background-image:url(images/r5_c9.jpg); height:40px;"></td>
<td style="background-image:url(images/r5_c10.jpg); height:40px;"></td>
<td style="background-image:url(images/r5_c11.jpg); height:40px;"></td>
</tr>
<tr>
<td style="background-image:url(images/r6_c2.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c3.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c6.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c8.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c9.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c10.jpg); height:318px;"></td>
<td style="background-image:url(images/r6_c11.jpg); height:318px;"></td>
</tr>
<tr>
<td style="background-image:url(images/r7_c2.jpg); height:14px;"><img src="images/px.gif" width="49px" height="1px" /></td>
<td style="background-image:url(images/r7_c3.jpg); height:14px;"><img src="images/px.gif" width="12px" height="1px" /></td>
<td style="background-image:url(images/r7_c4.jpg); height:14px;"><img src="images/px.gif" width="115px" height="1px" /></td>
<td style="background-image:url(images/r7_c5.jpg); height:14px;"><img src="images/px.gif" width="215px" height="1px" /></td>
<td style="background-image:url(images/r7_c6.jpg); height:14px;"><img src="images/px.gif" width="8px" height="1px" /></td>
<td style="background-image:url(images/r7_c7.jpg); height:14px;"><img src="images/px.gif" width="128px" height="1px" /></td>
<td style="background-image:url(images/r7_c8.jpg); height:14px;"><img src="images/px.gif" width="40px" height="1px" /></td>
<td style="background-image:url(images/r7_c9.jpg); height:14px;"><img src="images/px.gif" width="142px" height="1px" /></td>
<td style="background-image:url(images/r7_c10.jpg); height:14px;"><img src="images/px.gif" width="14px" height="1px" /></td>
<td style="background-image:url(images/r7_c11.jpg); height:14px;"><img src="images/px.gif" width="47px" height="1px" /></td>
</tr>
<tr>
<td colspan="10" style="background-image:url(images/r8_c2.jpg); height:120px;"></td>
</tr>
<tr>
<td colspan="10" style="background-image:url(images/r9_c2.jpg); height:100%;"></td>
</tr>
<tr>
<td colspan="10" style="background-image:url(images/r10_c2.jpg); height:8px;"></td>
</tr>
</table>

Permalink

Bernie Zimmermann on January 28, 2007 at 10:24 AM:

Witchman, be careful about all those explicit heights you're defining in the table cells. I see 118px here, and 318px there...eventually those are gonna add up. Also, I see that the table cell with r9_c2.jpg in it is also set to 100% height. That means it's going to stretch that cell to 100% the browser height in addition to the other heights you've defined in other cells. If you take that out and either go with an explicit height (like you have in other places) or just leave the height out altogether, you may see the result you're looking for. Good luck.

Permalink

Martin on January 31, 2007 at 10:36 PM:

I guess, thousands and thousands of developers spending thousands and thousands of hours to figure that out. I did not complain; one only becomes accustomed to the pain.

Permalink

Maurice Downes on February 08, 2007 at 7:06 AM:

If you are using a doctype of XHTML 1.0 Strict and want to get percentages work without using the tables mentioned above in forefox make sure you set the body,html and importantly the form tag to a height of 100%.

It is not enough to set the body and html as when not using a doctype
i.e
body, html ,form{ height:100%; }

Permalink

Dennis on February 08, 2007 at 9:04 AM:

Above solution works fine for me when I use Firefox.

But it doesn't work with IE 6.0? Is there any fix to obtain 100% height as mentioned above using IE 6.0

Thanks,
Dennis...

Permalink

JB4 on April 02, 2007 at 2:11 AM:

this is a great fix for tables, but I need one for divs.

Permalink

bobotron on July 27, 2007 at 10:11 PM:

Works for me in Firefox on a Mac. Thanks for the tip.

Permalink

Michael Fasani on September 06, 2007 at 6:15 PM:

<style type='text/css'>
html, body {
  height: 99%;
  //This is the IE FIX, BUT YOU WONT PASS A CSS VALIDATION TEST
  #height: 96%;
  background-color: #000;
}
#mytable {
  height: 100%;
  width: 100%;
  background-color: #000;
  text-align: center;
  color: white;
  font-family: verdana;
}
a {
  color: red;
}
</style>


http://code.michaelfasani.com/pagecenter_xhtml.htm

Permalink

Manual Niche Relevant backlinks on September 08, 2016 at 4:12 AM:

Pleasant post. I was checking continually this online journal and I am inspired! To a great degree accommodating data uniquely the last part I watch over such information a considerable measure. I was looking for this specific data for quite a while. Much obliged to you and good fortunes.

Permalink

xbox on October 22, 2016 at 2:43 AM:

It was a decent post in fact. I completely delighted in understanding it in my lunch time. Will unquestionably come and visit this blog all the more regularly. A debt of gratitude is in order for sharing. best of chaturbate xbox live membership

Permalink

netflix on November 07, 2016 at 1:59 AM:

This is an awesome motivating article.I am practically satisfied with your great work.You put truly extremely supportive data. Keep it up. Continue blogging. Hoping to perusing your next post. minecraft free download free netflix account

Permalink

dyson v8 absolute vs v6 on January 10, 2017 at 1:25 AM:

You we are have lengthy run to come in the course of a lot of techniques right after looking with from your details and specifics http://lfconferences.com/dyson-v8-absolute/

Permalink

best meat grinder for deer on January 10, 2017 at 1:36 AM:

Thank you because you have been willing to share information with us. we will always appreciate all you have done here because I know you are very concerned with our. http://terrabellica.com/get-best-choice-meat-grinder-for-small-scale-projects/

Permalink

online reputation management services on January 10, 2017 at 1:39 AM:

I think it could be more general if you get a football sports activity http://regionalbar.com/different-ways-to-select-an-online-credibility-management-service/

Permalink

Post Comments

If you feel like commenting on the above item, use the form below. Your email address will be used for personal contact reasons only, and will not be shown on this website.

Name:

Email Address:

Website:

Comments:

Check this box if you hate spam.