64

I have a table which should always occupy a certain percentage of the height of the screen. Most of the rows are of fixed height, but I have one row that should stretch to fill the available space. In the event that the contents of a cell in that row overflows the desired height, I'll like the contents to clip using overflow:hidden.

Unfortunately, tables and rows do not respect the max-height property. (This is in the W3C spec). When there is too much text in the cell, the table gets taller, instead of sticking to the specified percentage.

I can get the table cell to behave if I specify a fixed height in pixels for it, but that defeats the purpose of having it automatically stretch to fill available space.

I've tried using divs, but can't seem to find the magic formula. If I use divs with display:table, :table-row, and :table-cell the divs act just like a table.

Any clues on how I can simulate a max-height property on a table?

<head>
    <style>
        table {
            width: 50%;
            height: 50%;
            border-spacing: 0;
        }
        td {
            border: 1px solid black;
        }
        .headfoot {
            height: 20px;
        }
        #content {
            overflow: hidden;
        }
    </style>
</head>
<body>
<table>
    <tr class="headfoot"><td>header</td></tr>
    <tr>
        <td>
        <div id="content">
            put lots of text here
        </div>
        </td>
        <tr>
    <tr class="headfoot"><td>footer</td></tr>
</table>
</body>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
ccleve
  • 15,239
  • 27
  • 91
  • 157
  • If you paste the code into an html page you'll see it, except that the table takes up more than 50% of the height of the screen. It should take only 50%. Put lots of text in the content tag. – ccleve Aug 12 '11 at 20:30
  • 1
    Possible duplicate of [How to set maximum height for table-cell?](http://stackoverflow.com/questions/13667941/how-to-set-maximum-height-for-table-cell) – vaultah Sep 27 '16 at 17:43

9 Answers9

87

Just put the labels in a div inside the TD and put the height and overflow.. like below.

<table>
<tr>
  <td><div style="height:40px; overflow:hidden">Sample</div></td>
  <td><div style="height:40px; overflow:hidden">Text</div></td>
  <td><div style="height:40px; overflow:hidden">Here</div></td>
</tr>
</table>
keithics
  • 8,576
  • 2
  • 48
  • 35
  • 13
    that is the easy part, but what if you have no access to the HTML, and only to the CSS? – vsync Jan 31 '13 at 02:59
  • 5
    that answer its easier than using lots of js. Why wouldn't you have access to html when programming for web? – Guilherme David da Costa Jan 30 '15 at 18:39
  • 1
    I have this problem too and like @vsync, I'm using Kendo UI Grid and I can't very easily control what HTML lands up in the table. I think I can make a Row Template or a Column Template which both do allow me to input my own HTML. I can see where you could run into this with other frameworks/systems that don't allow templating. – HK1 Sep 13 '16 at 12:47
21

We finally found an answer of sorts. First, the problem: the table always sizes itself around the content, rather than forcing the content to fit in the table. That limits your options.

We did it by setting the content div to display:none, letting the table size itself, and then in javascript setting the height and width of the content div to the inner height and width of the enclosing td tag. Show the content div. Repeat the process when the window is resized.

ccleve
  • 15,239
  • 27
  • 91
  • 157
  • 2
    @ccleve can you please give a jsfiddle working code. I am not able to exactly understand what you did. I am facing the same issue since very long. – EdG Apr 03 '17 at 06:30
3

Possibly not cross browser but I managed get this demo in JSFiddle

Basically it requires a fixed height header and footer, and it absolute positions the table.

table {
    width: 50%;
    height: 50%;
    border-spacing: 0;
    position:absolute;
}
td {
    border: 1px solid black;
}
#content {
    position:absolute;
    width:100%;
    left:0px;
    top:20px;
    bottom:20px;
    overflow: hidden;
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • Interesting idea, I hadn't considered position:absolute. Didn't work on Firefox, though. – ccleve Aug 15 '11 at 18:46
  • 1
    This requires a wrapper div around the contents of the table cell: if that's a possibility, it's easier to just set the height of the wrapper div – user56reinstatemonica8 Apr 25 '14 at 09:25
  • Use "display: block" in element inside on the td, don't use "position: absolute" and "top, left,..." – Covii Jan 04 '22 at 17:51
2

What I found !!!, In tables CSS td{height:60px;} works same as CSS td{min-height:60px;}

I know that situation when cells height looks bad . This javascript solution don't need overflow hidden.

For Limiting max-height of all cells or rows in table with Javascript:

This script is good for horizontal overflow tables.

This script increase the table width 300px each time (maximum 4000px) until rows shrinks to max-height(160px) , and you can also edit numbers as your need.

var i = 0, row, table = document.getElementsByTagName('table')[0], j = table.offsetWidth;
while (row = table.rows[i++]) {
    while (row.offsetHeight > 160 && j < 4000) {
        j += 300;
        table.style.width = j + 'px';
    }
}

Source: HTML Table Solution Max Height Limit For Rows Or Cells By Increasing Table Width, Javascript

Community
  • 1
  • 1
Mr. Rick
  • 155
  • 1
  • 14
0

I've solved just using this plugin: http://dotdotdot.frebsite.nl/

it automatically sets a max height to the target and adds three dots

Francesco Borzi
  • 56,083
  • 47
  • 179
  • 252
0

I had the same problem with a table layout I was creating. I used Joseph Marikle's solution but made it work for FireFox as well, and added a table-row style for good measure. Pure CSS solution since using Javascript for this seems completely unnecessary and overkill.

html

<div class='wrapper'>
    <div class='table'>
        <div class='table-row'>
            <div class='table-cell'>
                content here
            </div>
            <div class='table-cell'>
                <div class='cell-wrap'>
                    lots of content here
                </div>
            </div>
            <div class='table-cell'>
                content here
            </div>
            <div class='table-cell'>
                content here
            </div>
        </div>
    </div>
</div>

css

.wrapper {height: 200px;}
.table {position: relative; overflow: hidden; display: table; width: 100%; height: 50%;}
.table-row {display: table-row; height: 100%;}
.table-cell {position: relative; overflow: hidden; display: table-cell;}
.cell-wrap {position: absolute; overflow: hidden; top: 0; left: 0; width: 100%; height: 100%;}

You need a wrapper around the table if you want the table to respect a percentage height, otherwise you can just set a pixel height on the table element.

cellen
  • 156
  • 1
  • 11
  • 3
    This is not a pure-CSS solution. You reproduced your table using `div`'s. – Nathan Arthur Aug 23 '17 at 13:33
  • 2
    Producing an HTML table with `div`s is not a good way to do it. There is a reason that there is a `table` tag e.g. considering users with disabilities – jdrake Dec 03 '19 at 14:29
  • @NathanArthur Pure CSS solution without using JavaScript but you're complaining about HTML being used as well? – Tim R Aug 22 '23 at 23:00
  • @TimR That comment is six years old. But, yes, you are correct, I was complaining about HTML being used as well. – Nathan Arthur Aug 23 '23 at 14:46
0

I solved it in that way:

.tbGDPR td {
    border: 1px solid #eee;
    border-collapse: collapse;
}
.tbGDPR td div {
    max-height: 2em;
    overflow: hidden;
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Merlinox
  • 377
  • 3
  • 9
0

The table cell height cannot be restricted but a nested element can, as others have answered in this question and the duplicate How to set maximum height for table-cell?

However, the previous answers don't address the inferred question of how the nested element height can be responsive to fill the available space while the table height remains a percentage of the screen.


Per the question description and given code, the table height should be 50% of the viewport, not the parent element. Therefore, the height value should be declared with a viewport length unit, such as 50vh or 50vb. (1vh is 1% of the viewport height. vb is the logical unit for the viewport block.)

table {
  height: 50vb;
}


The nested container #content should have height: 100% and overflow: auto so that it fills all and only the available space in the table cell without visible overflow. (Edit: I discovered that Firefox won't allow a percentage height with overflow. See next section for calculation.)

#content {
  height: 100%;
  overflow: auto;
}


However, a percentage cannot be used for the content height if overflow is to be hidden. (Maybe somebody can explain why.) The value can calculate the height of the table minus the height of the other rows (borders and spacing on the table cell should be subtracted as well.)

#content {
  height: calc(50vb - 42px);
  overflow: hidden;
}


This snippet demonstrates a responsive table for scrollable overflow and hidden overflow.

table {
  width: 50%;
  height: 50vb;
  border-spacing: 0;
}

td {
  padding: 0;
  border: 1px solid;
}

.headfoot {
  height: 20px;
}

#content {
  height: 100%;
  overflow: auto;
}


table:nth-of-type(2) #content {
  height: calc(50vb - 42px);
  overflow: hidden;
}

table:nth-of-type(2) {
 margin-block-start: 4em;
}
<table>
  <tr class="headfoot"><td>header</td></tr>
  <tr>
    <td>
      <div id="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In arcu cursus euismod quis viverra nibh cras pulvinar mattis. Dignissim sodales ut eu sem integer vitae justo eget magna. Quam vulputate dignissim suspendisse in est ante in nibh mauris. Tortor aliquam nulla facilisi cras. Dolor sit amet consectetur adipiscing elit ut. Sed libero enim sed faucibus turpis in eu. Duis convallis convallis tellus id interdum. Nunc congue nisi vitae suscipit. Integer enim neque volutpat ac tincidunt vitae semper. Metus dictum at tempor commodo ullamcorper. Dictum sit amet justo donec enim diam vulputate ut. Bibendum enim facilisis gravida neque convallis a.</p>
        <p>Tristique et egestas quis ipsum suspendisse ultrices gravida dictum. Tristique risus nec feugiat in fermentum. Iaculis at erat pellentesque adipiscing commodo elit. Elit scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Consequat interdum varius sit amet mattis vulputate enim nulla aliquet. Mattis molestie a iaculis at erat pellentesque. Massa enim nec dui nunc mattis. Sit amet dictum sit amet justo donec enim diam. Et netus et malesuada fames ac turpis egestas maecenas. Pretium aenean pharetra magna ac. Sit amet nisl purus in mollis. Euismod lacinia at quis risus sed vulputate odio ut enim. Non enim praesent elementum facilisis leo vel fringilla est. Ac ut consequat semper viverra nam. Egestas fringilla phasellus faucibus scelerisque.</p>
        <p>Egestas purus viverra accumsan in nisl nisi. Nulla malesuada pellentesque elit eget. Quis auctor elit sed vulputate mi sit. Elit sed vulputate mi sit. Duis at consectetur lorem donec massa. Ipsum dolor sit amet consectetur. Lacus vel facilisis volutpat est velit egestas dui id. Purus in mollis nunc sed id semper risus in. Scelerisque felis imperdiet proin fermentum leo vel orci. Fringilla est ullamcorper eget nulla facilisi etiam dignissim. Pulvinar proin gravida hendrerit lectus a.</p>
      </div>
    </td>
  </tr>
  <tr class="headfoot"><td>footer</td></tr>
</table>


<table>
  <tr class="headfoot"><td>header</td></tr>
  <tr>
    <td>
      <div id="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In arcu cursus euismod quis viverra nibh cras pulvinar mattis. Dignissim sodales ut eu sem integer vitae justo eget magna. Quam vulputate dignissim suspendisse in est ante in nibh mauris. Tortor aliquam nulla facilisi cras. Dolor sit amet consectetur adipiscing elit ut. Sed libero enim sed faucibus turpis in eu. Duis convallis convallis tellus id interdum. Nunc congue nisi vitae suscipit. Integer enim neque volutpat ac tincidunt vitae semper. Metus dictum at tempor commodo ullamcorper. Dictum sit amet justo donec enim diam vulputate ut. Bibendum enim facilisis gravida neque convallis a.</p>
        <p>Tristique et egestas quis ipsum suspendisse ultrices gravida dictum. Tristique risus nec feugiat in fermentum. Iaculis at erat pellentesque adipiscing commodo elit. Elit scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Consequat interdum varius sit amet mattis vulputate enim nulla aliquet. Mattis molestie a iaculis at erat pellentesque. Massa enim nec dui nunc mattis. Sit amet dictum sit amet justo donec enim diam. Et netus et malesuada fames ac turpis egestas maecenas. Pretium aenean pharetra magna ac. Sit amet nisl purus in mollis. Euismod lacinia at quis risus sed vulputate odio ut enim. Non enim praesent elementum facilisis leo vel fringilla est. Ac ut consequat semper viverra nam. Egestas fringilla phasellus faucibus scelerisque.</p>
        <p>Egestas purus viverra accumsan in nisl nisi. Nulla malesuada pellentesque elit eget. Quis auctor elit sed vulputate mi sit. Elit sed vulputate mi sit. Duis at consectetur lorem donec massa. Ipsum dolor sit amet consectetur. Lacus vel facilisis volutpat est velit egestas dui id. Purus in mollis nunc sed id semper risus in. Scelerisque felis imperdiet proin fermentum leo vel orci. Fringilla est ullamcorper eget nulla facilisi etiam dignissim. Pulvinar proin gravida hendrerit lectus a.</p>
      </div>
    </td>
  </tr>
  <tr class="headfoot"><td>footer</td></tr>
</table>
Tim R
  • 2,622
  • 1
  • 3
  • 19
-3

Another way around it that may/may not suit but surely the simplest:

td {
    display: table-caption;
}
zak
  • 776
  • 10
  • 10
  • 5
    This answer would benefit from a description of *what it does*. – TylerH Aug 30 '17 at 19:32
  • 2
    It umm. sets the display to ahhh table-caption :} – zak Oct 05 '17 at 04:54
  • 9
    Obviously, but what effect does that have on the code? In other words, *why* does setting the display value to table-caption solve the problem of the OP? Good answers provide both a solution and an explanation. – TylerH Oct 05 '17 at 14:21
  • 2
    table-caption always render on top of the table (@media print) similar to th but does not repeat on each page – venimus Dec 12 '17 at 07:50