td class, very confused, larger number makes width smaller? - html

This isn't really a problem as such, but I would like to know what's going on so I can understand it. I'm currently coding a new website which has required me to use a single table in the footer of the design. (I don't often use them, but this table just makes life a lot easier for this project.)
I am using a CSS class for the tables td with the only element being width:%; but for some reason I just can't understand, increasing the % from 10% to 20% actually makes the td's smaller in width. totally backwards.
I'm really stumped by this one, can anyone explain this?
HTML:
<div class="footertable">
<table border="2">
<tbody>
<tr>
<td valign="top" class="footer">
<div class="footerheading">SHOPPING</div>
</td>
<td valign="top" class="footer">
<div class="footerheading">CUSTOMER SERVICE</div>
</td>
<td valign="top" class="footer">
<div class="footerheading">PAYMENT OPTIONS</div>
</td>
<td valign="top" class="footer">
<div class="footerheading">SOCIAL</div>
</td>
<td valign="top" class="footer">
<div class="footerheading">ORDER</div>
</td>
</tr>
</tbody>
</table>
</div>​
CSS:
.footertable { margin:auto; max-width:1080px;}
td.footer {width:10%;}​
Notes:
The strange behavior happens for percentages lower than 24: from 15 to 23 the total width decreases, and from 23 to 24 it suddenly expands. For percentages higher than 24, you have normal behavior.
It doen't matter if you specify max-width or just width for the table
The problem is reproduceable in chrome, firefox, opera and IE9
jsFiddle here: http://jsfiddle.net/BPygA/

Table layout has its fans and haters, but one thing is for sure, it's an advanced maneuver. It's like a combination of forces, some weaker, some stronger, that ultimately determine your column widths. And there's a lot of input variables:
table-layout:fixed or not
Table has a specific width (in pixels or percent or not at all)
Do all columns have widths?
Is there a colgroup element in the table?
How much space is available for the table?
Do any cells have non-breakable content?
It's kind of a nightmare for the inexperienced.
In your particular situation you table has no specific width, meaning it'll be the sum of the widths of the columns. But the columns are sized in percentages, which would be percentages of the total table width. You can see this is a chicken-and-egg problem.
Also using percentages that don't add up to 100% is kind of undefined.
I'd take a step back and think about what you're trying to achieve exactly.

I can see the behavior switching between 10 and 20% width on the table cells.
Adding a width to the table itself (not the containing DIV) changes the behavior:
http://jsfiddle.net/BPygA/2/
Without a width on the table itself, the browser is making a best guess on how to display the cells based on their content. I'm not sure why it chooses a smaller width when the percentage is set to a larger number, but it's a non-deterministic calculation so the browser is free to do what it wants (see spec below).
In other words, without a width on the table you are telling the browser that each cell is 10% of a variable value that it is free to determine.
Another consideration may be that the table has 5 cells. Setting each one to 10% results in a total width of only 50%. Once again, the browser has to guess about the total width, but also has to determine what to do with the remaining 50% that is not accounted for.
As #Jacob pointed out the W3 defines recommendations (but only recommendations) to guide user agents in how to render tables.
This algorithm reflects the behavior of several popular HTML user
agents at the writing of this specification. UAs are not required to
implement this algorithm to determine the table layout in the case
that 'table-layout' is 'auto'; they can use any other algorithm even
if it results in different behavior.
The UA should try to use the requested percentage, but it may not always be possible.
A percentage value for a column width is relative to the table width.
If the table has 'width: auto', a percentage represents a constraint
on the column's width, which a UA should try to satisfy. (Obviously,
this is not always possible: if the column's width is '110%', the
constraint cannot be satisfied.)
http://w3.org/TR/CSS2/tables.html#propdef-table-layout
I would be curious as to a better explanation.

Related

Resize an image to fit into a table using eMail-compatible HTML

My HTML knowledge is 20 years old and my coding skills are limited to BASIC on the C64 and Scratch, so sorry about the basic question. :)
I'd like to create an email signature:
with a logo on the left and some text on the right
where the height of the logo is exactly the height of the text block
How I've been trying to accomplish this
I've used a table for the layout because my knowledge of CSS is too minimal I understand CSS isn't widely supported across various eMail clients.
The challenge is that the text part is rendered slightly differently on different devices, and I want the image to resize to perfectly fit the height of the text. I.e. I want the height of the table/row be defined by the size/height of the text, and the image to be resized accordingly (keeping the aspect ratio).
I guess the max-height tag might solve this, but it doesn't seem to be supported by GMail on the Web?
Thank you!
Pixel perfection is not achievable these days, due to the sheer number of devices, operating systems, fonts, email clients, and other variables--and nor is it desirable. It's not desirable because each environment has different features and screen sizes that mean that you want to optimise to each different environment, to get the best out of all.
Having said that, your requirements are fairly easy to achieve, within about 95% of the time.
To control text-size, you need to use font-size and line-height. Control default margins, paddings, cellspacing, cellpadding, borders for all elements (there are defaults that are different across different email clients).
If you use a websafe font like Arial, the rendering should be similar across almost every device & OS.
So if your logo is the height you want the text, e.g. 30px, then you might have the text like so:
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td>
<p style="margin:0;font-size:13px;line-height:15px;">Text</p>
<p style="margin:0;font-size:13px;line-height:15px;">More text</p>
</td>
</tr>
</table>
If you need space between the lines you should be able to do a 2px font-size and line-height. If you need the bottom one to be flush with the bottom, the line-height should be the same as the font-size.
Include the actual code if you want something more specific.

Collapsing TD width HTML

I have HTML such as:
<html>
<body>
<table>
<tr>
<td>
<img style="width: 300px; height: 300px;"></img>
<img style="width: 300px; height: 300px;"></img>
</td>
<td>
hello world
</td>
</tr>
</table>
</body>
</html>
When the page/window is decreased in width, the second image is pushed below the first image.
My question is: Why doesn't the TD cell shrink to to 300 width with the images are stacked? It seems to stay unnessarily large - causing an ugly gap to be between the images and the text of the next cell. Is there any way to force the cell to either 600 or 300 in width depending on how much room there is?
To understand the behavior of the table layout in your example, you need to review
the table width algorithms used by CSS to visually lay out the table:
http://www.w3.org/TR/CSS21/tables.html#auto-table-layout
The table width algorithm looks at the content in the cells making up each column and
determines a mininum and maximum value for the column width. The algorithm then tries
to allocate enough space to each column taking into account any specified column width
values, specified table width and so on.
In this case, the browser tries to allocate 600px (plus a bit for the white space between the two images) and some width for the text in the second column.
If the window is wide enough, all the content fits in a single line in each table cell.
However, as the window width shrinks, the algorithm will shrink each column width (the details here will vary among browsers since the CSS specification does not prescribe a detail algorithm).
The algorithm appears to be shrink each column proportionately. For the first column, this forces the images to wrap with the gap to the right. In this case, the algorithm
does not do a second pass to redistribute the excess space. The algorithm works pretty
well if you are wrapping words. However, when the content is a 300px wide image, the
result is big (ugly) gaps.
So, the table is working as it should, but the results are not ideal.
The table width algorithms try to be efficient by minimizing the number of times it
loops through the content to determine widths and heights. In this case, a more
sophisticated algorithm would be needed to get more pleasant results, but it would also
be a bit subjective.
Note: To fix the layout problem, you would have to build a JavaScript function to do the
math to get the column width to work out. I think this could be quite difficult to make
it foolproof.
You could add style='white-space: nowrap;' to thetd element to prevent the wrapping.
http://jsfiddle.net/mpWn3/
Take the widths away from your image tag. Add them in css for a start...
table img {max-width:100%;}
but yes - you would be better off with making it responsive. This is possible with tables. Read this article: http://css-tricks.com/responsive-data-tables/
My short answer would be to stop using tables and dive into a responsive div layout.
<div class='con'>
<div class='picture_con'>
<img src='img1.jpg'></img>
<img src='img2.jpg'></img>
</div>
<div class='text_con'>
Your text here
</div>
</div>
And then make it work with css
.con {
width:100%;
}
.con .picture_con {
display:inline-block;
}
.con .picture_con img {
width:300px;
display:inline;
}
.con .text_con {
display:inline;
}
This is all very well for big screens but now we need to deal with smaller screens. To do this we use #media css queries
#media(max-width:600px) {
.con .picture_con {
width:300px;
}
.con .picture_con img {
display:block;
}
}
Edit: If tables are really necessary
Here is an example of a responsive table design that does the job aswell
http://jsfiddle.net/4VHd5/

What does CSS width attribute mean in HTML table when layout is automatic?

If I specify a width for a <th> element in a table, what does that mean in terms of the wider table if table-layout is not specified and defaults to automatic? Does such a width specify a minimum width for the entire column? If so, where is this specified - I cannot find anything in the HTML/CSS specs that says width is interpreted this way, yet Firefox and IE both seem to interpret the width this way.
To put this in context, imagine a table of numeric data (e.g. production volumes) for the days of the week. The week days are the column headings. I want to cope with two conditions:
There is no data for a particular day, but I don't want the width of the column to collapse to some ugly minimum. Rather, I want to set that minimum.
When there are large numbers in columns, I want the width of the column to automatically expand to show the number in full.
When I specify a bunch of column widths as follows...
<tr>
<th style="width:3em">Sun</th>
<th style="width:3em">Mon</th>
<th style="width:3em">Tue</th>
...etc
</tr>
... I achieve the result I'm looking for. However, can I rely on this?
Yes, you can rely on this; it’s in the CSS spec, and browsers play by the book here. For table cells, the width property sets the minimum width used in the calculation of column width.
The spec is somewhat messy here, because the description of the width property does not say this or even refer to the description (as far as I can see), but this is described in section 17.5.2.2 Automatic table layout. Item 1 in the first numbered list there says: “Calculate the minimum content width (MCW) of each cell: the formatted content may span any number of lines but may not overflow the cell box. If the specified 'width' (W) of the cell is greater than MCW, W is the minimum cell width. A value of 'auto' means that MCW is the minimum cell width.”
To set the minimum allowed width and let the fields expand wider if need be, use something like this
th {
width: auto; /* This is default, but shown here for clarity */
min-width: 100px; /* or whatever size need be */
}

Chrome "cm" issue

I have noticed a problem with size of elements in Chrome browser.
I have written a simple code:
<html>
<body>
<table border="1px">
<tbody>
<tr>
<td>
<span style="display: inline-block; width: 5cm">TEXT</span>
<span style="display: inline-block; width: 5cm">TEXT</span>
<span style="display: inline-block; width: 5cm">TEXT</span>
<span style="display: inline-block; width: 5cm">TEXT</span>
</td>
</tr>
</tbody>
</table>
</body>
</html>
I expect to have 4 spans repeated vertically, 5cm each. It works on IE, Firefox, etc.:
IE - Works fine
But Chrome suffers the following problem:
Chrome - Doesn't work
In IE, spans have 189px width each and td has 772px.
In Chrome, spans have 189px width each and td has 771px.
Is this some kind of Chrome issue? Why my td element doesn't fit its content? It's important for me to stay with those span elements (I cannot replace them with i.e. div) and to set width in cm. The issue still exists when I remove table border.
CSS cm units are unreliable if you want a fixed number of pixels. They're also not likely to actually measure 5cm on the screen. The cm unit is intended mainly for printing styles. Yes, it can be used on screen, but don't expect any accuracy from it.
The fact that a 5cm box is rendered as 189 pixels tells us that a cm is not a whole number of pixels. This alone should be enough to tell you that you're unlikely to get accurate pixel-level cross-browser rendering using cm units.
It's just not going to happen. If you want pixel-perfect accuracy, use px units.
You say in the question that you can't change the units. You really should reconsider that if possible, because it's only going to keep giving you these issues.
If you really can't change them, then the one way I can think of to resolve your issue without changing the units is to give the <td> element a white-space:nowrap style. This should force all the spans onto the same line regardless of whether the browser thinks they should be there or not. It should do the trick for you. But it doesn't resolve the underlying problem, and it will likely come back in other ways if you keep using cm units on the screen.
As for what exactly is causing the glitch in the first place, I would guess that Chrome is handling the floating point pixel values slightly differently, and that there is a rounding error when it adds the pixel widths of the spans to work out how wide to make the <td>. If this is the case, then it sounds like a bug in Chrome, and you could report it to them, but given everything I've said above, I can't see them making it a high priority issue.

Impact of providing exact sizing for the page elements as opposed to the browser resizing tables

We have a application of huge amount of data which is to be converted into HTML tables via Velocity templates.Question1: One area to be focused is the impact of providing exact sizing for the page elements as opposed to the browser resizing tables height and width
want to understand how much time is spent by the browser doing that
as opposed to creating a page that exactly sized for 1024 x 768, for example
Question2 :The page actually loading is a chart with lots of graphs and cells with in a grid which depicts 15 min interval of day which is micro version of the data. So the grid cells were constructed to put '*' value inside the grid. Is there any better way of doing this.
Question 1:
If your document is data intensive as you portray it to be, it would be beneficial to allow for the flow [auto-resizing] of your display markup [layers/tables] to take into consideration those with larger display areas [Above: 1024x768]. You might want to consider defining the smallest possible width/height through layers+css or placeholder images to keep from over-wrapping by those with display areas that are less than the intended 1024x768.
Example:
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="25%"><div style="width:200px;height:1px;overflow:hidden;clip:rect(0px 200px 1px 0px);" title="Column Space Saver"></div></td>
<td width="75%"><div style="width:400px;height:1px;overflow:hidden;clip:rect(0px 400px 1px 0px);" title="Body Space Saver"></div></td>
</tr>
<tr>
<td width="25%" valign="top" style="background:#EB0000">Will be 200px or 25%, whichever is greater, and always adhere to those parameters even if my screen size is smaller than combined 600px [hence column is 200px body is 400px].</td>
<td width="75%" valign="top">Will be 400px or 75%, whichever is greater, and always adhere to those parameters even if my screen size is smaller than combined 600px [hence column is 200px body is 400px].</td>
</tr>
</table>