CSS:截断表格单元格,但尽可能合适

时间:2011-03-08 23:46:17

标签: html css overflow tablelayout

认识弗雷德。他是一张桌子:

One cell has more content and is wider, the other has less content and is narrower

<table border="1" style="width: 100%;">
    <tr>
        <td>This cells has more content</td>
        <td>Less content here</td>
    </tr>
</table>
弗雷德的公寓有一个改变大小的奇怪习惯,所以他学会隐藏他的一些内容,以免推翻所有其他单位,并将弗利福德太太的客厅推到遗忘之中:

The cells are now the same size, but only one has its content truncated, and it looks like if the other cell gave if some whitespace, they could both fit.

<table border="1" style="width: 100%; white-space: nowrap; table-layout: fixed;">
    <tr>
        <td style="overflow: hidden; text-overflow: ellipsis">This cells has more content</td>
        <td style="overflow: hidden; text-overflow: ellipsis">Less content here</td>
    </tr>
</table>

这很有效,但弗雷德有一种唠叨的感觉,即如果他的右侧牢房(他的绰号为Celldito)放弃了一点空间,他的左侧牢房就不会被截断。你能救他的理智吗?


总结:表格的单元格如何均匀地溢出,并且只有当它们都放弃了所有空格时?

18 个答案:

答案 0 :(得分:62)

<table border="1" style="width: 100%;">
    <colgroup>
        <col width="100%" />
        <col width="0%" />
    </colgroup>
    <tr>
        <td style="white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:1px;">This cell has more content.This cell has more content.This cell has more content.This cell has more content.This cell has more content.This cell has more content.</td>
        <td style="white-space: nowrap;">Less content here.</td>
    </tr>
</table>

http://jsfiddle.net/7CURQ/

答案 1 :(得分:36)

我相信我有一个非JavaScript的解决方案!迟到总比不到好,对吧?毕竟这是一个很好的问题,谷歌就是全力以赴。我不想满足于javascript修复,因为我发现页面加载后出现的轻微抖动是不可接受的。

功能

  • 没有javascript
  • 没有固定布局
  • 没有加权或百分比宽度技巧
  • 适用于任意数量的列
  • 简单的服务器端生成和客户端更新(无需计算)
  • 跨浏览器兼容

工作原理:在表格单元格中,将内容的两个副本放在相对定位的容器元素中的两个不同元素中。间隔元件静态定位,因此将影响台单元的宽度。通过允许隔离物单元的内容物包裹,我们可以获得我们正在寻找的表格单元的“最佳”宽度。这也允许我们使用绝对定位的元素将可见内容的宽度限制为相对定位的父元素的宽度。

经过测试和使用:IE8,IE9,IE10,Chrome,Firefox,Safari,Opera

结果图片

Nice proportional widths Nice proportional clipping

JSFiddle http://jsfiddle.net/zAeA2/

示例HTML / CSS

<td>
    <!--Relative-positioned container-->
    <div class="container">
        <!--Visible-->
        <div class="content"><!--Content here--></div>
        <!--Hidden spacer-->
        <div class="spacer"><!--Content here--></div>
        <!--Keeps the container from collapsing without
            having to specify a height-->
        <span>&nbsp;</span>
     </div>
</td>

.container {
    position: relative;
}
.content {
    position: absolute;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.spacer {
    height: 0;
    overflow: hidden;
}

答案 2 :(得分:20)

前几天我遇到了同样的挑战。 Lucifer Sam found似乎是最佳解决方案。

但我注意到你应该在spacer元素中复制内容。认为它不是那么糟糕,但我还想为剪辑文本应用title弹出窗口。这意味着长文本将在我的代码中第三次出现。

我建议从title伪元素访问:after属性以生成spacer并保持HTML清洁。

适用于IE8 +,FF,Chrome,Safari,Opera

<table border="1">
  <tr>
    <td class="ellipsis_cell">
      <div title="This cells has more content">
        <span>This cells has more content</span>
      </div>
    </td>
    <td class="nowrap">Less content here</td>
  </tr>
</table>
.ellipsis_cell > div {
    position: relative;
    overflow: hidden;
    height: 1em;
}

/* visible content */
.ellipsis_cell > div > span {
    display: block;
    position: absolute; 
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1em;
}

/* spacer content */
.ellipsis_cell > div:after {
    content: attr(title);
    overflow: hidden;
    height: 0;
    display: block;
}

http://jsfiddle.net/feesler/HQU5J/

答案 3 :(得分:18)

如果Javascript是可以接受的,我会整理一个快速例程,您可以将其作为起点。它动态地尝试使用跨度的内部宽度来调整单元格宽度,以响应窗口大小调整事件。

目前,它假设每个单元通常获得行宽的50%,并且它将折叠右单元以使左单元保持其最大宽度以避免溢出。根据您的使用情况,您可以实现更复杂的宽度平衡逻辑。希望这会有所帮助:

我用于测试的行的标记:

<tr class="row">
    <td style="overflow: hidden; text-overflow: ellipsis">
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
    </td>
    <td style="overflow: hidden; text-overflow: ellipsis">
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
    </td>
</tr>

连接调整大小事件的JQuery:

$(window).resize(function() {
    $('.row').each(function() {
        var row_width = $(this).width();
        var cols = $(this).find('td');
        var left = cols[0];
        var lcell_width = $(left).width();
        var lspan_width = $(left).find('span').width();
        var right = cols[1];
        var rcell_width = $(right).width();
        var rspan_width = $(right).find('span').width();

        if (lcell_width < lspan_width) {
            $(left).width(row_width - rcell_width);
        } else if (rcell_width > rspan_width) {
            $(left).width(row_width / 2);
        }
    });
});

答案 4 :(得分:15)

有一个更简单,更优雅的解决方案。

在要应用截断的表格单元格中,只需包含一个带有css table-layout:fixed的容器div。此容器占用父表单元格的整个宽度,因此它甚至可以响应。

确保将截断应用于表格中的元素。

从IE8 +

开始
<table>
  <tr>
    <td>
     <div class="truncate">
       <h1 class="truncated">I'm getting truncated because I'm way too long to fit</h1>
     </div>
    </td>
    <td class="some-width">
       I'm just text
    </td>
  </tr>
</table>

和css:

    .truncate {
      display: table;
      table-layout: fixed;
      width: 100%;
    }

    h1.truncated {
      overflow-x: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

这是一个工作小提琴 https://jsfiddle.net/d0xhz8tb/

答案 5 :(得分:11)

问题是'table-layout:fixed',它创建了均匀间隔固定宽度的列。但是禁用这个css-property会导致文本溢出,因为表会变得尽可能大(而且还会溢出)。

我很抱歉,但在这种情况下弗雷德不能吃他的蛋糕并把它吃掉......除非房东给予Celldito更少的空间,弗雷德不能使用他的......

答案 6 :(得分:9)

您可以尝试“加权”某些列,例如:

<table border="1" style="width: 100%;">
    <colgroup>
        <col width="80%" />
        <col width="20%" />
    </colgroup>
    <tr>
        <td>This cell has more content.</td>
        <td>Less content here.</td>
    </tr>
</table>

您还可以尝试一些更有趣的调整,例如使用0%-width列并使用white-space CSS属性的某种组合。

<table border="1" style="width: 100%;">
    <colgroup>
        <col width="100%" />
        <col width="0%" />
    </colgroup>
    <tr>
        <td>This cell has more content.</td>
        <td style="white-space: nowrap;">Less content here.</td>
    </tr>
</table>

你明白了。

答案 7 :(得分:3)

是的,我会说thirtydot有它,除非你使用js方法,否则没有办法做到这一点。您正在谈论一组复杂的渲染条件,您必须定义它们。例如当两个单元格对于他们的公寓变得太大时会发生什么,你将不得不决定谁有优先权,或者只是给他们一定比例的区域,如果他们过满,他们都会占用那个区域,只有当你有空白时你才会在另一个细胞中拉伸你的双腿,无论哪种方式都无法用css做到这一点。虽然人们用css做了一些我从未想过的非常时髦的事情。我真的怀疑你能做到这一点。

答案 8 :(得分:3)

使用一些css hack,似乎display: table-column;可以来拯救:

<div class="myTable">
    <div class="flexibleCell">A very long piece of content in first cell, long enough that it would normally wrap into multiple lines.</div>
    <div class="staticCell">Less content</div>
</div>

.myTable {
    display: table;
    width: 100%;
}

.myTable:before {
    display: table-column;
    width: 100%;
    content: '';
}

.flexibleCell {
    display: table-cell;
    max-width:1px;
    white-space: nowrap;
    text-overflow:ellipsis;
    overflow: hidden;
}

.staticCell {
    white-space: nowrap;
}

JSFiddle: http://jsfiddle.net/blai/7u59asyp/

答案 9 :(得分:3)

就像samplebias回答一样,如果Javascript是可接受的答案,我专门为此目的制作了一个jQuery插件:https://github.com/marcogrcr/jquery-tableoverflow

要使用插件,只需输入

即可
$('selector').tableoverflow();

完整示例: http://jsfiddle.net/Cw7TD/3/embedded/result/

<强>编辑:

  • 修复jsfiddle以获取IE兼容性。
  • 修复jsfiddle以获得更好的浏览器兼容性(Chrome,Firefox,IE8 +)。

答案 10 :(得分:1)

此问题在Google顶部弹出,因此,在我的情况下,我使用了CSS片段 来自https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/的结果,但将其应用于td并没有得到期望的结果。

我不得不在td中的文本周围添加一个div标签,省略号终于起作用了。

HTML代码缩写

<table style="width:100%">
 <tr>
    <td><div class='truncate'>Some Long Text Here</div></td>
 </tr>
</table>

CSS的缩写;

.truncate { width: 300px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

答案 11 :(得分:0)

不知道这是否会对任何人有所帮助,但我通过为每列指定特定宽度大小百分比来解决类似问题。显然,如果每列的宽度不会变化太大,这将最有效。

答案 12 :(得分:0)

你可以将右边单元格的宽度设置为所需宽度的最小值,然后将overflow-hidden + text-overflow应用到左边单元格的内部,但Firefox在这里有错误......

虽然,似乎,flexbox可以提供帮助

答案 13 :(得分:0)

我最近一直在努力。查看此jsFiddle test,自己尝试更改基表的宽度以检查行为。

解决方案是将表格嵌入到另一个表格中:

<table style="width: 200px;border:0;border-collapse:collapse">
    <tbody>
        <tr>
            <td style="width: 100%;">
                <table style="width: 100%;border:0;border-collapse:collapse">
                    <tbody>
                        <tr>
                            <td>
                                <div style="position: relative;overflow:hidden">
                                    <p>&nbsp;</p>
                                    <p style="overflow:hidden;text-overflow: ellipsis;position: absolute; top: 0pt; left: 0pt;width:100%">This cells has more content</p>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </td>
            <td style="white-space:nowrap">Less content here</td>
        </tr>
    </tbody>
</table>

弗雷德现在对Celldito的扩张感到满意吗?

答案 14 :(得分:0)

检查“nowrap”是否在一定程度上解决了问题。注意:HTML5不支持nowrap

<table border="1" style="width: 100%; white-space: nowrap; table-layout: fixed;">
<tr>
    <td style="overflow: hidden; text-overflow: ellipsis;" nowrap >This cells has more content  </td>
    <td style="overflow: hidden; text-overflow: ellipsis;" nowrap >Less content here has more content</td>
</tr>

答案 15 :(得分:-1)

我有同样的问题,但我需要显示多行(text-overflow: ellipsis;失败)。我使用textarea中的TD解决它,然后将其设置为表格单元格。

    textarea {
        margin: 0;
        padding: 0;
        width: 100%;
        border: none;
        resize: none;

        /* Remove blinking cursor (text caret) */
        color: transparent;
        display: inline-block;
        text-shadow: 0 0 0 black; /* text color is set to transparent so use text shadow to draw the text */
        &:focus {
            outline: none;
        }
    }

答案 16 :(得分:-1)

只需将以下规则添加到td

即可
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// These ones do the trick
width: 100%;
max-width: 0;

示例:

&#13;
&#13;
table {
  width: 100%
}

td {
  white-space: nowrap;
}

.td-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  max-width: 0;
}
&#13;
<table>
  <tr>
    <td>content</td>
    <td class="td-truncate">long contenttttttt ttttttttt ttttttttttttttttttttttt tttttttttttttttttttttt ttt tttt ttttt ttttttt tttttttttttt ttttttttttttttttttttttttt</td>
    <td>other content</td>
  </tr>
</table>
&#13;
&#13;
&#13;

<强> PS: 如果要将自定义宽度设置为另一个td使用属性min-width

答案 17 :(得分:-2)

鉴于'table-layout:fixed'是基本的布局要求,这会创建均匀间隔的不可调整列,但是您需要创建不同百分比宽度的单元格,或者将单元格的'colspan'设置为多个?

例如,使用总宽度100进行简单的百分比计算,并说您需要一个80%的单元格和20%的另一个单元格,请考虑:

<TABLE width=100% style="table-layout:fixed;white-space:nowrap;overflow:hidden;">
     <tr>
          <td colspan=100>
               text across entire width of table
          </td>
     <tr>
          <td colspan=80>
               text in lefthand bigger cell
          </td>
          <td colspan=20>
               text in righthand smaller cell
          </td>
</TABLE>

当然,对于80%和20%的列,您可以将100%宽度的单元格colspan设置为5,将80%设置为4,将20%设置为1。