过渡弹性增长与动态内容高度

时间:2016-01-23 21:05:20

标签: html css css3 flexbox

我正在显示一个项目列表。每个项目都有一个标题和一些内容。单击其标题时,每个项目的高度会展开/折叠。每个项目内容的高度都是动态的。

我有以下代码(如下所示)有效。但是,用户点击.header和转换开始之间会稍有延迟。

这种延迟似乎是由我使用max-height: min-content引入的。我相信在添加/删除.isCollapsed类后,浏览器需要花一点时间重新计算内容的高度。

我想知道是否有更正确的方法来实现这种效果?

如果我删除max-height: min-content,则flex: 1上的.item会导致展开时每个项目的高度相同。这是不希望的。我希望每个项目的高度都适合其内容。

我不想要一个需要我用JavaScript或类似方法测量文本的解决方案。目标是利用flexbox在不知道content的高度的情况下执行转换。

$('.header').click(function() {
  $(this).parent().toggleClass('isCollapsed');
});
*,
*::before,
*::after {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
  margin: 0;
}
ul,
li {
  list-style: none;
  margin: 0;
  padding: 0;
}
.items {
  display: flex;
  flex-direction: column;
  height: 100%;
  flex: 1;
}
.item {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 48px;
  transition: flex-grow 1s;
  flex: 1;
  max-height: min-content;
}
.header {
  display: flex;
  height: 48px;
  padding: 16px;
  align-items: center;
  flex-shrink: 0;
}
.isCollapsed {
  flex-grow: .001;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='items'>
  <li class='item'>
    <div class='header'>Item A Header</div>
    <div class='content'>Item A Content This content is</br>
      really</br>
      really</br>
      really</br>
      really</br>
      long.
    </div>
  </li>
  <li class='item'>
    <div class='header'>Item B Header</div>
    <div class='content'>
      Item B Content This content is</br>
      short.
    </div>
  </li>
</ul>

2 个答案:

答案 0 :(得分:2)

在下面的代码块中,有一些提高效率的空间。

.item {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 48px;
  transition: flex-grow 1s;
  flex: 1;
  max-height: min-content;
}

您正在使用min-heightflex。但是对于flex,您并不需要min-height

请改为尝试:

.item {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* min-height: 48px; */
  transition: flex-grow 1s;
  flex: 1 0 48px; /* adjusted */
  max-height: min-content;
}

延迟消失了。

DEMO

我还更正了<br>代码(</br>无效)。

答案 1 :(得分:0)

这是一个版本,对于不支持max-height的浏览器具有后备功能。

总是可以使用transition-durationcontent值来实现更平滑的过渡,但要使其完美,并假设min-content高度不是静态的,我(今天)不能在没有脚本的情况下看到这种情况。

我注意到在Chrome上使用max-height)的一个奇怪的事情是,$('.header').click(function() { $(this).parent().toggleClass('isCollapsed'); });版本没有*, *::before, *::after { box-sizing: border-box; } html, body { height: 100%; margin: 0; } ul, li { list-style: none; margin: 0; padding: 0; } .items { display: flex; flex-direction: column; height: 100%; flex: 1; } .item { display: flex; flex-direction: column; overflow: hidden; min-height: 48px; transition: max-height .5s; flex: 0 0 auto; max-height: 300px; } .header { display: flex; height: 48px; padding: 16px; align-items: center; flex-shrink: 0; } .isCollapsed { max-height: 48px; transition: max-height .2s; } @supports (max-height: min-content) { .item { max-height: min-content; transition: flex-grow .6s; flex: 1; } .isCollapsed { max-height: min-content; flex: .001; transition: flex-grow .3s; } }版本的可见过渡效果在速度上有所不同

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='items'>
  <li class='item'>
    <div class='header'>Item A Header</div>
    <div class='content'>Item A Content This content is<br>
      really<br>
      really<br>
      really<br>
      really<br>
      long.
    </div>
  </li>
  <li class='item'>
    <div class='header'>Item B Header</div>
    <div class='content'>
      Item B Content This content is<br>
      short.
    </div>
  </li>
  <li class='item'>
    <div class='header'>Item C Header</div>
    <div class='content'>Item C Content This content is<br>
      really<br>
      really<br>
      really<br>
      really<br>
      long.
    </div>
  </li>
</ul>
&#13;
{{1}}
&#13;
{{1}}
&#13;
&#13;
&#13;