daisyui icon indicating copy to clipboard operation
daisyui copied to clipboard

[Enhancement] Modal close animation

Open asportnoy opened this issue 4 years ago • 11 comments

Modals have an animation for opening, but closing just happens instantly with no animation. It would be nice to have a closing animation, potentially just the opening animation in reverse.

This also occurs on the docs so I know it is not an issue with my code.

asportnoy avatar Jan 28 '22 15:01 asportnoy

I don't have a solution for this yet.
If I add a CSS animation for closing the modal, it will cause a flicker when page loads and that's not good.

saadeghi avatar Feb 14 '22 11:02 saadeghi

it will cause a flicker when page loads

wdym? why should a page load if I hide a modal?

lkj4 avatar Mar 01 '22 06:03 lkj4

@lkj4 currently modal has visibility: hidden when it's closed and has visibility: visible when it's open. We can't apply CSS animation when an element goes from visible to hidden because it's instant. A workaround is to use opacity instead of visibility which can have animations. The problem is when a close modal wouldn't be invisible when page loads and then the fade out animation fires which will cause a flicker of modal when page loads.

saadeghi avatar Mar 01 '22 07:03 saadeghi

I think it would be better to reopen this and mark it as help wanted some someone else might be able to come up with a solution.

asportnoy avatar Mar 01 '22 12:03 asportnoy

Agree with @asportnoy. This approach is less compelling without a smooth transition on close. I'm using Sveltekit and will probably have to migrate to something like svelte-simple-modal. Although honestly, I'd prefer to use DaisyUI as much as possible.

cryptosmithio avatar Apr 01 '22 09:04 cryptosmithio

Okay I re-open this but that wouldn't help. We can't animate to visibility: hidden

saadeghi avatar Apr 01 '22 09:04 saadeghi

I'm not great at CSS, but how does svelte-simple-modal implement?

cryptosmithio avatar Apr 01 '22 10:04 cryptosmithio

It applies animation using JS and removes it after showing/hiding modal.
I can't add JS to daisyUI since it's a Tailwind CSS plugin. However, it is possible to apply your own JS (based on the JS framework you're using).
Also, there is no downside in using a JS plugin that handles modals (like svelte-simple-modal) because there are things a JS plugin can do that CSS can not.

saadeghi avatar Apr 01 '22 11:04 saadeghi

In solidjs I solved it like this:

const Modal: FlowComponent<{ open: boolean }> = (props) => {
  const [isVisible, setVisibility] = createSignal(props.open);
  createEffect(() => {
    if (props.open) {
      setVisibility(true);
    } else {
      setTimeout(function () {
        setVisibility(false);
      }, 200);
    }
  });

  return (
    <div
      classList={{
        modal: true,
        "modal-open": props.open,
        "!visible": isVisible(),
      }}
    >
      <div class="modal-box w-1/2 p-20 max-w-none">{props.children}</div>
    </div>
  );
};
``

katywings avatar Jun 19 '22 13:06 katywings

What if we include a hint and maybe some quick vanilla js example "Modal with close animation" just in the Daisyui docs. That way users would see that they have to do something with js & that this behavior is intended!

katywings avatar Jun 19 '22 13:06 katywings

I'm definitely for adding a JS tab like the html tab for examples that require js to function properly.

clicktodev avatar Aug 26 '22 21:08 clicktodev

The closing animation is working as expected after I made the modal visible by default with <label className="modal visible">. I'm not seeing any unusual artifact such as flickering.

Is there any hidden behavior that I'm not aware of?

ni554n avatar Sep 27 '22 19:09 ni554n

Maybe the modal CSS closing animation could be realized by using a transition-delay on visibility, as explained here.

transition: visibility 0s 2s;

we’re trying to delay the application of visbility:hidden using pure CSS. We can do this using the transition-delay property, and apply a different delay to the opacity transition (no delay) and to the visibility transition (delay equal to the duration of the opacity transition)

PS: Thx for explaining the issue with the closing modal animation, and also all the work you put into this @saadeghi.

MentalGear avatar Nov 09 '22 09:11 MentalGear

PR https://github.com/saadeghi/daisyui/pull/1335

I was able to add smooth modal closing transitions by simple adding visibility to the transition-property. Tested both on Safari 15 and Chrome 107.

css

https://user-images.githubusercontent.com/2837147/200816412-7aa3f782-b819-49b8-85d8-37df61330634.mov

MentalGear avatar Nov 09 '22 11:11 MentalGear

PR added, this should finally fix this issue.

On a side-note: A few months ago I also thought JS to be the answer for most interactivity, but since using sveltekit, which advocates progressive enhancement (e.g. great functionality without JS), I must say it helped to figure out different approaches on how things can be implemented without JS and be more accessible and even faster.

MentalGear avatar Nov 09 '22 11:11 MentalGear

Can this be added for toasts too?

MarcGodard avatar Jan 19 '24 17:01 MarcGodard

@MarcGodard unfortunately no. HTML elements can use a CSS animation when being added to the page but when we remove them from the page, they will be removed instantly, so there's no way for CSS to run an animation before the node is being removed. To achieve this, you can manually add a style (could be transform: scale(.9) or anything) and then with a delay, delete the node from DOM

You can also use a JS animation library for that. Or if your framework has animation functions (like Svelte) you can use them

saadeghi avatar Jan 22 '24 19:01 saadeghi