如何从未知值开始执行 Javascript/CSS3 动画?

How to perform Javascript/CSS3 animation starting from unknown value?

我有一个 <div> 页面加载时我不知道其高度。

如何让它在页面加载时滑入视图并固定在页面底部?

我希望这段代码能正常工作,但 div 只是直接跳入视图,没有流畅的动画。

var $warning = $('.bottom-warning');
var height = $warning.outerHeight();

/* Put div right below screen */
$warning.css('bottom', -height);

/* Make it visible */
$warning.css('display', 'inline-block');

/* Configure transition */
$warning.css('transition', 'bottom 400ms');

/* Apply new value */
/* SHOULDN'T VALUE BE ANIMATED? */
$warning.css('bottom', 0);

fiddle

如果最后一行稍后设置为 运行(使用 setTimeout),那么它可以工作,但我想避免这种情况,因为这是不好的做法。

要求:使用原生 CSS3 过渡或动画,无 Javascript 动画(包括 jQuery 动画)

如果您想获得 "slide in" 效果,从底部开始,您必须将默认 bottom 位置设置在屏幕外的某个位置,例如 -999em。否则,没有任何 "transition" 因为该元素没有要引用的起点。另外,给过渡一个时间量,例如bottom 1s.

$(function () {
    
    setTimeout(function () {
        var $warning = $('.bottom-warning');
        var height = $warning.outerHeight();
        
        /* Put div right below screen */
        $warning.css('bottom', -height);
        
        /* Make it visible */
        $warning.css('display', 'inline-block');
        
        /* Configure transition */
        $warning.css('transition', 'bottom 1s');
        
        /* Apply new value */
        /* SHOULDN'T VALUE BE ANIMATED? */
        $warning.css('bottom', 0);
    }, 500);
});
body, html {
    margin: 0;
    padding: 0;
}

.bottom-warning {
    background-color: lightblue;
    box-sizing: border-box;
    display: none;
    left: 0;
    bottom: -999em;
    padding: 20px;
    position: fixed;
    width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Lorem ipsum ipsum ipsum.
    <div class="bottom-warning">This site requires an HTML rendering engine!</div>

将元素翻译出页面,然后在 document.ready 上应用 class 将其恢复。

.bottom-warning {
    background-color: lightblue;
    box-sizing: border-box;
    left: 0;
    padding: 20px;
    position: fixed;
    width: 100%;
    bottom:0;
    height: auto;
    transform:translateY(100%);
    transition: transform .5s ease;

}

JSfiddle Demo

$(document).ready(function() {
  $('.bottom-warning').addClass('up');
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 20px;
  position: fixed;
  width: 100%;
  bottom: 0;
  height: auto;
  transform: translateY(100%);
  transition: transform .5s ease;
}
.bottom-warning.up {
  transform: translateY(0%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<body>Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

编辑

改用这个新的。

$(function() {

  setTimeout(function() {
    $(".bottom-warning").addClass("up");
  }, 500);
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 0 20px;
  position: fixed;
  width: 100%;
  bottom: -20px;
  transition: all 1s ease-in-out;
  -webkit-transition: all 1s ease-in-out;
  height: 0px;
  overflow: hidden;
}
.up {
  height: auto;
  padding: 20px;
  bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<body>
  Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

https://jsfiddle.net/wp3ndug6/2/

编辑结束

我认为您可能过于复杂了,抱歉,如果这不是正确的,但认为它是您想要的。

$(function() {

  setTimeout(function() {
    $(".bottom-warning").addClass("up");
  }, 500);
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 20px;
  position: fixed;
  width: 100%;
  bottom: -100%;
  transition: all 1s ease-in-out;
  -webkit-transition: all 1s ease-in-out;
}
.up {
  bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<body>
  Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

https://jsfiddle.net/wp3ndug6/1/

由于您已经在使用 JQuery 为您的 css 制作动画,我建议查找动画。它提供了流畅的滑动动画,您可以指定动画的速度。 http://api.jquery.com/animate/

$warning.animate({
      bottom: "0px"
    }, 400);

如果您有 display: none,当设置 display: inline-block(或 display: block 无关紧要)时,您的转换将不起作用。您可以使用 setTimeout(fn, 0) hack — https://jsfiddle.net/sergdenisov/up430ww3/2/.

var $warning = $('.bottom-warning');
var height = $warning.outerHeight();

$warning.css('bottom', -height);
$warning.css('display', 'inline-block');

setTimeout(function() {
    $warning.css('bottom', 0);
}, 0);

关于 setTimeout(fn, 0)Why is setTimeout(fn, 0) sometimes useful?.

我明白了为什么没有发生转换。

似乎浏览器在顺序设置动画属性时会跳过过渡。 要解决此问题,我们必须强制重绘,如 http://blog.alexmaccaw.com/css-transitions 中所述(向下滚动到 "Redraw" 部分)

因此,例如,添加:

var redraw = $warning[0].offsetHeight;

...就在设置 属性 之前,似乎一切都按预期方式工作。

fiddle

非常感谢 Alex MacCaw 的精彩文章!