如何在模态对话框元素打开时进行CSS过渡?

huangapple go评论79阅读模式
英文:

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(&quot;dialog&quot;);

document.querySelector(&quot;#open-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  dialog.showModal();
});
document.querySelector(&quot;#close-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  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 -->

&lt;button id=&quot;open-button&quot;&gt;Open Dialog Element&lt;/button&gt;

&lt;dialog&gt;
  &lt;button id=&quot;close-button&quot;&gt;Close Dialog Element&lt;/button&gt;
&lt;/dialog&gt;

<!-- 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 transitions or animations anywhere, implying this should work as any other element.

I am testing this in Firefox on Windows 10.

答案1

得分: 3

您的对话从display:nonedisplay:block的过渡会破坏transition效果。原本的想法是添加dialog { display:block; },但效果不好,因为对话框只是隐藏了,并且对键盘TAB导航等有反应...所以我们需要保持关闭的对话框display:none

所以有几种解决方案:

  1. 您可以使用animation,我喜欢它,因为它是纯CSS解决方案:
dialog[open] {
  animation: fadein 2s ease-in forwards;
}

@keyframes fadein{
  0%{
    opacity:0;
  }
  100%{
    opacity:1;
    background-color: green;
  }
}
  1. 您还可以在打开后使用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:

  1. 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(&quot;dialog&quot;);

document.querySelector(&quot;#open-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  dialog.showModal();
});
document.querySelector(&quot;#close-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  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 -->

&lt;button id=&quot;open-button&quot;&gt;Open Dialog Element&lt;/button&gt;

&lt;dialog&gt;
  &lt;button id=&quot;close-button&quot;&gt;Close Dialog Element&lt;/button&gt;
&lt;/dialog&gt;

<!-- end snippet -->

  1. 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 your transition left intact.
setTimeout(()=&gt;dialog.classList.add(&#39;open&#39;));
dialog.addEventListener(&#39;close&#39;, () =&gt; dialog.classList.remove(&#39;open&#39;));

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const dialog = document.querySelector(&quot;dialog&quot;);

dialog.addEventListener(&#39;close&#39;, () =&gt; dialog.classList.remove(&#39;open&#39;));

document.querySelector(&quot;#open-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  dialog.showModal();
  setTimeout(()=&gt;dialog.classList.add(&#39;open&#39;));
});

document.querySelector(&quot;#close-button&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  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 -->

&lt;button id=&quot;open-button&quot;&gt;Open Dialog Element&lt;/button&gt;

&lt;dialog&gt;
  &lt;button id=&quot;close-button&quot;&gt;Close Dialog Element&lt;/button&gt;
&lt;/dialog&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月18日 06:04:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76708361.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定