是什么导致了这种折叠或扩展 CSS 过渡期间的跳转?



我知道有CSS/JS动画库可以做到这一点,但我正在学习CSS过渡,并希望用最小的JS完成。 (我非常喜欢CSS:)

我有几个与flex-grow: 1大小相同的弹性项目列。 我想单击列标题以缩小或扩展列,标题本身应保持可见(以便可以单击以展开(。 由于display不是可动画的 CSS 属性,因此我正在尝试在弹性项目内容(标题除外(的width: 0; opacity: 0;上进行 2 秒的过渡,在弹性项目本身上flex-grow: 0过渡。

我试图在崩溃结束时和扩展开始时消除不受欢迎的"跳跃"。

尽管持续时间相同并且可能同时触发(在单击时更改类之后(,但似乎弹性增长过渡与内容的宽度/不透明度过渡不同步,因此弹性增长过渡"过早"完成(在内容宽度为 0 之前(,然后在宽度过渡完成后跳转最后一位。 如果我使弹性增长过渡更长(比宽度过渡更长(并延迟它,则跳跃会减少。

我试图了解确切的交互以消除跳跃,而不会产生幻数黑客。

这是一个代码笔: https://codepen.io/richardkmichael/pen/abzYOjB

document.querySelectorAll(".collapsible").forEach(function(c) {
c.addEventListener("click", function(e) {
this.classList.toggle("collapsed");
});
c.addEventListener("transitionrun", function(e) {
this.classList.add("transitioning");
});
c.addEventListener("transitionend", function(e) {
this.classList.remove("transitioning");
// Set `display: none;` on contained div?
// Perhaps unnecessary, since `width: 0`?
});
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
p {
margin: 1rem;
}
.container {
outline: 1px solid blue;
padding: 1rem;
margin-bottom: 3rem;
display: flex;
}
.collapsible {
outline: 1px solid red;
text-align: center;

/* Lengthen transition and/or increase delay to remove jump. */
/* Permits width/opacity transition to complete? */
flex-grow: 1;
transition: flex-grow 2.5s 0.5s;
}
.collapsible.collapsed {
flex-grow: 0;
}
.collapsible div {
outline: 1px solid green;
opacity: 1;
width: 100%;
transition: opacity 2s, width 2s;
}
.collapsed div {
outline: 1px solid purple;
opacity: 0;
width: 0;
overflow: hidden;
white-space: nowrap;
}
.transitioning div {
/* Debugging. */
background: cyan;
/* Needed during transition to full-size. */
overflow: hidden;
white-space: nowrap;
}
<div class="container">

<div class="collapsible">
<h3>One</h3>
<div>This is item 1.</div>
</div>

<div class="collapsible">
<h3>Two</h3>
<div>This is item 2.</div>
</div>

</div>
<p>
The aim is to smoothly eliminate the column content, leaving only the header.
</p>
<p>
Click a column header ("One" or "Two") to collapse the column; click again to expand.</p>
<p>
What is causing the jump near the end of the collapse or expand transition?
</p>

如果它有助于传达目标,我的用例是周视图中的日历,其中天数(星期一等(是列。

我想这个问题是由于width:100%,更准确地说,使用百分率值创建了一个复杂的计算来解决它。

您可以尝试改为对max-width进行动画处理。唯一的缺点是,使用大值时,开始时会有延迟,但您可以调整过渡来纠正此问题:

document.querySelectorAll(".collapsible").forEach(function(c) {
c.addEventListener("click", function(e) {
this.classList.toggle("collapsed");
});
c.addEventListener("transitionrun", function(e) {
this.classList.add("transitioning");
});
c.addEventListener("transitionend", function(e) {
this.classList.remove("transitioning");
// Set `display: none;` on contained div?
// Perhaps unnecessary, since `width: 0`?
});
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
p {
margin: 1rem;
}
.container {
outline: 1px solid blue;
padding: 1rem;
margin-bottom: 3rem;
display: flex;
}
.collapsible {
outline: 1px solid red;
text-align: center;

/* Lengthen transition and/or increase delay to remove jump. */
/* Permits width/opacity transition to complete? */
flex-grow: 1;
transition: flex-grow 2.5s 0.5s;
}
.collapsible.collapsed {
flex-grow: 0;
}
.collapsible div {
outline: 1px solid green;
opacity: 1;
max-width: 100vw;
transition: opacity 2s, max-width 2s;
}
.collapsed div {
outline: 1px solid purple;
opacity: 0;
max-width: 0;
overflow: hidden;
white-space: nowrap;
}
.transitioning div {
/* Debugging. */
background: cyan;
/* Needed during transition to full-size. */
overflow: hidden;
white-space: nowrap;
}
<div class="container">

<div class="collapsible">
<h3>One</h3>
<div>This is item 1.</div>
</div>

<div class="collapsible">
<h3>Two</h3>
<div>This is item 2.</div>
</div>

</div>
<p>
The aim is to smoothly eliminate the column content, leaving only the header.
</p>
<p>
Click a column header ("One" or "Two") to collapse the column; click again to expand.</p>
<p>
What is causing the jump near the end of the collapse or expand transition?
</p>

简短的回答:

在您的 .collapseddiv(代码笔中的第 46 行左右(上更改:

width: 0

width: 0%

最新更新