CSS 显示的不透明度过渡:none
CSS Opacity transition with display: none
我有一个菜单,我想用 javascript 淡入。我希望它从 display: none
和 opacity: 0
过渡到 display: flex
和 opacity: 1
。但是当我使用 javascript 将不透明度设置为 1 时,它不会过渡,而是突然捕捉到 1,而如果我没有将显示设置为 none,它会优雅地过渡。我想使用 display: none
因为在菜单出现之前我需要能够在后台的 canvas 上捕捉鼠标移动。我做了一个代码笔来演示这个 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>
不需要 JS...
您可以添加 animation
css 规则,然后在您的 CSS 中添加 keyframes
将动画指向您的 opacity
。将其命名为 fadeIn
之类的名称,然后添加您希望动画工作的轻松程度和时间。然后在你的 css 中添加 @keyframes fadeIn
并通过 0% { opacity: 0; }
然后 100% { opacity: 1; }
的百分比将不透明度的关键帧设置为 运行。这将增加我认为您正在寻找的轻松淡入度。
注意:确保在您的@keyframes 中添加多浏览器支持css
编辑:如果您想让它淡入然后在设定的时间长度后淡出,请调整关键帧和动画时间设置。请参阅我更新的 snipit...我还删除了 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>
不要对要 fade-in 的元素使用 display: none
。 display: none
将从您的显示中删除该元素。重新出现时不会应用您的 css 动画。
因此您必须使用 JavaScript 来制作动画。 在 CSS 中保留 animation/display 逻辑。
有一个古老的 CSS 技巧,您可以在屏幕外隐藏 absolute
或 fixed
元素。使用左边 属性.
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;
}
<div id="text" class='hidden'>Testing Testing 123</div>
虽然看起来很奇怪,但答案是在您的代码中添加一行,如下所示:
window.setTimeout((function () {
text.style.display = "flex";
document.body.offsetHeight; // Yes, this line!
text.style.opacity = "1";
}), 2000);
这一行除了在您的页面中执行 'read' 数据外没有什么特别之处(任何从 DOM 读取数据的操作都可以)。这样做是强制浏览器布局(或重排)页面。这很重要,因为一般来说,如果您执行一系列 'write' 操作 - 例如添加一个元素或设置它的样式,浏览器将把它们分批处理并一次性执行。这意味着当您将元素的不透明度设置为 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.
我的解决方案是在显示和不透明度之间设置 1 毫秒的超时。
我认为所有这些解决方案都有些俗气。
我正在寻找更好的解决方案,但我想有 none.
我有一个菜单,我想用 javascript 淡入。我希望它从 display: none
和 opacity: 0
过渡到 display: flex
和 opacity: 1
。但是当我使用 javascript 将不透明度设置为 1 时,它不会过渡,而是突然捕捉到 1,而如果我没有将显示设置为 none,它会优雅地过渡。我想使用 display: none
因为在菜单出现之前我需要能够在后台的 canvas 上捕捉鼠标移动。我做了一个代码笔来演示这个 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>
不需要 JS...
您可以添加 animation
css 规则,然后在您的 CSS 中添加 keyframes
将动画指向您的 opacity
。将其命名为 fadeIn
之类的名称,然后添加您希望动画工作的轻松程度和时间。然后在你的 css 中添加 @keyframes fadeIn
并通过 0% { opacity: 0; }
然后 100% { opacity: 1; }
的百分比将不透明度的关键帧设置为 运行。这将增加我认为您正在寻找的轻松淡入度。
注意:确保在您的@keyframes 中添加多浏览器支持css
编辑:如果您想让它淡入然后在设定的时间长度后淡出,请调整关键帧和动画时间设置。请参阅我更新的 snipit...我还删除了 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>
不要对要 fade-in 的元素使用 display: none
。 display: none
将从您的显示中删除该元素。重新出现时不会应用您的 css 动画。
因此您必须使用 JavaScript 来制作动画。 在 CSS 中保留 animation/display 逻辑。
有一个古老的 CSS 技巧,您可以在屏幕外隐藏 absolute
或 fixed
元素。使用左边 属性.
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;
}
<div id="text" class='hidden'>Testing Testing 123</div>
虽然看起来很奇怪,但答案是在您的代码中添加一行,如下所示:
window.setTimeout((function () {
text.style.display = "flex";
document.body.offsetHeight; // Yes, this line!
text.style.opacity = "1";
}), 2000);
这一行除了在您的页面中执行 'read' 数据外没有什么特别之处(任何从 DOM 读取数据的操作都可以)。这样做是强制浏览器布局(或重排)页面。这很重要,因为一般来说,如果您执行一系列 'write' 操作 - 例如添加一个元素或设置它的样式,浏览器将把它们分批处理并一次性执行。这意味着当您将元素的不透明度设置为 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.
我的解决方案是在显示和不透明度之间设置 1 毫秒的超时。 我认为所有这些解决方案都有些俗气。 我正在寻找更好的解决方案,但我想有 none.