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


222

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

一个单元格的内容更多且更宽,另一个单元格的内容更少且更窄

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

弗雷德(Fred)的公寓有个变大小的怪异习惯,因此他学会了隐藏自己的一些物品,以免将其他所有公寓推倒,从而使惠特福德太太的客厅变得li废:

现在,这些单元格的大小相同,但是只有一个单元格的内容被截断了,如果另一个单元格给出了一些空格,看起来它们都可以容纳。

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

这行得通,但是弗雷德有种that的感觉,如果他的右单元格(他的昵称为Celldito)放弃了一点空间,那么他的左单元格将不会被大部分时间截断。你能救他的理智吗?


总结:只有当所有单元格都放弃所有空格时,表格的单元格才能均匀溢出吗?


95
+1先生,很高兴地表征一个虚拟对象:)
Myles Gray

6
我怀疑您将不得不依靠JavaScript来解决此问题。
2011年

6
Lolz .. +1表示娱乐价值:) ...是否需要动态设置,还是不能简单地在每列上设置宽度?
战争

Answers:


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


9
啊。如此出色,但我不知道为什么,这让我很紧张:(
Shaun Rowan 2014年

谢谢!不能完全按照问题的意思进行操作(均匀截断所有列),但是这段代码的行为正是我想要的。
2015年

3
另外,请注意,您可以<col>通过在<td>样式之前添加宽度来消除s :jsfiddle.net/7CURQ/64
Sam Sam

2
实际上,这似乎破坏了非截断列的动态列大小。它们似乎总是缩小到最小宽度。
2015年

38

我相信我有一个非JavaScript解决方案!迟到总比不到好,对吧?毕竟,这是一个很好的问题,谷歌已经解决了。我不想解决JavaScript问题,因为我发现页面加载后发生的一些轻微抖动是不可接受的。

特点

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

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

经过测试并在以下环境中工作:IE8,IE9,IE10,Chrome,Firefox,Safari,Opera

结果图片

不错的比例宽度 不错的比例裁剪

JSFiddlehttp : //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;
}

3
如果您的内容是一个很长的单词,没有空格,则不起作用,但是您只需使用&shy;在间隔符中的内容中添加连字符即可。jsfiddle.net/zAeA2/160
Riccardo Casatta 2014年

2
这太棒了!我犯了使用ATTR,以避免重复的内容我自己的变种:jsfiddle.net/coemL8rf/2
Jayen

@Jayen Nice-也许使用title而不是data-spacer在鼠标悬停时获取工具提示:)
William George

@Jayen,我只是尝试了您的,似乎没有截断右侧的单元格,因此不符合单元格均匀溢出的要求。我正在使用Chrome46。– 2015
山姆

@Sam是的,没错。我的示例仅显示了可以在不重复内容的情况下制作两种类型的单元格。我没有试图回答这个问题,只是显示了另一种方式。如果您在我的示例中更改了HTML,则可以根据需要运行。
Jayen 2015年

24

几天前,我也面临着同样的挑战。看起来路西法·萨姆(Lucifer Sam) 找到了最好的解决方案。

但是我注意到您应该在spacer元素处重复内容。以为还算不错,但我也想title对剪切后的文本应用弹出窗口。这意味着长文本将在我的代码中第三次出现。

在这里,我建议title:after伪元素访问属性以生成间隔符并保持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/


不能同意,精彩!
Mikhail

比其他css解决方案好得多,因为它可以按两个顺序工作,即,如果内容较多的单元格位于内容较少的单元格之后。
buggedcom

19

如果可以接受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,它挂接了resize事件:

$(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);
        }
    });
});

18

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

在要应用截断的表单元中,只需包括一个带有div的容器div,该表具有css table-layout:已修复。该容器占用父表单元格的全部宽度,因此它甚至可以响应。

确保对表中的元素应用截断。

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个附加的块级元素才能实现非结构化效果。可以将一个表单元格设置为“ display:table”,这使您摆脱了div之一。jsfiddle.net/rza4hfcv不确定,对此我应该怎么想。但是,感谢您分享您的解决方案!
阿明2015年

该解决方案是否遇到任何问题?我正在考虑在专业环境中使用它。
阿明2015年

@armin,尝试复制要截断的单元格:不能同时放置多个。
DanielM

我不会说这是最终解决方案。您失去了表的主要好处之一:列根据其内容调整大小。如果这样设置每一列,则无论其内容的长度如何,所有列的宽度都相同。
DanielM

@DanielM您可以通过进一步嵌套表来扩展解决方案,就像在旧的表布局天中一样,但现在仅使用CSS。
阿明2015年

11

问题是“ table-layout:fixed”创建了固定宽度的固定宽度的列。但是禁用此css-property将杀死文本溢出,因为表将变得尽可能大(并且不存在溢出)。

对不起,但是在这种情况下,弗雷德不能拿蛋糕来吃。.除非房东一开始没有给Celldito足够的工作空间,否则弗雷德不能使用他的蛋糕。


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%宽度的列和white-spaceCSS属性的组合。

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

你明白了。


3

是的,我会说三十点有它,除非您使用js方法,否则没有办法。您正在谈论必须定义的一组复杂的渲染条件。例如,当两个单元格都变得太大而无法容纳时,您将不得不决定谁拥有优先级,或者只是给他们一定比例的区域,如果它们过满,它们都将占用该区域,并且只有一个空白时才会您在另一单元格中伸展双腿,无论哪种方式都无法通过css完成。尽管人们对CSS有一些非常时髦的事情,但我从未想到过。我真的怀疑您可以这样做。



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/


很好的解决方案!谢谢!
Valeriu92

:看着还不错,直到我的柔性电池之前添加静态细胞jsfiddle.net/7u59asyp/5
山姆

这是唯一一个对我有用的方法,尽管效果并不理想,因为我有4个列,其预期的内容大小有所不同
简写为

2

这个问题会在Google顶部弹出,因此在我的情况下,我使用了https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/中的css片段,但未将其应用于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; }

2

只需将以下规则添加到您的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: 如果要为另一个tduse属性设置自定义宽度min-width


问题是默认情况下,表列按比例消耗空间。如果一行的内容比另一行的内容长,它将分配更多的宽度。但是,此技术会平均划分空间。有没有解决的办法?
Malik Brahimi

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>


white-space: nowrapnowrap属性具有相同的效果(在示例中我正在使用它)。据我所知,在此处添加它不会改变任何内容。
2011年

0

您可以将右侧单元格的宽度设置为所需宽度的最小值,然后在左侧单元格的内部应用overflow-hidden + text-overflow,但是Firefox在此处存在问题。

虽然,看起来,flexbox可以提供帮助


0

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

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

<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的扩张感到满意吗?


抱歉,没有回复!我看不到它与单个表有何不同。当我在Chrome或Firefox中查看小提琴时,它看起来就像是问题中的第二个屏幕截图。我想念什么吗?
s4y 2012年

抱歉,该链接不是我发布的链接。实际上就是这个jsfiddle.net/VSZPV/2。更改两个单元格的文本和要测试的主表的宽度。希望这是您要寻找的东西...
IG Pascual,2012年

0

不知道这是否对任何人都有帮助,但是我通过为每一列指定特定的宽度大小(百分比)解决了类似的问题。显然,如果每个列的内容宽度都不太宽,这将是最好的。


-1

我遇到了同样的问题,但是我需要显示多行(text-overflow: ellipsis;失败的地方)。我使用一个textareainside来解决它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;
        }
    }

-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%的单元格colspan设置为4,将20%的列设置为1。


1
嘿@Siubear。与在tds 上指定百分比宽度有何不同?
s4y

以这种方式使用colspan是一个可怕的想法。为什么不使用宽度呢?
Percy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.