【发布时间】:2016-04-30 08:39:03
【问题描述】:
我正在显示一个项目列表。每个项目都有一个标题和一些内容。单击其标题时,每个项目的高度都会展开/折叠。每个项目内容的高度是动态的。
我有以下有效的代码(见下文)。但是,在用户单击 .header 和过渡开始之间会有一点延迟。
这种延迟似乎是由于我使用max-height: min-content 而引起的。我相信在添加/删除.isCollapsed 类之后,浏览器需要一点时间来重新计算内容的高度。
不知道有没有更正确的方法可以达到这个效果?
如果我删除max-height: min-content,那么.item 上的flex: 1 会导致每个项目在展开时具有相同的高度。这是不希望的。我希望每个项目的高度适合其内容。
我不想要需要我用 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>
【问题讨论】:
-
这根本没有回答我的问题。您可以从我的示例代码中看到,我为 flex-grow 指定了 0.001 的值,并且它在我提供的示例中成功地设置了动画。请阅读问题。
-
用户交互和动画之间存在延迟。如果我删除
max-height: min-content延迟消失,但每个项目的高度变得太大/不受其内容的限制。 -
是的...不确定这里是否有使用 flexbox 的答案。正如您所建议的,延迟是由浏览器进行数学运算引起的。
-
我查看了 Bootstrap 如何进行折叠菜单,看起来他们在 JS 中测量文本,设置高度、过渡,然后删除固定高度。你知道这是否是目前实现这种效果的唯一可行方法吗?我认为 Bootstrap 的解决方案可能只是针对较旧的浏览器支持。我找不到太多关于严格针对常青浏览器执行此操作的信息。
-
这里最好的技巧是将它的最大高度转换为一个总是大于内容的值,并使用缓出,使它看起来最好。