I have a footer section that has some hidden content that can be toggled. For whatever reason the transition animation isn't working/ is super stuttery and I'm not too sure what I am doing wrong here.
I've read about making max-height
the attribute you target with the animations, but this is still not working properly.
I've made a CodeSandbox to show the issue, so please take a look!
Any advise or tips would be greatly appreciated!
Cheers!
Footer.vue
<template>
<div class="_real-time-footer">
<div class="_real-time-footer-top">
<div class="_real-time-footer-top-left-side">
<p class="_real-time-footer-top-left-side-inferences-text">Something</p>
<div>button</div>
<div>button</div>
</div>
<div class="_video-play-and-time">
<button
v-if="!videoIsPlaying"
key="1"
style="cursor: pointer"
@click.prevent="() => playVideo()"
class="_video-play-and-time-play-button"
>
<svg
class="_video-play-and-time-play-button-icon"
id="Play_Btn"
data-name="Play Btn"
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"
viewBox="0 0 32 32"
>
<rect
id="Rectangle_3351"
data-name="Rectangle 3351"
width="32"
height="32"
rx="4"
fill="#4972fa"
opacity="0.254"
/>
<path
id="Play"
d="M7.649,1.382a1,1,0,0,1,1.7,0l6.71,10.893A1,1,0,0,1,15.21,13.8H1.79a1,1,0,0,1-.851-1.524Z"
transform="translate(25.16 7.5) rotate(90)"
fill="#466ff4"
opacity="0.998"
/>
</svg>
</button>
<button
v-else
key="2"
style="cursor: pointer"
@click.prevent="() => stopVideo()"
class="_video-play-and-time-play-button"
>
<svg
class="_video-play-and-time-play-button-icon"
id="Stop_Btn"
data-name="Stop Btn"
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"
viewBox="0 0 32 32"
>
<rect
id="Rectangle_2865"
data-name="Rectangle 2865"
width="32"
height="32"
rx="4"
fill="rgba(71,113,250,0.25)"
/>
<rect
id="Rectangle_3155"
data-name="Rectangle 3155"
width="15"
height="15"
rx="1"
transform="translate(8.5 8.5)"
fill="#4771fa"
/>
</svg>
</button>
<p class="_video-play-and-time-time">{{ videoTime }}</p>
</div>
<div class="_current-time">
<p class="_current-time-time">{{ time }}</p>
<p class="_current-time-timezone">{{ timezone }}</p>
</div>
</div>
<Transition name="slide" mode="out-in">
<div
v-if="liveInferenceManagementPanelIsVisible"
style="
display: flex;
justify-content: center;
align-items: center;
max-height: 0;
background-color: #202634;
padding: 3em 0;
"
>
<div>something here</div>
</div>
</Transition>
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
setup() {
const videoIsPlaying = ref(false);
const liveInferenceManagementPanelIsVisible = ref(false);
const videoTime = ref("00:00:00");
const time = new Date().toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
// hour12: false,
});
const timezone = new Date()
.toLocaleDateString(undefined, { day: "2-digit", timeZoneName: "long" })
.substring(4)
.match(/\b(\w)/g)
.join("");
function playVideo() {
videoIsPlaying.value = true;
liveInferenceManagementPanelIsVisible.value = false;
console.log("Video starts");
}
function stopVideo() {
videoIsPlaying.value = false;
liveInferenceManagementPanelIsVisible.value = true;
console.log("Video ends");
}
return {
videoIsPlaying,
liveInferenceManagementPanelIsVisible,
videoTime,
time,
timezone,
playVideo,
stopVideo,
};
},
});
</script>
<style lang="sass" scoped>
._real-time-footer
position: absolute
bottom: 0
left: 0
right: 0
&-top
display: flex
justify-content: center
align-items: center
width: 100%
padding: 1rem 2rem
color: #A5B0CB
background: #283044
&-left-side
flex: 1 1 0
display: flex
align-items: center
gap: 2em
// flex-wrap: wrap
&-inferences-text
margin-right: 2em
&-live-feed
position: absolute
top: 1.5em
left: 1.5em
color: #fff
._video-play-and-time
flex: 1 1 0
display: flex
align-items: center
background: none
gap: 1.25em
&-play-button
&:focus
outline: none
&-icon
width: 2em
&-time
opacity: 50%
._current-time
justify-self: right
display: flex
align-items: center
gap: 0.75em
border-radius: 12px
padding: 0.35em 1.25em
background-color: #202634
&-time
font-size: 14px
&-timezone
font-size: 8px
opacity: 66%
._dsp-wrapper
position: absolute
top: 10px
left: 10px
height: 70%
width: 20%
._fsp-wrapper
position: absolute
top: 8px
right: 8px
height: 43%
width: 20%
._ccp-wrapper
position: absolute
bottom: 8px
right: 10px
left: 10px
// width: 100%
height: 23%
background: red
opacity: 70%
.fade-move,
.fade-enter-active,
.fade-leave-active
height: inherit
transition: opacity 0.3s
.fade-enter,
.fade-leave-to
opacity: 0
.slide-enter-active
-moz-transition-duration: 0.3s
-webkit-transition-duration: 0.3s
-o-transition-duration: 0.3s
transition-duration: 0.3s
-moz-transition-timing-function: ease-in-out
-webkit-transition-timing-function: ease-in-out
-o-transition-timing-function: ease-in-out
transition-timing-function: ease-in-out
.slide-leave-active
-moz-transition-duration: 0.3s
-webkit-transition-duration: 0.3s
-o-transition-duration: 0.3s
transition-duration: 0.3s
-moz-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
-webkit-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
-o-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
.slide-enter-to,
.slide-leave
max-height: 200px
overflow: hidden
.slide-enter,
.slide-leave-to
overflow: hidden
max-height: 0
</style>
A couple of remarks.
.slide-enter
should be now .slide-enter-from
. Check out the css based transitions.With all this in place your sass code should look something like:
.slide-container
display: flex
justify-content: center
align-items: center
max-height: 0
background-color: #202634
padding: 3em 0
.slide-enter-active
...
.slide-leave-active
...
.slide-enter-to,
.slide-leave-from
padding: 3em 0
overflow: hidden
.slide-enter-from,
.slide-leave-to
overflow: hidden
padding: 0em 0
I forked your example and made the changes for you to play around.