views:

497

answers:

4

I have a table as follow:

<table>
<tr>
<td>
*PROBLEMATIC CELL*
</td>
<td rowspan="2">
</td>
<td rowspan="3">
</td>
</tr>

<tr>
<td>
</td>
</tr>

<tr>
<td colspan="2">
</td>
</tr>
</table>

The first cell of the first row, has a padding at the bottom. Well it's not really padding but it looks like padding and using firebug I can not find what the space there actually is.

I think what is happening is that, firefox automatically adjusts the bottom padding of the first td in the first tr with the padding top of the first and only td of the second tr.

p.s. works perfectly fine in Chrome.

Basically what I am trying to achieve is for the height of the first td in the first tr, to be only as tall as required but not taller so that the content of that cell ends on the same place as where the td ends without any space between them.

The website URL is: http://mmamail.com/

It seems to have something to do with the padding-top placed on the first TD of the SECOND TR. The weird thing is that it works nicely on chrome.

+1  A: 

Controlling table cell padding with css can be tricky. Try adding these two css rules:

table { border-spacing: 0; }
table td { padding: 0; }

Unfortunately, the border-spacing rule isn't supported by all browser, so you may have to add cellpadding="0" and cellspacing="0" as an attribute to the table.

Xavi
You should not need to include cellpadding/cellspacing for value `0` in this century. The IE6-7 problem with `border-spacing` not working can be worked around with the style `border-collapse: collapse`.
bobince
A: 

I've tried with the follow HTML code which is merely a more complete version of your code fragment. However, I'm seeing no padding as you have described. So my best guess is that it's caused by some other CSS rules you defined elsewhere.

<!doctype html>
<html>
<head>
</head>
<body>
<table>
<tr>
<td>
*PROBLEMATIC CELL*
</td>
<td rowspan="2">
&nbsp;
</td>
<td rowspan="3">
&nbsp;
</td>
</tr>

<tr>
<td>
&nbsp;
</td>
</tr>

<tr>
<td colspan="2">
&nbsp;
</td>
</tr>
</table>
</body>
</html>
shinkou
the website is URL is http://mmamail.com/
John
The problem has nothing to do with padding. Instead, it was the fieldset's height which does not max out to the table cell's.
shinkou
+1  A: 

if you are referring to the space in between the "Monthly poll" and "Monthly Magazine" boxes, it is not caused by padding...

What's happening is the td containing the flash video is too tall, and because it has a rowspan of 2, the two tds on the left are being adjusted to the height of the tallest td (aka the video box)

One solution is to add another tr below the first 2 rows,
let it have an empty td,
change the rowspan of the video box to 3

And then the redundant space you see in between the first 2 boxes will be transfered to the empty td you have just created.

OR

I would suggest you bite the bullet and start using CSS rather than tables for layout, purely because:

  1. We are in the second decade of the 21st century
  2. It is much more flexible to use CSS
  3. It will be much easier for you change the look of the site in th future, without touching the markup.
  4. It will be much better for search engines to index your site content
  5. Assistive software such as screen readers can see your content in the order they are supposed to be seen
  6. You will be one happy developer in the end
pǝlɐɥʞ
+2  A: 

You've presented the browser with an incomplete layout problem. You have a three-by-three grid, none of whose columns or rows have fixed sizes. So the issue is you end up with a taller first row than you intended, as the browser tries to allocate ‘spare’ height caused by the rowspan in the second column amongst the cells in the first column.

There isn't a standardised algorithm for this; browsers do different things, often including unpleasant things like looking at the raw number of bytes of markup in each cell. You don't want to rely on this behaviour. It also slows page rendering down and can give really weird, page-distorting effects when there's a very small or large amount of content. If you need to use tables for layout, make sure to use table-layout: fixed with explicit widths for the fixed-size columns, and set explicit heights for cells when there are rowspans, to avoid ambiguity.

But a proliferation of rowspan/colspan is often a hint you should be looking at a different form of layout. This example is very much easier to acheive using CSS instead. eg.:

<div id="ads">
    <script type="text/javascript">//...google stuff...</script>
    ...
</div>
<div id="content">
    <div id="video"><fieldset>
        <legend>...</legend>
        <object ...>
    </fieldset></div>
    <form id="poll" method="post" action="..."><fieldset>
        <legend>...</legend>
        ...options...
    </fieldset></form>
    <form id="subscribe" method="post" action="..."><fieldset>
        <legend>...</legend>
        ...fields...
    </fieldset></form>
    <div id="about">
        ...
    </div>
</div>

with styles something like:

#ads { position: absolute; right: 0; width: 160px; }
#content { margin-right: 160px; }
#video { float: right; width: 440px; }
#poll, #subscribe { margin: 0 440px 0 0; }
#about { clear: right; }

I'd also advise you to move the JavaScript logic out from the inline event handler attributes you currently have to separate JavaScript blocks (either embedded <script> blocks or linked external scripts). Especially for the multi-line event handlers: quite apart from the horrible maintainability of mixing scripts into markup, in HTML/XML newlines in attributes are not preserved. That means your newlines in JS code are converted into spaces, so if you miss a single semicolon your script will break or behave oddly (where usually in a script block or external script, the auto-newline-semicolon-fallback would save you).

ie.

onsubmit="
  var inputs = this.getElementsByTagName('input');
  var checkedValue;
  for(var i = 0; i < inputs.length; i++)
  {
        if(inputs[i].getAttribute('type') == 'radio' && inputs[i].checked)
        {
            checkedValue = inputs[i].value;
        }
  }
  /*makeAjaxPostRequest('/poll/ajax-vote.php', 'vote='+checkedValue, processAjaxResponse);*/
  makeAjaxGetRequest('/poll/ajax-vote.php?vote='+checkedValue, processAjaxResponse);
  return false;"

instead:

<form id="pollForm" method="post" action="/poll/form-vote.php>
    ...
</form>
<script type="text/javascript">
    document.getElementById('pollForm').onsubmit= function() {
        var checkedValue= getRadioValue(this.elements.vote);
        makeAjaxPostRequest('/poll/ajax-vote.php', 'vote='+encodeURIComponent(checkedValue), processAjaxResponse);
        return false;
    };

    function getRadioValue(fields) {
        for (var i= fields.length; i-->0;)
            if (fields[i].checked) 
                return fields.value;
        return '';
    };
</script>

Always allow only POST requests for active forms that do something positive. Always use encodeURIComponent when creating query strings. Don't use getAttribute as it doesn't work right in IE; use direct DOM Level 1 HTML properties instead, eg. input.type.

bobince