Force table column widths to always be fixed regardless of contents - html

I have an html table with table-layout: fixed and a td with a set width. The column still expands to hold the contents of text that doesn't contain a space. Is there a way to fix this other than wrapping the contents of each td in a div?
Example: http://jsfiddle.net/6p9K3/29/
<table>
<tbody>
<tr>
<td style="width: 50px;">Test</td>
<td>Testing 1123455</td>
</tr><tr>
<td style="width: 50px;">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</td>
<td>B</td>
</tr>
</tbody>
</table>
table
{
table-layout: fixed;
}
td
{
border: 1px solid green;
overflow: hidden;
}
In the example, you can see that the column with AAAAAAAAAAAA... expands despite being explicitly set to 50px wide.

Specify the width of the table:
table
{
table-layout: fixed;
width: 100px;
}
See jsFiddle

Try looking into the following CSS:
word-wrap:break-word;
Web browsers should not break-up "words" by default so what you are experiencing is normal behaviour of a browser. However you can override this with the word-wrap CSS directive.
You would need to set a width on the overall table then a width on the columns. "width:100%;" should also be OK depending on your requirements.
Using word-wrap may not be what you want however it is useful for showing all of the data without deforming the layout.

Make the table rock solid BEFORE the css. Figure your width of the table, then use a 'controlling' row whereby each td has an explicit width, all of which add up to the width in the table tag.
Having to do hundreds html emails to work everywhere, using the correct HTML first, then styling w/css will work around many issues in all IE's, webkit's and mozillas.
so:
<table width="300" cellspacing="0" cellpadding="0">
<tr>
<td width="50"></td>
<td width="100"></td>
<td width="150"></td>
</tr>
<tr>
<td>your stuff</td>
<td>your stuff</td>
<td>your stuff</td>
</tr>
</table>
Will keep a table at 300px wide. Watch images that are larger than the width by extremes

You can add a div to the td, then style that. It should work as you expected.
<td><div>AAAAAAAAAAAAAAAAAAA</div></td>
Then the css.
td div { width: 50px; overflow: hidden; }

You can also use percentages, and/or specify in the column headers:
<table width="300">
<tr>
<th width="20%">Column 1</th>
<th width="20%">Column 2</th>
<th width="20%">Column 3</th>
<th width="20%">Column 4</th>
<th width="20%">Column 5</th>
</tr>
<tr>
<!--- row data -->
</tr>
</table>
The bonus with percentages is lower code maintenance: you can change your table width without having to re-specify the column widths.
Caveat: It is my understanding that table width specified in pixels isn't supported in HTML 5; you need to use CSS instead.

You can also work with "overflow: hidden" or "overflow-x: hidden" (for just the width). This requires a defined width (and/or height?) and maybe a "display: block" as well.
"Overflow:Hidden" hides the whole content, which does not fit into the defined box.
Example:
http://jsfiddle.net/NAJvp/
HTML:
<table border="1">
<tr>
<td><div>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div></td>
<td>bbb</td>
<td>cccc</td>
</tr>
</table>
CSS:
td div { width: 100px; overflow-y: hidden; }
EDIT: Shame on me, I've seen, you already use "overflow". I guess it doesn't work, because you don't set "display: block" to your element ...

I would try setting it to:
max-width: 50px;

This works for me
td::after {
content: '';
display: block;
width: 30px;
}

Related

Understanding tables in html / css

I am trying to understand tables in html / css, but I don't understand anything of it. I have a lot of questions about it, but i will start with the first one.
Here:
http://www.w3schools.com/cssref/pr_tab_table-layout.asp
they are saying in case of "table-layout: fixed;":
"The horizontal layout only depends on the table's width and the width of the columns, not the contents of the cells"
Okay....so it does not depend on the contents of the cell? Let's test it:
I made a table with table-layout: fixed and I gave one column a width of 200px (inline css in the html):
.myTable {
border: 1px solid black;
}
.myTable th,
.myTable td {
border: 1px solid black;
}
<table class="myTable" style="width: auto; table-layout: fixed;">
<tr>
<th>Column A</th>
<th style="width: 200px">Column B</th>
</tr>
<tr>
<td>A1</td>
<td>B1: This is a sentence with a very long word in it, to check what the behavior is of the table in a case like that. Will long words be broken and wrap onto the next line? Thisisaverylongwordyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitis</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>
Why that column with width 200px is now bigger than 200px? If the width would not depend on the contents of the cell then I would expect a width of 200px. In this case i would expect that the long word could overflow, but now the table / column is adjusting its width.
Can anyone tell me how this is working and why it's working like that? I know I can solve it with things like word-wrap: break-word; but I want to understand it.
Because you included a long line of unbroken text. By default the browser won't break up that text unless you tell it to with a rule like word-break:break-all;. So it does work as expected, you're just giving it text that it doesn't want to break because that's the default behavior. You'll also see if you remove that long unbroken string of text that the column is 200px wide.
.myTable {
border: 1px solid black;
}
.myTable th,
.myTable td {
border: 1px solid black;
word-break:break-all;
}
<table class="myTable" style="width: auto; table-layout: fixed;">
<tr>
<th>Column A</th>
<th style="width: 200px">Column B</th>
</tr>
<tr>
<td>A1</td>
<td>B1: This is a sentence with a very long word in it, to check what the behavior is of the table in a case like that. Will long words be broken and wrap onto the next line? Thisisaverylongwordyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitis</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>

HTML table with variable, fixed, and remaining width

I need to create an HTML table with the following layout:
[Name] [Message] Date]
Where the width of [Name] should be the width of the longest name (Up to a max), [Date]should be a fixed width of 95px (And floating to the right), while [Message] should take the remaining width.
I've tried using multiple div's, but I can't get the result I need, and a table seems much simpler.
So far, the following isn't working:
<table style="width: 100%">
<tr>
<td style="width: 100%; max-width: 100px">NAME</td>
<td style="width: 100%">message</td>
<td style="width: 95px">TIME</td>
</tr>
<tr>
<td style="width: 100%; max-width: 100px">NAME OTHER</td>
<td style="width: 100%">message</td>
<td style="width: 95px">TIME</td>
</tr>
</table>
Edit 1 Seems as though this example has exactly what I need. Although I still think a table would be neater.
Edit 2 The [Message] needs to allow for multiline...
Edit 3 Here is a working sample of what I need (Exactly) based on the link in Edit 1
This cannot be done in CSS alone, due to the requirements. The first column should be flexible, which is easy (just prevent line breaks and let the column take its natural width), and setting the last column width is trivial, but telling the browser to use all the rest in the mid column (instead of expanding the first column too) cannot be done in CSS. If you set its width to 100%, things work the desired way in some browsers, but other browsers (like IE) treat it differently. You would require a width of something plus 100% plus 95px to equal 100%, which is of course impossible, and browsers handle this in different ways.
However, with a little bit of JavaScript the medicine goes down: do as outlined above, with 100%, then postprocess the table by setting the first column to a specific width in pixels (using the value allocated by the browser), remove the width: 100% setting, and set table layout to fixed—which means that the browser now has two columns width fixed width, total width set to 100%, and one column with no width set, so it is easy to it to allocate the remaining width to the mid column.
<style>
td:first-child { white-space: nowrap }
td:nth-child(2) { width: 100% }
td:nth-child(3) { width: 95px }
</style>
<table border cellspacing=0 style="width: 100%">
<tr>
<td style="">NAME</td>
<td style="">message</td>
<td style="width:95px">TIME</td>
</tr>
<tr>
<td>NAME OTHER</td>
<td>message</td>
<td>TIME</td>
</tr>
</table>
<script>
(function () {
var row = document.getElementsByTagName('tr')[0];
var cell1 = row.children[0];
cell1.style.width = cell1.clientWidth + 'px';
row.children[1].style.width = 'auto';
document.getElementsByTagName('table')[0].style.tableLayout = 'fixed';
})();
</script>
For simplicity, this code is based on the assumption that there are no other tables on the page. Modify as needed. The attributes border cellspacing=0 are there just make the cell widths more visible.
Update: This does not address the issue of setting a maximum width on the first column. That requirement is underdefined unless you specify what should happen if the width is exceeded (truncation, word wrap, wrap anywhere, wrap with hyphenation?).
try this code .
.test
{
max-width:100px;
}
<table style="text-align: center;">
<tr>
<th>NAME</th>
<th>message</th>
<th style="width: 95px">TIME</th>
</tr>
<tr>
<td class="test">NAME OTHER</td>
<td>message</td>
<td style="width: 95px">TIME</td>
</tr>
</table>
The following .css code provides the template for the attached picture:
table {
display: table;
width: 100%;
table-layout: fixed;
position: absolute;
top: 10px;
empty-cells: hide;
}
td.small:first-Child {
vertical-align: top;
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
}
td.small:last-Child {
vertical-align: top;
width: 95px;
}
td.extend {
vertical-align: top;
word-wrap: break-word;
}
.userName a {
color: #9DC8FC;
}
<tr>
<td class="small userName">
<a title="Administrator" href="#">Administrator</a>
</td>
<td class="extend">
is it me you're looking for?
</td>
<td class="small">
10:14:01 AM
</td>
</tr>

In an html table, why doesn't header width change overall table width?

Check out this fiddle:
http://jsfiddle.net/foreyez/hQ9ZR/
<table background='red'>
<thead>
<tr>
<th style='width:3000px;background:red'>Students</th>
</tr>
</thead>
<tbody>
<tr>
<td>Joe</td>
</tr>
<tr>
<td>Shmoe</td>
</tr>
</tbody>
​
and the css is:
html,body { overflow:auto; }
When I make the width of the Header 3000px I'd expect it to cause an overflow (scrollbar) in the page. But it doesn't. It's because the width of the header cell doesn't change the overall table's width.
If you set the width of the table to 3000px, you'll see the overflow (scrollbar)
So basically, I'm wondering if there's a way to make it so the table's width is defined by it's headers widths?
Thanks
First of all this is not the way you style tables these days
<table background='red'>
use this instead
<table style="background:red;">
And secondly you need to use min-width for th instead of width
My Fiddle
<th style='border: 1px solid #fffff0;min-width:5000px;background:red'>Students</th>

How to force min-height on table

I have this code :
<table cellspacing="0" cellpadding="0" border="0" style="width:415px">
<tbody>
<tr valign="top">
<td style="font-family:Arial;min-height:60px;font-size:12px;line-height:14px;">
This is my text that I need in 2 lines
</td>
</tr>
<tr valign="top">
<td style="font-size:12px;line-height:14px">
Second Line
</td>
</tr>
</tbody>
</table>
As you can see, the first tr/td should be height 60px (min-height:60px) but in fact it isn't.
For many reasons, I can't use height directly (this code is formatted trought back office system, in a newsletter).
So, how can I take the whole height on the td trought min-height?
Also, tried putting min-height:60px; on tr, but nothing change...
min-height doesn't work for table elements:
In CSS 2.1, the effect of 'min-width' and 'max-width' on tables, inline tables, table cells, table columns, and column groups is undefined.
I can only assume this applies to td and tr as well.
What should always work is wrapping the content in a div, and applying min-height to that, as shown in this JSFiddle:
<td style="font-family:Arial;min-height:60px;font-size:12px;line-height:14px;">
<div style="min-height: 60px; background-color: green">
This is my text that I need in 2 lines
</div>
</td>
Edit: You say this doesn't work with Outlook.
Alternative idea: Place a 60 px tall image in the td, and make it float: left:
<td>
<img src="..." style="float: left">
</td>
Use <td height="60"> not CSS height or min-height
For HTML email set your table cell as <td height="60"> and it will treat that as the min-height. If your content is more than 60px, it will expand accordingly.
Put a DIV in the cell, style the DIV instead.
Min-height doesn't works on tables.
It is sometimes useful to constrain the height of elements to a certain range. Two properties offer this functionality: min-height & max-height
But these can't be used on non-replaced inline elements, table columns, and column groups.
You can't set min-height and min-width, but you can use some CSS3 for achievements this same effect.
.default-table table {
border-collapse: collapse;
}
.default-table table td {
padding: 0;
}
.default-table tr:before {
width: 0px;
content: '';
float: left;
overflow: hidden;
height: 28px;
font-size: 0;
}
.default-table {
overflow: hidden;
}
<div class="default-table">
<table>
<tbody>
<tr>
<td>Steve</td>
<td>Smith</td>
<td>stevesmith#gmail.com</td>
</tr>
<tr>
<td>Jone</td>
<td>Polanski</td>
<td>jonep#gmail.com</td>
</tr>
</tbody>
</table>
</div>
but if u having collapse or padding in td. You must give for .default-table table minus margin-left.
HTML :
<table></table>
CSS :
table{
height:0px; /*Set any facultative length value to Height (percentage value doesn't work)*/
min-height:100vh;
}
That's how I always resolve this problem ...
Add display block
<td style="font-family:Arial;min-height:60px;font-size:12px;line-height:14px;display:block;">
Here's a solution that works in Outlook (tested) and other e-mail clients:
<td style="mso-line-height-rule:exactly;line-height:300px;"> </td>
This is cleaner than using an image, which could negatively affect your spam score, and does the exact same thing.
If you have other content in the <td> that you don't want to have that line height, you can just wrap the non-breaking space in a <span> and set the line-height on that tag:
<td><span style="mso-line-height-rule:exactly;line-height:300px"> </span>**Other content without 300px line-height here**</td>
The reason height or min-height works on <div> tags and not <td> is because <td> are set to display:table-cell and do not respect height the same way that display:block (<div>) elements do.
I have resolved this issue by adding display:block; to its style as
<td style="display:block; min-height:200px;">
min-height does not work in td, Set height that will work like min-height and automatic increase height if needed. That is worked for me
Here is a solution that does not depend on the height in pixels. It works in all email clients:
<table cellspacing="0" cellpadding="0" border="0" style="width:415px">
<tbody>
<tr valign="top">
<td style="font-family:Arial;font-size:12px;line-height:14px;">
This is my text that I need in 2 lines
</td>
<td style="font-family:Arial;font-size:12px;line-height:14px;">
<br/><br/>
</td>
</tr>
<tr valign="top">
<td style="font-size:12px;line-height:14px">
Second Line
</td>
</tr>
</tbody>
The solution works by adding a zero-width column with two lines to the right of the first one. It uses the  character, which is a non-breaking zero-width space.
It may be reviving a 2012 post, for those who searched and found this post like me:
Note: Check these addresses for the email client support before using this method, at the time of writing this answer, the support was around 50% -ish.
E-mail client support range of :first-child
E-mail client support range of ::before
table tr:first-child td:before {
min-height: 100px;
display: block;
content: ""
}
<table border="1">
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>
What I found !!!, In tables CSS td{height:60px;} works same as CSS td{height:60px;}

Overflow in table cells

I need to create a chat layout that uses all the available space and scales nicely, but has few fixed sizes.
Here's the structure:
<table style="width: 100%; height: 100%">
<tr>
<td></td>
<td style="width: 200px; background: red;"></td>
</tr>
<tr>
<td style="height: 100px; background: blue"></td>
<td></td>
</tr>
</table>
However, I want to place a lot of content in the first table cell and I want it to scroll, so it won't expand the table.
Is it possible to make it overflow properly, without having a fixed height for the cell? Simply adding overflow: auto doesn't seem to work.
PS. I hate tables, but can't figure out a very clean and cross-browser way to do a layout like this with divs and css. If someone can come up with one, I'll gladly use it.
One way to achieve is use put all content in div element and set div overflow property to auto
<table style="width: 100%; height: 100%">
<tr>
<td>
<div style="overflow:auto;">
//your contain
</div>
</td>
<td style="width: 200px; background: red;"></td>
</tr>
<tr>
<td style="height: 100px; background: blue"></td>
<td></td>
</tr>
</table>
An alternative if your content shouldn't actually even be in a table is to use a CSS grid system, such as 960.gs or Nicole Sullivan's "OO-CSS".
You'd want to divide a container into however many grids you needed and these lend themselves much better to CSS decoration. They're much more flexible and simple to use.