我可以将 CSS 转换应用于溢出 属性 吗?

Can I apply a CSS transition to the overflow property?

我正在尝试通过添加 [=36] 单击 divtransition-delay 设置为 bodyoverflow 属性 =] 到 body 如下:

$("div").click(function(){
    $("body").addClass("no_overflow");
});
div{
  background:lime;
  height:2000px;
}
.no_overflow{  
 overflow:hidden;
}
body{  
  overflow:auto;
  transition: overflow 0 2s;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>I'm div</div>

但是,这似乎不起作用(没有延迟)。我在这里做错了什么吗?

我知道这可以通过使用 setTimeout 函数来实现,但想知道为什么不能使用 css 转换来实现?是否有任何特定的样式属性可以应用 css 转换?

有许多属性无法转换。 overflow在其中;渲染引擎不知道如何在 "hidden" 和 "shown" 之间转换,因为它们是二元选项,而不是间隔。这就是为什么你不能在 display: none;display: block; 之间转换的原因(例如):没有中间阶段可以用作转换。

您可以在 Mozilla 开发者网络上看到可以设置动画的属性列表 here

溢出 不是 CSS 动画 属性。您可以查看动画 CSS 属性的完整列表 there.

你不能在二进制属性之间转换是有道理的,例如 overflow: hidden;overflow: visible 但如果不是 "transitioning" 那么它会非常好(在js伪代码中:

setTimeout("applyOverflowVisible()", transitionTime);

但是您当然可以在 JavaScript 中自己执行此操作,但是您会在多个地方之间拆分代码,这会使其他人难以理解。我想使用 React 之类的东西会有所帮助,但即使在那里我也想避免将 css 混入 js.

您可以使用 animation 模拟延迟:

$("div").click(function() {
  $("body").addClass("no_overflow");
});
div {
  background: lime;
  height: 2000px;
}

.no_overflow {
  overflow: hidden;
  /* persist overflow value from animation */
  animation: 7s delay-overflow;
}

body {
  overflow: auto;
}

@keyframes delay-overflow {
  from { overflow: auto; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>I'm div</div>

如果您想延迟 removeClass,则必须对 .body 应用单独的动画,并且还要注意两个动画不会重叠,否则它们会相互抵消。

如果有人像我一样正在查看答案,寻找一种动画元素裁剪的方法,需要溢出 - 这是对我有用的解决方案:可动画的 clip-path css property而且用途广泛。

这是一个很酷的工具,可以用来获取动画的正确开始/结束值:https://bennettfeely.com/clippy/

Dmitry 的答案应该是唯一被接受的答案,因为它是一个纯粹的 CSS 解决方案,将延迟应用于“非动画”属性。但是值得一提的是,应用动画的 CSS 规则应该在每次需要时“触发”。

例如,以下代码不起作用:

@keyframes show-overflow {
  from { overflow: hidden; }
}
.hideable, .overlay {
  font-size: 36px;
  height: 50px;
}
.hideable {
  transition: height 2s;
  overflow: visible;
  animation: show-overflow 2s;  /* this line should be in separate  "triggerable" CSS rule to work */
}
.hideable.hidden {
  height: 0;
  overflow: hidden;
}
<button onclick="document.getElementById('hideable').classList.toggle('hidden')">
  Clik HERE to hide/show the text below
</button>
<div id='hideable' class='hideable'>
  This is the text to hide and show.  
</div>
<div class='overlay'>
  This is overlaying text
</div>

但是在将标记的 属性 移动到单独的 CSS 规则后,一切都按预期进行:

@keyframes show-overflow {
  from { overflow: hidden; }
}
.hideable, .overlay {
  font-size: 36px;
  height: 50px;
}
.hideable {
  transition: height 2s;
  overflow: visible;
}
.hideable:not(.hidden) {
  animation: show-overflow 2s;  /* now this works! */
}
.hideable.hidden {
  height: 0;
  overflow: hidden;
}
<button onclick="document.getElementById('hideable').classList.toggle('hidden')">
  Clik HERE to hide/show the text below
</button>
<div id='hideable' class='hideable'>
  This is the text to hide and show.  
</div>
<div class='overlay'>
  This is overlaying text
</div>