我 http://semisignal.com/?p=5298 读这篇文章,作者写道
"需要在删除不可见类之前触发回流,以便转换按预期工作。
我的问题是:
1) 为什么需要触发回流焊?
2)我知道我们应该避免使用回流,如果这是真的,为什么作者建议使用回流以使过渡工作?
3)除了使用回流焊,是否有不同的方法可以使过渡工作?
谢谢。
(有效:"为什么我不能轻松地将过渡与display
属性一起使用")
简答:
CSS 过渡依赖于元素的起始属性或静态属性。当元素设置为display: none;
文档 (DOM) 时,将呈现为该元素不存在。这意味着当它设置为display: block;
- 没有要转换的起始值。
更长的答案:
- 需要触发重排,因为设置为
display: none;
的元素尚未在文档中绘制。这可以防止转换具有起始值/初始状态。将元素设置为display: none;
会使文档呈现,就好像该元素根本不存在一样。 - 他建议重排,因为通常接受隐藏和显示具有
display: none;
和display: block;
元素 - 通常在操作(选项卡或按钮单击,回调函数,超时函数等)请求元素之后。转换是 UX的巨大好处,因此重排是允许这些转换发生的一种相对简单的方法。当您在简单站点上使用简单过渡时,它不会产生巨大影响,因此出于一般目的,您可以触发重排,即使从技术上讲您不应该这样做。想想这个家伙的例子,就像在生产站点中使用未缩小的JavaScript文件一样。可以吗?确定!你应该吗?可能不是,但在大多数情况下,它不会产生非常明显的差异。 - 有不同的选项可以防止重排,或者通常比您提供的链接中的方法更易于使用。以以下代码片段为例:
答:此元素设置为height: 0;
和overflow: hidden;
。显示时,它设置为height: auto;
。我们仅将动画应用于opacity
.这给了我们类似的效果,但我们可以在没有重排的情况下转换它,因为它已经在文档中呈现并给出了要使用的过渡初始值。
B:此元素与 A 相同,但将高度设置为定义的大小。
A 和 B 在元素中淡入淡出的效果很好,但由于我们将高度从auto/100px
立即设置为0
,因此它们似乎在"淡出"时折叠
C:这个元素是隐藏的,我们试图转换孩子。您可以看到这也不起作用,需要触发重排。
D:这个元素是隐藏的,我们给孩子做动画。由于动画关键帧给出了定义的起始值和结束值,因此效果要好得多。但请注意,黑框会捕捉到视图中,因为它仍附加到父级。
E:这类似于D,但我们把所有东西都从孩子身上跑掉,这并不能解决我们在D上遇到的"黑匣子"问题。
F:这可能是两全其美的解决方案。我们将样式从父级移到孩子身上。我们可以触发父级的动画,我们可以控制子项的display
属性并根据需要animate
过渡。这样做的缺点是您需要使用动画关键帧而不是过渡。
G:虽然我不知道这是否触发了函数内部的回流,因为我自己还没有解析过它,但你可以简单地使用 jQuery 的.fadeToggle()
函数用一行 JavaScript 来完成所有这些,并且经常使用(或类似的 JS/jQuery fadeIn/fadeOut 方法),以至于重排的主题并不经常出现。
例子:
这是一个代码笔:https://codepen.io/xhynk/pen/gerPKq
下面是一个片段:
jQuery(document).ready(function($){
$('button:not(#g)').click(function(){
$(this).next('div').toggleClass('show');
});
$('#g').click(function(){
$(this).next('div').stop().fadeToggle(2000);
});
});
* { box-sizing: border-box; }
button {
text-align: center;
width: 400px;
}
div {
margin-top: 20px;
background: #000;
color: #fff;
}
.a,
.b {
overflow: hidden;
height: 0;
opacity: 0;
transition: opacity 3s;
}
.a.show {
height: auto;
opacity: 1;
}
.b.show {
height: 100px;
opacity: 1;
}
.c,
.d {
display: none;
}
.c.show,
.d.show {
display: block;
}
.c div {
opacity: 0;
transition: 3s all;
}
.c.show div {
opacity: 1;
}
.d div {
opacity: 0;
}
.d.show div {
animation: fade 3s;
}
@keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
.e div {
display: none;
}
.e.show div {
display: block;
animation: fade 3s;
}
.f {
background: transparent;
}
.f div {
background: #000;
display: none;
}
.f.show div {
display: block;
animation: fade 3s;
}
.g {
display: none;
}
<button id="a">A: Box Height: Auto</button>
<div class="a">This<br/>Has<br/>Some Strange<br/><br/>Content<br>But<br>That doesn't really<br>Matter<br/>Because shown,<br/>I'll be<br/>AUTO</div>
<button id="b">B: Box Height: 100px</button>
<div class="b">Content For 2</div>
<button id="c">C: Hidden - Child Transitions (bad)</button>
<div class="c"><div>Content<br/>For<br/>3<br/></div></div>
<div style="clear: both;"></div>
<button id="d">D: Hidden - Child Animates (Better)</button>
<div class="d"><div>Content<br/>For<br/>4<br/></div></div>
<div style="clear: both;"></div>
<button id="e">E: Hidden - Child Hidden & Animates</button>
<div class="e"><div>Content<br/>For<br/>5<br/></div></div>
<button id="f">F: Child Has BG & Animates (Works)</button>
<div class="f"><div>Content<br/>For<br/>5<br/></div></div>
<div style="clear: both;"></div>
<button id="g">G: This uses fadeToggle to avoid this</button>
<div class="g">I animate with<br/>JavaScript</div>
<footer>I'm just the footer to show the bottom of the document.</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>