如何为表格行切换添加动画效果?

23
我想要为表格行的出现和消失添加动画效果。
首先,我尝试使用 CSS 的 transition 属性,但由于 display 属性的变化,它没有任何效果。
所以我使用了 animation 属性,这也达到了预期的效果。
问题是,在动画开始时会保留行的完整高度。在下面的代码片段中可以看到这个问题的演示:第三行直接向下推移,而动画还没有开始。
如何逐步地动画化行的高度,使其只占用必要的空间呢?
额外的要求是:
- 不需要为行设置固定高度; - 应该看起来像一个翻译,而不是缩放;它应该从上面的行“滑落”; - 它应该是双向的(隐藏时反向进行)。
代码片段如下:
$('button').on('click', function() {
  $('tr:nth-child(2)').toggleClass('active');
});
@keyframes anim {
  0% {
    transform: scaleY(0);
  }
  100% {
    transform: scaleY(1);
  }
}
tr {
  background: #eee;
  border-bottom: 1px solid #ddd;
  display: none;
  transform-origin: top;
}
tr.active {
  display: table-row;
  animation: anim 0.5s ease;
}
td {
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<button type="button">Toggle</button>
<table>
  <tbody>
    <tr class="active">
      <td>Row 1</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <td>Row 2</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr class="active">
      <td>Row 3</td>
      <td>...</td>
      <td>...</td>
    </tr>
  </tbody>
</table>


我的回答有帮到你吗?如果没有,我还能改进或者澄清什么吗? - Asons
@LGSon 抱歉没有早点给你反馈,我一直在等待看看其他人是否会提出替代方案。我将直接在你的答案上写下我的评论。 - BenMorel
可能是使用高度属性在表格行上进行CSS3过渡的重复问题。 - Ronnie Royston
2个回答

35

由于tablerow/cell不会遵守比其内容更小的height,因此我们需要使用内部的div。我们无法动画显示并且无法动画设置为autoheight,因此我在这里展示了一种使用max-height的解决方案。

诀窍是给max-height一个足够高的值以启用最高的内容。

$('button').on('click', function() {
  $('tr:nth-child(2)').toggleClass('active');
});
table {
  border-collapse: collapse;
}
tr {
  background: #eee;
  border-bottom: 1px solid #fff;
}
tr, td {
  padding: 0;
}
tr td div {
  max-height: 0;
  padding: 0 10px;
  box-sizing: border-box;
  overflow: hidden;
  transition: max-height 0.3s, padding 0.3s;
}
tr.active td div {
  max-height: 100px;
  padding: 10px 10px;
  transition: max-height 0.6s, padding 0.6s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<button type="button">Toggle</button>
<table>
  <tbody>
    <tr class="active">
      <td><div>Row 1</div></td>
      <td><div>...</div></td>
      <td><div>...</div></td>
    </tr>
    <tr>
      <td><div>Row 2</div></td>
      <td><div>...</div></td>
      <td><div>...</div></td>
    </tr>
    <tr class="active">
      <td><div>Row 3</div></td>
      <td><div>...</div></td>
      <td><div>...</div></td>
    </tr>
  </tbody>
</table>


2
这比我想出来的更好,所以谢谢你。我只看到两个小问题仍然可以改进:一是它没有使用display来完全隐藏它(不确定这有多重要,但我担心旧浏览器和语义:使用height:0来隐藏元素可能不是最佳实践);二是它缩小了,而不是像从上面的行底部滑动一样,这是我的理想目标! - BenMorel
@Benjamin 关于旧版浏览器,如果你使用 transition,它们已经被淘汰了。如果能在 tr 上设置 height: 0,那么“滑动”下来的理想目标就可以实现,但是这并不起作用,所以如果你想要这个效果,你需要放弃 table 标记,改用 div 行,如果你可以接受每列固定宽度(因为它们不会像普通单元格一样表现),那么这个效果可以实现。 - Asons
不使用表格从语义上讲并不是一个真正的解决方案,因为它确实是表格数据。至于旧版浏览器,在没有过渡效果的情况下,它们仍然可以正确地显示和隐藏,所以没问题! - BenMorel
2
@Benjamin 遇到了类似的问题。还没有到时间吗?给那个人的答案一些爱心吧 :D - MrVocabulary
1
我想我从未接受它,因为我从未真正满意结果,特别是它缩小而不是滑动的事实。但是如果我坚持使用表格,似乎没有更好的解决方案,所以让我们这样做。接受! - BenMorel
显示剩余8条评论

1
如果您可以选择使用CSS3 / 支持现代浏览器,您可以考虑使用transform:translateY转换并使用overflow:hidden隐藏溢出内容。
请注意,Edge / IE不支持表元素上的转换变换。Chrome支持它。

6
谢谢,你能提供一个演示这个的示例代码吗? - BenMorel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接