196

A lot of people still use tables to layout controls, data etc. - one example of this is the popular jqGrid. However, there is some magic happening that I cant seem to fathom (its tables for crying out loud, how much magic could there possibly be?)

How is it possible to set a table's column width and have it obeyed like jqGrid does!? If I try to replicate this, even if I set every <td style='width: 20px'>, as soon as the content of one of those cells is greater than 20px, the cell expands!

Any ideas or insights?

C R
  • 2,182
  • 5
  • 32
  • 41
Jimbo
  • 22,379
  • 42
  • 117
  • 159

7 Answers7

277

You could try using the <col> tag manage table styling for all rows but you will need to set the table-layout:fixed style on the <table> or the tables css class and set the overflow style for the cells

http://www.w3schools.com/TAGS/tag_col.asp

<table class="fixed">
    <col width="20px" />
    <col width="30px" />
    <col width="40px" />
    <tr>
        <td>text</td>
        <td>text</td>
        <td>text</td>
    </tr>
</table>

and this be your CSS

table.fixed { table-layout:fixed; }
table.fixed td { overflow: hidden; }
hunter
  • 62,308
  • 19
  • 113
  • 113
  • 18
    col wouldn't work in html5, set width of individual td instead by inline css or css classes – Pankaj Phartiyal May 22 '13 at 17:58
  • 11
    The accepted answer does not work unless you explicitly apply a width for the desired table. Works perfectly whether you use a unit or a percentage. Figured I'd point this out since @totymedli's answer didn't get any votes and I didn't want users to ignore it. However, the word-break suggestion isn't necessary unless that's what you're aiming for. – thebdawk05 Jul 29 '13 at 18:12
  • What happens when you have rows with only 1 TD element that spans multiple columns? Using your sample code, if you had `` in a row by itself would it be 90px? – sab669 Jun 17 '15 at 13:43
  • Thanks it helped. For data overlapping, add this `table.fixed td { word-wrap: break-word; }`. – Parag Tyagi Jan 05 '16 at 10:52
  • The word-break suggestion isn't necessary, but it is useful for the rest of SO users and quite pertinent to the question, as overflowing content in fixed width tables is almost certain to ocurr in most scenarios. – Amy Pellegrini Feb 24 '17 at 16:41
  • Can I use percentages for the `col` width, or does it have to be pixel values? – Cardinal System Feb 27 '23 at 14:00
  • What about row height? – Cardinal System Feb 28 '23 at 16:00
111

Now in HTML5/CSS3 we have better solution for the problem. In my opinion this purely CSS solution is recommended:

table.fixed {table-layout:fixed; width:90px;}/*Setting the table width is important!*/
table.fixed td {overflow:hidden;}/*Hide text outside the cell.*/
table.fixed td:nth-of-type(1) {width:20px;}/*Setting the width of column 1.*/
table.fixed td:nth-of-type(2) {width:30px;}/*Setting the width of column 2.*/
table.fixed td:nth-of-type(3) {width:40px;}/*Setting the width of column 3.*/
<table class="fixed">
    <tr>
        <td>Veryverylongtext</td>
        <td>Actuallythistextismuchlongeeeeeer</td>
        <td>We should use spaces tooooooooooooo</td>
    </tr>
</table>

You need to set the table's width even in haunter's solution. Otherwise it doesn't work.
Also a new CSS3 feature that vsync suggested is: word-break:break-all;. This will break the words without spaces in them to multiple lines too. Just modify the code like this:

table.fixed { table-layout:fixed; width:90px; word-break:break-all;}

Final result

Rendered table

Community
  • 1
  • 1
totymedli
  • 29,531
  • 22
  • 131
  • 165
  • If you throw a row in with a `colspan`, this seems to break this solution. Any suggestions on how to utilize this solution with a table that contains `colspan` > 1? – Eric K Jan 16 '14 at 16:31
  • @QuantumDynamix I fixed this by including as the first row, a row with no colspans, just all individual columns with widths. I then hid that row with 0 height, border:none, visibility:hidden, padding:0px etc., then the second row is the first one I want seen where there are colspans. The first row with individual fixed width cells establishes the widths. – AaronLS Mar 18 '14 at 16:42
  • @totymedli Any ideas how to get my table to take on the sum of all my column widths? My table is generated dynamically a bit and I so can't calculate in advance the table width, but I don't want to use 100% because that stretches some elements. – AaronLS Mar 18 '14 at 16:43
18
table td 
{
  table-layout:fixed;
  width:20px;
  overflow:hidden;
  word-wrap:break-word;
}
Bakudan
  • 19,134
  • 9
  • 53
  • 73
ajreal
  • 46,720
  • 11
  • 89
  • 119
  • 11
    Are you sure you can use `table-layout` on a td element? – Nick Feb 08 '14 at 01:18
  • @Nick - it works okay. Hovewer i have to add min-width and max-width property also (same value as width), and then it became truly fixed width. – Denis Khay May 11 '18 at 14:27
16

I had one long table td cell, this forced the table to the edges of the browser and looked ugly. I just wanted that column to be fixed size only and break the words when it reaches the specified width. So this worked well for me:

<td><div style='width: 150px;'>Text to break here</div></td>

You don't need to specify any kind of style to table, tr elements. You may also use overflow:hidden; as suggested by other answers but it causes for the excess text to disappear.

Tarik
  • 4,270
  • 38
  • 35
  • 2
    Or you can use max-width instead of width where needed. This will allow you not to break the text unless you reach your width limit. And the table cell won't have empty space if your text is smaller than the specified width.
    Text to break here
    – Tarik Jul 11 '16 at 14:51
6

for FULLSCREEN width table:

  • table width MUST be 100%

  • if need N colunms, then THs MUST be N+1

example for 3 columns:

table.fixed {
      table-layout: fixed;
      width: 100%;
    }
table.fixed td {
      overflow: hidden;
    }
  <table class="fixed">
      <col width=20 />
      <col width=20 />
      <col width=20 />
    <tr>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>FREE</th>
    </tr>
    <tr>
      <td>text111111111</td>
      <td>text222222222</td>
      <td>text3333333</td>
    </tr>
  </table>
Ramil Gilfanov
  • 552
  • 1
  • 8
  • 12
2
table { 
    table-layout:fixed; width:200px;
}
table tr {
    height: 20px;
}

10x10

hafichuk
  • 10,351
  • 10
  • 38
  • 53
-2
table
{
  table-layout:fixed;
}
td,th
{
  width:20px; 
  word-wrap:break-word;
}

:first-child ... :nth-child(1) or ...

xhdix
  • 145
  • 1
  • 7