如何使 table 单元格内的 div 跟随单元格的宽度?

How do I make a div inside a table cell follow the cell's width?

我有一个 table 这样的:

<table style="width: 100%;">
  <tr>
    <td>
      Title 1
    </td>
    <td>
      Stuff
    </td>
  </tr>
  <tr>
    <td>
      Title 2
    </td>
    <td>
      More stuff
    </td>
  </tr>
</table>

此 table 中的列会根据需要和可用 space 自行调整。我现在想在标题下加个副标题,太长就截断:

<table style="width: 100%;">
  <tr>
    <td>
      <div>Title 1</div>
      <div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
        Subtitle that might be long
      </div>
    </td>
    <td>
      Stuff
    </td>
  </tr>
  <tr>
    <td>
      <div>Title 2</div>
      <div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
        Subtitle that might be long
      </div>
    </td>
    <td>
      More stuff
    </td>
  </tr>
</table>

table 现在将根据字幕的宽度调整列的大小,因此它可以显示尽可能多的字幕。我不想要这个,我希望字幕 div 基本上“跟随”其周围环境的大小,并以它最终达到的任何宽度呈现。

有没有简单、通用的方法来完成这种事情?

我已经尝试过替代方案,例如根据视口显式设置宽度,但它总是会导致奇怪的行为,因为页面上还有其他响应元素使 table 变量的大小与视口相比.所以这些解决方案是次优的,理想情况下我只想在宽度计算期间忽略 div 并只获得单元格最终的宽度。

如果您希望某些元素重排其周围的其他内容,那么您需要将该元素中移除normal document flow.

一种方法是通过 positioning 通过 position: absolute 元素。请注意,您当然需要创建一个显式的“space”才能使它存在,因为根据设计我们说这个字幕不流畅所以它不会自己创建 space!

请注意,这也有缺点,我们为其创建的 space 是 固定的。 在您的示例中,您提到希望字幕变为 标题下,所以这就对标题做了一个假设,即标题有多高(有多少行)。对于此示例,它假定标题为 1 行,或 1em 的垂直 space。如果这限制太多,您需要调整布局,或使用 javascript 动态设置元素的定位。我不建议这样做。

table {
  width: 100%;
}

td {
  position: relative;
}

.title {
  /* Create 1 line of space for subtitle below */
  margin-bottom: 1em;
}

.subtitle {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  
  position: absolute;
  
  top: 1em;
  left: 0;
  width: 100%;
  height: 100%;
}
<table border="1">
  <tr>
    <td>
      <div class="title">Title 1</div>
      <div class="subtitle">
        Subtitle that might be long. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
    </td>
    <td>
      Stuff
    </td>
  </tr>
  <tr>
    <td>
      <div class="title">Title 2</div>
      <div class="subtitle">
        Subtitle short
      </div>
    </td>
    <td>
      More stuff
    </td>
  </tr>
</table>

<hr>

<table border="1">
  <tr>
    <td>
      <div class="title">Title 1</div>
      <div class="subtitle">
        Subtitle that might be long. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
    </td>
    <td>
      Stuff
    </td>
    <td>
      Extra Stuff
    </td>
  </tr>
  <tr>
    <td>
      <div class="title">Title 2</div>
      <div class="subtitle">
        Subtitle that might be long
      </div>
    </td>
    <td>
      More stuff
    </td>
    <td>
      Lots more stuff
    </td>
  </tr>
</table>