如何截断表格单元格,但要尽可能多地容纳内容?

Posted

技术标签:

【中文标题】如何截断表格单元格,但要尽可能多地容纳内容?【英文标题】:How can I truncate table cells, but fit as much as content possible? 【发布时间】:2011-07-11 12:26:14 【问题描述】:

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

<table border="1" style="width: 100%;">
    <tr>
        <td>This cells has more content</td>
        <td>Less content here</td>
    </tr>
</table>

Fred 的公寓有一个奇怪的改变大小的习惯,所以他学会了隐藏他的一些内容,以免将所有其他单元推倒并把 Whitford 夫人的客厅推到遗忘:

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

这行得通,但 Fred 有一种挥之不去的感觉,即如果他的右单元格(他的昵称 Celldito)放弃一点空间,他的左单元格在很多时候都不会被截断。你能拯救他的理智吗?


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

【问题讨论】:

我怀疑你必须求助于 javascript 来解决这个问题。 Lolz .. +1 娱乐价值 :) ... 这需要是动态的还是你不能简单地在每列上设置一个宽度? 【参考方案1】:
<table border="1" style="width: 100%;">
    <colgroup>
        <col  />
        <col  />
    </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/

【讨论】:

呃。效果很好,但我不知道为什么,这让我很紧张:( 谢谢!不完全按照问题所说的去做(均匀地截断所有列),但是 this 代码的行为正是我想要的。 另外,请注意,您可以通过在 &lt;td&gt; 样式前添加宽度来消除 &lt;col&gt;s:jsfiddle.net/7CURQ/64 实际上,这似乎破坏了非截断列的动态列大小。它们似乎总是缩小到最小宽度。 为什么需要 max-width:1px 值?我可以看到没有它就无法工作,但不知道为什么。【参考方案2】:

我相信我有一个非 JavaScript 解决方案!我不想满足于 JavaScript 修复,因为我发现页面加载后移动的轻微抖动是不可接受的。

特点

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

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

经过测试和工作:IE8、IE9、IE10、Chrome、Firefox、Safari、Opera

结果图片

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;

【讨论】:

如果您的内容是一个没有空格的很长的单词,这不起作用,但您只需使用 ­ 将连字符添加到分隔符中的内容。 jsfiddle.net/zAeA2/160 这太棒了!我使用 attr 制作了自己的变体以避免重复内容:jsfiddle.net/coemL8rf/2 @Jayen Nice - 也许使用 title 而不是 data-spacer 来获得鼠标悬停的工具提示 :) @Jayen,我刚试过你的,它似乎没有截断右侧的单元格,所以它不符合单元格均匀溢出的要求。我正在使用 Chrome 46。 @Sam 是的,没错。我的示例仅表明可以在不复制内容的情况下制作这两种类型的单元格。我不是想回答这个问题,只是展示另一种方式。如果您在我的示例中更改 html,它会按您的意愿工作。【参考方案3】:

几天前我也面临同样的挑战。看来Lucifer Samfound 是最好的解决方案。

但我注意到您应该在间隔元素处复制内容。认为这还不错,但我还想将title 弹出窗口应用于剪辑文本。这意味着长文本将第三次出现在我的代码中。

这里我建议从:after 伪元素中访问title 属性来生成分隔符并保持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/

【讨论】:

比其他 css 解决方案要好得多,因为它可以按两种顺序工作,即内容越多的单元格在内容越少的单元格之后。 另一个好的副作用是它可以与-webkit-line-clamp 结合使用以实现多行截断(如果需要并且不需要支持 IE)。 jsfiddle.net/katdLfe5【参考方案4】:

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

在要应用截断的表格单元格中,只需包含一个带有 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/

【讨论】:

此解决方案需要 2 个额外的块级元素来实现非结构效果。可以将一个表格单元格设置为“显示:表格”,这样您就可以摆脱其中一个 div。 jsfiddle.net/rza4hfcv 不确定,我应该怎么想。但是感谢您分享您的解决方案! 您在使用该解决方案时遇到过任何问题吗?我正在考虑在专业环境中使用它。 @armin,尝试复制您要截断的单元格:您不能并排放置多个。 我不会说这是最终解决方案。您失去了表格的主要好处之一:列根据其内容调整大小。如果你像这样设置每一列,无论其内容的长度如何,它们都将具有相同的宽度。 @DanielM 您可以通过进一步嵌套表格来扩展解决方案 - 就像在旧的表格布局天中一样 - 但现在只使用 css。【参考方案5】:

只需将以下规则添加到您的td

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

例子:

table 
  width: 100%


td 
  white-space: nowrap;


.td-truncate 
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  max-width: 0;
<table border="1">
  <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>

PS: 如果您想将自定义宽度设置为另一个td,请使用属性min-width

【讨论】:

这样做的问题是,默认情况下,表列会按比例消耗空间。如果一行的内容比另一行的内容长,它将分配更多的宽度。但是,这种技术均匀地划分了空间。有解决办法吗? 据我所知,没有。可悲的是,HTML 表格的设计真的很糟糕☹️。【参考方案6】:

如果 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);
        
    );
);

【讨论】:

【参考方案7】:

问题是“table-layout:fixed”创建了均匀间隔固定宽度的列。但是禁用这个 css 属性会杀死文本溢出,因为表格会变得尽可能大(并且不会溢出)。

很抱歉,但在这种情况下,Fred 不能把蛋糕吃完……除非房东一开始就给 Celldito 更少的工作空间,否则 Fred 不能使用他的……

【讨论】:

【参考方案8】:

您可以尝试“加权”某些列,如下所示:

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

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

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

你明白了。

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

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

要使用插件,只需键入

$('selector').tableoverflow();

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

编辑:

修复 jsfiddle 以实现 IE 兼容性。 修复 jsfiddle 以获得更好的浏览器兼容性(Chrome、Firefox、IE8+)。

【讨论】:

【参考方案11】:

使用一些 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/

【讨论】:

看起来不错,直到我在灵活单元格之前添加了一个静态单元格:jsfiddle.net/7u59asyp/5 这是唯一对我有用的,虽然不是很完美,因为我有 4 列,预期内容大小不同【参考方案12】:

这个问题在谷歌中弹出顶部,所以在我的例子中,我使用了 css sn-p 来自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; 

【讨论】:

【参考方案13】:

检查“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>

【讨论】:

white-space: nowrapnowrap 属性具有相同的效果(我在示例中使用它)。据我所知,在此处添加它并没有改变任何东西。【参考方案14】:
<table style="table-layout: fixed; max-width: 100%;">
    <tr>
        <td>
             <div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">This cells has more content</div>
        </td>
        <td>Less content here</td>
    </tr>
</table>

【讨论】:

没有解释的源代码不能作为答案。请说明您推荐此源代码的原因。【参考方案15】:

您可以将右侧单元格的宽度设置为所需宽度的最小值,然后将溢出隐藏+文本溢出应用到左侧单元格的内部,但是 Firefox 在这里有错误...

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

【讨论】:

【参考方案16】:

我最近一直在研究它。看看这个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>

Fred 现在对 Celldito 的扩张感到满意吗?

【讨论】:

抱歉没有回复!我看不出这与单个表的行为有何不同。当我在 Chrome 或 Firefox 中查看小提琴时,它看起来与问题中的第二个屏幕截图完全相同。我错过了什么吗? 抱歉,链接不是我发布的。其实就是这个jsfiddle.net/VSZPV/2。更改两个单元格的文本和要测试的主表的宽度。希望这就是你要找的东西......【参考方案17】:

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

【讨论】:

【参考方案18】:

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

    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;
        
    

【讨论】:

【参考方案19】:

鉴于 '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。

【讨论】:

嘿@Siubear。这与在tds 上指定百分比宽度有什么不同? 以这种方式使用 colspan 是一个可怕的想法。为什么不使用宽度呢?

以上是关于如何截断表格单元格,但要尽可能多地容纳内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何使表格视图单元格的大小动态变化?

自定义表格单元格未调整大小以适合内容视图

如何使用 iText 剪辑 PdfPTable 中的单元格?

数据表 - 单元格字符串截断

如何在表格视图中显示表格单元格的详细视图?

为啥在 iOS 中显示为 PDF 时,具有居中文本的底部表格单元格会被截断?