[Enhancement] Modal close animation
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.
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.
it will cause a flicker when page loads
wdym? why should a page load if I hide a modal?
@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.
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.
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.
Okay I re-open this but that wouldn't help. We can't animate to visibility: hidden
I'm not great at CSS, but how does svelte-simple-modal implement?
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.
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>
);
};
``
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!
I'm definitely for adding a JS tab like the html tab for examples that require js to function properly.
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?
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:hiddenusing pure CSS. We can do this using thetransition-delayproperty, 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.
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.
https://user-images.githubusercontent.com/2837147/200816412-7aa3f782-b819-49b8-85d8-37df61330634.mov
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.
Can this be added for toasts too?
@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