英文:
How do I CSS transition a modal dialog element when it opens?
问题
我想将“transition”应用于对话框元素在打开时,但我的“transition”属性似乎没有任何效果。这是我的代码:
<button id="open-button">打开对话框</button>
<dialog>
<button id="close-button">关闭对话框</button>
</dialog>
我的目的是让对话框以渐变的方式显示,其背景从红色变为绿色。相反,dialog[open]
的规则立即应用?
我在Windows 10上的Firefox中进行测试。
英文:
I want to apply a transition
to dialog elements when they are opened, but my transition
attribute doesn't seem to be having any effect. Here's my code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const dialog = document.querySelector("dialog");
document.querySelector("#open-button").addEventListener("click", () => {
dialog.showModal();
});
document.querySelector("#close-button").addEventListener("click", () => {
dialog.close();
});
<!-- language: lang-css -->
button {
display: block;
}
dialog {
position: absolute;
top: 50px;
margin: auto;
padding: 0;
width: 50%;
height: 50%;
background-color: red;
opacity: 0;
-webkit-transition: opacity 2s ease-in, background-color 2s ease-in;
-o-transition: opacity 2s ease-in, background-color 2s ease-in;
transition: opacity 2s ease-in, background-color 2s ease-in;
}
dialog[open] {
background-color: green;
opacity: 1;
}
<!-- language: lang-html -->
<button id="open-button">Open Dialog Element</button>
<dialog>
<button id="close-button">Close Dialog Element</button>
</dialog>
<!-- end snippet -->
My intent is to slowly fade the dialog into view as its background visibly changes from red to green.
Instead, the rules of dialog[open]
are immediately applied? The MDN <dialog> article doesn't mention transition
s or animations anywhere, implying this should work as any other element.
I am testing this in Firefox on Windows 10.
答案1
得分: 3
您的对话从display:none
到display:block
的过渡会破坏transition
效果。原本的想法是添加dialog { display:block; }
,但效果不好,因为对话框只是隐藏了,并且对键盘TAB导航等有反应...所以我们需要保持关闭的对话框display:none
。
所以有几种解决方案:
- 您可以使用
animation
,我喜欢它,因为它是纯CSS解决方案:
dialog[open] {
animation: fadein 2s ease-in forwards;
}
@keyframes fadein{
0%{
opacity:0;
}
100%{
opacity:1;
background-color: green;
}
}
- 您还可以在打开后使用
setTimeout
添加一个CSS类,以允许DOM重新渲染,并在关闭时移除它,从而保持您的transition
效果不受影响。
setTimeout(() => dialog.classList.add('open'));
dialog.addEventListener('close', () => dialog.classList.remove('open'));
英文:
Your dialog transitions from display:none
to display:block
and that ruins transition
. The idea was to add dialog { display:block; }
but it turned out bad because the dialog is just hidden and reacts to the keyboard TAB navigation for example... So we need to keep a closed dialog display:none
.
So a couple of solutions:
- You could use
animation
which I like since it's a pure CSS solution:
dialog[open] {
animation: fadein 2s ease-in forwards;
}
@keyframes fadein{
0%{
opacity:0;
}
100%{
opacity:1;
background-color: green;
}
}
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
const dialog = document.querySelector("dialog");
document.querySelector("#open-button").addEventListener("click", () => {
dialog.showModal();
});
document.querySelector("#close-button").addEventListener("click", () => {
dialog.close();
});
<!-- language: lang-css -->
button {
display: block;
}
dialog {
position: absolute;
top: 50px;
margin: auto;
padding: 0;
width: 50%;
height: 50%;
background-color: red;
opacity: 0;
}
dialog[open] {
animation: fadein 2s ease-in forwards;
}
@keyframes fadein{
0%{
opacity:0;
}
100%{
opacity:1;
background-color: green;
}
}
<!-- language: lang-html -->
<button id="open-button">Open Dialog Element</button>
<dialog>
<button id="close-button">Close Dialog Element</button>
</dialog>
<!-- end snippet -->
- You could also add a CSS class after the opening with
setTimeout
to allow the DOM to be re-rendered and remove it on the closing with yourtransition
left intact.
setTimeout(()=>dialog.classList.add('open'));
dialog.addEventListener('close', () => dialog.classList.remove('open'));
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
const dialog = document.querySelector("dialog");
dialog.addEventListener('close', () => dialog.classList.remove('open'));
document.querySelector("#open-button").addEventListener("click", () => {
dialog.showModal();
setTimeout(()=>dialog.classList.add('open'));
});
document.querySelector("#close-button").addEventListener("click", () => {
dialog.close();
});
<!-- language: lang-css -->
button {
display: block;
}
dialog {
position: absolute;
top: 50px;
margin: auto;
padding: 0;
width: 50%;
height: 50%;
background-color: red;
opacity: 0;
-webkit-transition: opacity 2s ease-in, background-color 2s ease-in;
-o-transition: opacity 2s ease-in, background-color 2s ease-in;
transition: opacity 2s ease-in, background-color 2s ease-in;
}
dialog.open {
background-color: green;
opacity: 1;
}
<!-- language: lang-html -->
<button id="open-button">Open Dialog Element</button>
<dialog>
<button id="close-button">Close Dialog Element</button>
</dialog>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论