Fluid table:在需要时截断单元格内容,否则保持 table 尽可能窄

Fluid table: Truncate cell contents when needed, otherwise keep the table as narrow as possible

我在响应式页面 (Bootstrap) 上有一个 HTML 5 table 三行四列(每行两个 attribute/value 对)。

在桌面视图(或内容很少)中,我希望 table 而不是 填充整个可用宽度,刚好足以显示数据。列应该有单独的宽度,刚好足以显示它们的内容。换句话说,如果可能的话,我希望 space 位于 table 的右侧。

在移动视图(或有很多内容)中,我希望单元格内容被截断(例如使用 text-overflow: ellipsis;),而不是换行。如果可能,我希望属性列首先截断到预设的最小值。如果不能优雅地解决,没有优先级也可以。

期望的结果:

我已经浏览 Stack Overflow 等几个小时,我找到的大多数解决方案(例如 1, 2, 3)都要求设置 table 的宽度,通常为 100%,即不符合我的目的。我看到有人提到将 div 元素放在 td 元素中,但没有示例,我自己也无法弄清楚。

我不必使用 table 来解决这个问题,因此欢迎使用其他解决方案。

尝试将 div 放入 td 并使用 Chris Coyier's truncate。此外,将截断容器的 width 设置为 100% 以根据可用 space 而不是固定宽度进行截断。

好的,我找到了解决办法。 Fiddle here.

策略:

使用隐藏 table 收集可见 table 的所需单元格宽度。

战术:

除了用户应该看到的 table 之外,必须在可见 table 的正上方创建具有相同内容的隐藏 "shadow" table。

阴影 table 必须允许内容包裹在单元格内(这是默认 table 行为)。

页面加载后,每次 window 调整大小时,show() 阴影 table,测量顶部每个 tdwidth行,然后 hide() 影子 table。然后将 width 值复制到可见 table 中相应的 td 元素,其中必须应用 Chris Coyier's truncate

适用于我测试过的所有浏览器,包括移动设备。

奖金提示:

  • 如有必要,使用 ­ 将长词换行,并使用   停止换行。这只能应用于阴影 table.
  • 由于 Internet Explorer 中的错误,在阴影 table 中使用 1px 更多的单元格填充 - 否则,IE 的可见 table 有时会比阴影 table.

JavaScript(要求jQuery):

<script type="text/javascript">

function loadEvents() {
  initFluidTables();
}

// Resize fluid table(s)
function resizeFluidTables() {

  // Show source cells
  $( ".fluid-table-invisible-source" ).show(0);

  var fluidTableCellWidth = [];

  // Measure (normally invisible) source cells
  $( ".fluid-table-invisible-source td" ).each(function( index, value ) {
    fluidTableCellWidth[index] = $( this ).width();
  });

  // Resize (always visible) target cells. Adding 1 pixel due to apparent bug in Firefox.
  $( ".fluid-table-visible-target td>i" ).each(function( index, value ) {
    $( this ).css({'width': fluidTableCellWidth[index]+1 });
  });

  // Re-hide source cells
  $( ".fluid-table-invisible-source" ).hide();

}

// Create table(s) to be fluid
function initFluidTables() {

  // Create a container. Not really necessary, but keeps DOM tidier.
  $(".fluid-table").wrap( "<div></div>" );

  // This looks like a mess. What it does, is that .fluid-table duplicates itself, and each sibling gets a different class.
  $(".fluid-table").each(function() {
    $( this ).clone().appendTo( $( this ).addClass( "fluid-table-invisible-source" ).parent() ).addClass( "fluid-table-visible-target" );
  });

  // Add truncating element inside target cells
  $(".fluid-table-visible-target td").wrapInner( "<i></i>");

  // Truncate table contents at first drawing of the DOM and every time the window resizes
  resizeFluidTables();
  $( window ).resize(function() {
    resizeFluidTables();
  });
}
</script>

CSS:

.fluid-table td { padding-right: 5px; }

.fluid-table td:nth-child(odd) { color: #aaa; }

.fluid-table-visible-target td>i {
  font-style: inherit;
  white-space: nowrap;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* source slighly more padded than target due to IE bug */

.fluid-table-invisible-source td:nth-child(even) {
  padding-right: 10px;
}

.fluid-table-visible-target td:nth-child(even) {
  padding-right: 9px;
}

样本table:

请注意使用 &shy;&nbsp; 来指示您(不)希望文本截断的位置。

<table class="fluid-table">
  <tr>
    <td>Avail&shy;able <i>until</i>:</td><td>No&nbsp;expiry date</td><td>Avail&shy;ability:</td><td>Worldwide</td><td></td>
  </tr><tr>
    <td>Year:</td><td>2016</td><td>Length:</td><td>29&nbsp;minutes</td><td></td>
  </tr><tr>
    <td>First broad&shy;cast:</td><td>Feb&nbsp;2</td><td>Last broad&shy;cast:</td><td>Feb&nbsp;3</td><td></td>
  </tr>
</table>