There are some invalid syntax/conceptions with the provided code:
.alt-pop {
animation: alt-pop-enter, alt-pop-leave;
}
This applies both of these named animations at the same time - probably not you'd want. Also note that no duration has been provided so the duration for both these animations is 0s
and thus there would be no visual effect.
@keyframes alt-pop-enter {
@apply transform ease-out duration-300 transition;
/* … */
}
@keyframes alt-pop-leave {
@apply transition ease-in duration-100;
/* … */
}
You can't use @apply
as immediate "child" of @keyframes
, since this would conceptually output something like:
@keyframes alt-pop-enter {
transform: /* … */;
transition-timing-function: /* … */;
/* … */
}
And this is invalid CSS.
@apply transform ease-out duration-300 transition;
/* … */
@apply transition ease-in duration-100;
It feels like you are trying to manipulate the animation
, but you are using classes that set transition-*
properties. These properties do not affect animation
.
How do I use css as much as possible to setup this entering and leaving animation instead of JS?
There will always be some aspect of JavaScript needed, since the CSS needs to be applied on the event when the animation needs to play.
And how do I use tailwindcss classes as much as possible?
Use your existing solution with the enter/leave classes.
And how do I set the delay before switching from entering to leaving?
This would be best done in the JavaScript that controls the enter/leaving classes. Otherwise, you could add a delay-*
class to the leaving
set of classes.
One approach I can think of is convert all the tailwind classes back to the actual tailwind then write my own keyframes and animation css class.
Is there a better approach than this?
Yes, your existing enter/leave classes.
Edit 1: Reply to @Kim Stacks
"What about the answer provided by Rifky Niyas at stackoverflow.com/a/75715839/80353? there's also a sandbox example of his solution. It seems that it's possible to do so without any JS"
It might seem working, but if you see keenly, your asked requirement is not met. Further I would refer your own comment to prove my point.
How is the transform and transition in Entering and transition in Leaving handled?
also in your sandbox example in play.tailwindcss, i expected the div to be completely hidden in the end because opacity-0, but it's still visible to me at the end. Am I missing something?
@keyframes alt-pop-enter {
from {
@apply translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2;
}
to {
@apply translate-y-0 opacity-100 sm:translate-x-0;
}
}
Adding on you can't use variants in @keyframes
since it would produce invalid CSS. In this instance, you'd create a separate @keyframes
for the sm:
case and then apply that to the .alt-pop
class. Something like:
.alt-pop {
animation: 300ms ease-out alt-pop-enter, 100ms ease-in 500ms alt-pop-leave;
}
@media screen(sm) {
.alt-pop {
animation: 300ms ease-out alt-pop-enter-sm, 100ms ease-in 500ms alt-pop-leave;
}
}
@keyframes alt-pop-enter {
from {
@apply translate-y-2 opacity-0;
}
to {
@apply translate-y-0 opacity-100;
}
}
@keyframes alt-pop-enter-sm {
from {
@apply opacity-0 translate-x-2;
}
to {
@apply opacity-100 translate-x-0;
}
}
Edit 2: Reply to @Rifky Niyas
Your @keyframes compile to:
@keyframes alt-pop-enter {
from {
--tw-translate-y: 0.5rem;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
opacity: 0;
}
@media (min-width: 640px) {
from {
--tw-translate-y: 0px;
--tw-translate-x: 0.5rem;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
}
to {
--tw-translate-y: 0px;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
opacity: 1;
}
@media (min-width: 640px) {
to {
--tw-translate-x: 0px;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
}
}
Where the @media rules inside the @keyframes is invalid CSS