【问题标题】:CSS Opacity transition with display: none带显示的 CSS 不透明度过渡:无
【发布时间】:2021-01-08 01:06:03
【问题描述】:

我有一个菜单,我想用 javascript 淡入。我希望它从display: noneopacity: 0 过渡到display: flexopacity: 1。但是当我使用 javascript 将 opacity 设置为 1 时,它不会转换,而是突然捕捉到 1,而如果我没有将 display 设置为 none,它会优雅地转换。我想使用display: none,因为在菜单出现之前,我需要能够在后台的画布上捕捉鼠标移动。我做了一个codepen来演示这个here

注意:我也希望能够使用 Javascript 淡出

我也看过this question,但第一个建议的答案无法淡出。

谢谢!

text = document.getElementById("text");
window.setTimeout((function () {
  text.style.display = "flex";
  text.style.opacity = "1";
}), 2000)
#text {
  display: none;
  opacity: 0;
  width: 500px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 3rem;
  color: white;
  align-items: center;
  justify-content: center;
  transition-duration: 2s;
  background-color: black;
  border-radius: 5px;
}
<div id="text">Testing Testing 123</div>

【问题讨论】:

  • 浏览器将无法识别display: none 元素的属性。过渡将简单地停止。您可能想查看visibility 或仅使用不透明度,然后在动画完成后使用display: none
  • 我在后台有一个画布,需要在菜单不可见时主动获取用户输入。我相信能见度:没有人会妨碍它。

标签: javascript css css-transitions


【解决方案1】:

无需 JS...

您可以添加 animation css 规则,然后在 CSS 中添加 keyframes,将动画指向您的 opacity。将其命名为fadeIn,然后添加您希望动画工作的轻松和时间。然后在你的css中添加@keyframes fadeIn并设置关键帧的不透明度通过0% { opacity: 0; }然后100% { opacity: 1; }的百分比。这将增加我认为您正在寻找的淡入淡出。

注意:确保在 @keyframes css 中添加多浏览器支持

编辑:如果您希望它在设定的时间长度后淡入然后淡出,请调整关键帧和动画时间设置。查看我更新的代码片段...我还在 setTimeout() 中删除了 JS opacity: 1,因为它迫使 css 动画回到 opacity: 1

Mozilla @keyframes Documentation

text = document.getElementById("text");
window.setTimeout((function() {  
  text.style.display = "flex";
}), 2000)
#text {
  animation: fadeIn ease 5s;
  display: none;
  opacity: 0;
  width: 500px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 3rem;
  color: white;
  align-items: center;
  justify-content: center;
  transition-duration: 2s;
  background-color: black;
  border-radius: 5px;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
<div id="container">
  <div id="text">Testing Testing 123</div>
</div>

【讨论】:

  • 嗨!抱歉,如果我不清楚,但我还需要能够使用 javascript 淡出。我已经编辑了我的帖子,以便更清楚。
  • @wickedtree 查看更新。我不确定您希望 css 如何淡出,但如果它与时间相关,也可以使用关键帧来完成。只需重置您在动画中的时间并设置 two 内部关键帧以触发不透明度,然后最后一帧将触发opacity: 0 这可以通过多种方式进行调整以获得不同的动画效果和关键帧...
  • 不,它与时间无关。它在加载所有资产后由 javascript 触发。感谢您的建议!
【解决方案2】:

不要将display: none 用于要淡入的元素。 display: none 将从您的显示中删除该元素。当它重新出现时,它不会应用您的 css 动画。

因此,您将不得不为动画使用 JavaScript。 将动画/显示逻辑保留在 CSS 中

有一个旧的 CSS 技巧,您可以在屏幕外隐藏 absolutefixed 元素。使用 left 属性。

const text = document.getElementById("text");
window.setTimeout( function() {
  text.classList.remove('hidden');
}, 1000);

window.setTimeout( function() {
  text.classList.add('hidden');
}, 5000)
#text {
  width: 500px;
  height: 100px;
  display: flex;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 3rem;
  color: white;
  align-items: center;
  justify-content: center;
  background-color: black;
  border-radius: 5px;
  opacity: 1;
  transition: opacity 500ms;
}
#text.hidden {
  left: -500000px;
  opacity: 0;
  transition: opacity 500ms, left 0ms 500s;
}
&lt;div id="text" class='hidden'&gt;Testing Testing 123&lt;/div&gt;

【讨论】:

【解决方案3】:

虽然看起来很奇怪,但答案是在您的代码中添加一行,如下所示:

window.setTimeout((function () {
  text.style.display = "flex";
  document.body.offsetHeight;  // Yes, this line!
  text.style.opacity = "1";
}), 2000);

这一行没有什么特别之处,只是它在您的页面中执行“读取”数据(任何从 DOM 读取数据的操作都可以工作)。这样做是强制浏览器布局(或重排)页面。这很重要,因为一般来说,如果您执行一系列“写入”操作 - 例如添加一个元素或设置它的样式,浏览器会将它们批处理并一次执行它们。这意味着当您将元素的不透明度设置为0,然后设置为1时,浏览器会将这些操作批处理并在页面重排之前将它们一起执行,因此没有动画。通过在两者之间插入写操作,浏览器能够从元素的透明状态到完全不透明的状态进行动画处理。

让它消失有点不同:

text = document.getElementById("text");

window.setTimeout((function () {
  text.style.display = "flex"; // write operation
  document.body.offsetHeight; // read operation which forces reflow

  text.addEventListener('transitionend', function listener1() {
    text.removeEventListener('transitionend', listener1);
    
    text.addEventListener('transitionend', function listener2() {
      text.removeEventListener('transitionend', listener2);
      text.style.display = 'none'; // remove text
    });
    
    window.setTimeout(function () {
      text.style.opacity = 0.1; // hide text
    }, 1000);
  });
  
  text.style.opacity = 1; // write operation - show text
  
}), 2000);

最好在开始新的转换之前等待上一个转换完成。在事件触发后删除事件侦听器也是一种很好的做法。在从 DOM 中删除元素之前,您必须等待转换完成。在设置触发动画的样式之前无需执行读取操作,因为页面已经布局,不透明度设置为 1。我将不透明度设置为 0.1,以便您可以看到元素实际上消失了。

你可以看到JFiddle here.

【讨论】:

    猜你喜欢
    • 2021-07-26
    • 2014-05-25
    • 2020-05-29
    • 2019-12-02
    • 2019-01-03
    • 2017-06-27
    • 1970-01-01
    • 2018-08-01
    • 2016-12-08
    相关资源
    最近更新 更多