ccleve
ccleve

Reputation: 15799

Setting max-height for table cell contents

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>

Upvotes: 65

Views: 167989

Answers (9)

Tim R
Tim R

Reputation: 3102

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>

Upvotes: 1

Merlinox
Merlinox

Reputation: 377

I solved it in that way:

.tbGDPR td {
    border: 1px solid #eee;
    border-collapse: collapse;
}
.tbGDPR td div {
    max-height: 2em;
    overflow: hidden;
}

Upvotes: 0

Joseph Marikle
Joseph Marikle

Reputation: 78520

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;
}

Upvotes: 3

zak
zak

Reputation: 876

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

td {
    display: table-caption;
}

Upvotes: -3

cellen
cellen

Reputation: 156

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.

Upvotes: 0

Francesco Borzi
Francesco Borzi

Reputation: 61834

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

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

Upvotes: 0

Mr. Rick
Mr. Rick

Reputation: 155

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

Upvotes: 2

keithics
keithics

Reputation: 8758

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>

Upvotes: 91

ccleve
ccleve

Reputation: 15799

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.

Upvotes: 20

Related Questions