8

If I have

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

and

table
    { width: 100%; height: 100%; }

Each cell takes up an equal quarter of the table, and the table stretches to fit the window.

How can I prevent these table cells from resizing themselves to fit the content within the cells (while still fitting the table's container)?

Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
Nick
  • 4,830
  • 8
  • 36
  • 67

8 Answers8

15

You could try table-layout:fixed; - this sets the layout to a certain fixed size (specified in CSS) and ignores the content of the cells, so the width of the cell never changes. I'm not sure if this affects vertical layout or not.

More info on w3schools.

whostolemyhat
  • 3,031
  • 4
  • 32
  • 50
  • 3
    You're right -- it works on horizontal widths but not vertical. I feel like CSS is useless for even the simplest of things. I'm just trying to make a calendar! – Nick Jan 11 '11 at 17:55
  • @RomanGaufman I think that [my answer to this question](http://stackoverflow.com/a/17429778/49942) works for vertical as well. – ChrisW Jul 02 '13 at 15:38
2

You can do it by using position: absolute on the content of each table cell: because if you do then the size of the content doesn't affect the size of the cell.

To do this, you must then also position the table cells (so that absolute positioning of the content is relative to the table cell) -- and/or, to support Firefox, position an extra div within the table cells since Firefox doesn't let you apply position to the cells themselves.

For example, I'm using this HTML:

<td><div class="bigimg"><img src="...."/></div></td>

Together with the following CSS, so that the size of the image doesn't affect the size of the cell which contains it:

div.bigimg
{
    height: 100%;
    width: 100%;
    position: relative;
}
div.bigimg > img
{
    position: absolute;
    top: 0;
    left: 0;
}

I set the height and width of div.bigimg to 100% to match the size of the td which contains it, because I'm using JavaScript to resize the images at run time to fit their containers, which are the div.bigimg.


Here's another example, using text instead of images -- same principle though, i.e. position: absolute inside position: relative inside each cell and the cells don't fit the content.

enter image description here

ChrisW
  • 51,820
  • 11
  • 101
  • 201
  • Is there some explanation as to WHY this would be required? a 3x3 table seems to resize even though the image already fits within the table cell! – ericslaw Sep 28 '16 at 03:55
  • @ericslaw I don't understand your comment/question. Maybe you could post it as a new question. – ChrisW Sep 29 '16 at 15:36
  • @PhilipRego I don't see why -- if the cell's content is `position: absolute` then it's no longer really content, is it, i.e. no longer positioned as a child of the cell. Are you sure your cell content is 'position:absolute` (see e.g. the HTML and CSS in my answer)? – ChrisW Apr 19 '19 at 19:06
  • @PhilipRego Wrap each p inside a div; make the div position relative, and make the p position absolute. The table will then layout as if there's nothing inside each cell (i.e. cells will be too small for the content unless you resize them), the apparently-empty div will be positioned in each cell, and the paragraphs will be positioned on (but won't affect the size of) each div. – ChrisW Apr 19 '19 at 19:50
  • 1
    @PhilipRego I added a corrected version of your example to the answer above. – ChrisW Apr 19 '19 at 20:11
2

I have managed to do this without fixed table layout. The cell's css:

.dataCell {
  display: table-cell;
  padding: 2px 15px 2px 15px;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  width: auto;
  max-width: 1px;
}
Galvani
  • 232
  • 2
  • 8
1

You can also lock the cells to a percentage, in order to maintain responsiveness, eg:

  td:first-child, th:first-child {
    width: 20%;
  }
  // assuming you have 8 remaining columns (20 + 10*8 = 100%)
  td:not(:first-child), th:not(:first-child) {
    width: 10%;
  }
Vinnie James
  • 4,816
  • 4
  • 33
  • 47
1

You could try to pick a single cell to chew up all the space and set that to 100% height and width:

<table>
    <tr>
        <td>Hi There.</td>
        <td>x</td>
    </tr>
    <tr>
        <td>Here is some text.</td>
        <td class="space-hog"></td>
    </tr>
</table>

and some CSS:

table {
    width: 100%;
    height: 100%;
}
td {
    white-space: nowrap;
}
td.space-hog {
    width: 100%;
    height: 100%;
}

And a live example. You need to be careful to avoid unpleasant line wrapping when .space-hog does its thing, hence the white-space: nowrap. If you put the .space-hog in the last row then you can avoid pushing the interesting parts down.

mu is too short
  • 396,305
  • 64
  • 779
  • 743
  • I'm not trying to get one cell to take up all the space -- I want ever cell to be equal in width and height regardless of content. – Nick Jan 11 '11 at 17:53
  • Okay, it wasn't clear to me. I don't think there is a way to say "make all these things the same size" in CSS, you have to say "make all these things Wpx wide and Hpx tall" and compute the dimensions yourself on the server or in JavaScript. Maybe supply more context in the question and someone might come up with a whole new approach that avoids table sizing kludges entirely. – mu is too short Jan 11 '11 at 18:20
0

td{ width:50%; } will work until the table gets small enough.

Jake
  • 11,124
  • 13
  • 57
  • 91
  • What if I don't know the number of rows or columns in advance? I've been using Javascript to give each cell a percentage width and height but can no longer do this. – Nick Jan 11 '11 at 05:45
  • I can't think of a pure HTML/CSS solution, you will probably need Javascript. You could try playing with the CSS overflow property. – Jake Jan 11 '11 at 05:52
0

Something along the lines of using overflow:hidden; perhaps?

nchpmn
  • 864
  • 1
  • 8
  • 22
-2

Add table-layout:fixed; to the table's styling.

If you notice this helps fix the width but not the height, this is because there might still exist some sort of padding within each td cell. Add padding:0px; to the td's styling.

Nathan Tuggy
  • 2,239
  • 27
  • 28
  • 36