I have this scss code in my vue app. I'm trying to make a smooth transition from left for a menu when the isVisible property is set to true but I'm not able to apply the transition I've defined and the menu will instantly appear.
I've done a reserach here on SO and I've found some interesting questions but all of them are using jQuery and css animation so they are not really useful.
I'm not a CSS master, any suggestion about?
HTML
<div class="col-12 settings p-3 position-fixed" :class="{ 'show': isVisible }" ref="settings" v-if="isVisible">
<h4>Settings</h4>
</div>
CSS
.settings {
top: 0;
width: 50%;
height: 100vh;
background-color: white;
transform: translateX(-100%);
transition: transform 0.5s ease;
&.show {
transform: translateX(0);
transition: transform 0.5s ease;
}
}
This is done with <transition>
Here an example:
<transition name="slide">
<div class="col-12 settings p-3 position-fixed" class="settings" v-if="isVisible">
<h4>Settings</h4>
</div>
</transition>
CSS class
.slide-enter-active, .slide-leave-active {
transition: transform .5s;
}
.slide-enter, .slide-leave-to {
transform: translateX(-200px);
}
.settings {
top: 0;
width: 50%;
height: 100vh;
background-color: white;
}
Its really not that hard
Take a look: https://v2.vuejs.org/v2/guide/transitions.html
I believe the issue is that, because you are using v-if, the element is only being rendered when the condition isVisible === True. This means that it is being rendered with the conditional 'show' class already applied, therefore no transition.
You could use the v-show directive instead of v-if, this makes the element hidden but rendered until the condition is true. (more info here).
<div
class="col-12 settings p-3 position-fixed"
:class="{ 'show': isVisible }"
ref="settings"
v-show="isVisible">
<h4>Settings</h4>
</div>
If you want to do more with transitions, I suggest looking up vue-transitions - documentation here - this allows you to assign css to the element during its rendering states, i.e. what styles apply as it enters and when it leaves.
See the other answer here for an example of how to do this with vue transition.
Related
I have a div with adding a class by condition
<div
className={`${
showLinks ? "links-container show-container" : "links-container"
}`}
>
And some styles
.links-container {
height: 0;
overflow: hidden;
transition: all 0.3s linear;
}
.show-container {
height: 10rem;
}
So when the component is render/rerender, a smooth div extension animation is triggered thanks to my transition style. How it works? Is this css or react rules?
I've built myself a carousel of divs that slide in and out of the screen. My problem is that on the start of every transition, when the new div first renders (ie. the carousel_2 key changes), it seems to render without the transition-enter class applied to it. This means that the new div flickers overtop of the old one before getting translated off the screen and out of view. It's almost as though the transition takes a tick to register that the new div has appeared. If I could figure out how to delay the new div from rendering for a tick, I believe that my problem might be solved, though I don't know how to do this with keys.
<transition name="slide-img">
<div :key="carousel_2" class="workDiv-container">
<div class="workDiv">
<div class="imgDiv">
<img :src="carousel_2.img" style="width: 100%;"/>
</div>
<div class="infoDiv">
<h1>{{ carousel_2.title }}</h1>
<h3>{{ carousel_2.creator }}</h3>
<h3>{{ carousel_2.date }}</h3>
<h3>{{ carousel_2.medium }}</h3>
<h3>{{ carousel_2.idno }}</h3>
<h3>{{ carousel_2.dimensions }}</h3>
</div>
</div>
</div>
</transition>
.slide-img-enter {
left: -100%;
transform: translate(0, 0);
}
.slide-img-enter-to {
left: -100%;
transform: translate(100%, 0);
}
.slide-img-enter-active {
transition: transform 2s;
}
.slide-img-leave {
transform: translate(0, 0);
}
.slide-img-leave-to {
transform: translate(100%, 0);
}
.slide-img-leave-active {
transition: transform 2s;
}
.workDiv-container {
position: absolute;
width: 100%;
height: 100%;
}
NOTE: carousel_2 is just a computed value that is updated with the object containing the values to display.
on the start of every transition, when the new div first renders (ie. the carousel_2 key changes), it seems to render without the transition-enter class applied to it
That's right. Because In Vue 3 the v-enter and v-leave classes are renamed to v-enter-from and v-leave-from
If you change your transition classes to:
.slide-img-enter-from {
left: -100%;
transform: translate(0, 0);
}
/* this one is actually not needed at all */
.slide-img-leave-from {
transform: translate(0, 0);
}
...the problem is fixed. Demo
I'm trying to use the same button to open and close a menu, I'm sure this is super simple but I'm new to the world of jQuery. I'm using the Wordpress builder 'Oxygen' if that helps. Here's my code:
The modal is an in-built feature in the website builder so I can't provide much code on that. It's basically set to trigger when element with class "open" is clicked, and close with element class "oxy-modal-close".
jQuery
jQuery("#toggle").click(function () {
jQuery('#plus').toggleClass('rotate');
jQuery('#toggle').toggleClass('open oxy-modal-close');
});
HTML
<div id="toggle" class="open">
<img id="plus" src="http://hausse.co.uk/wp-content/uploads/2021/01/plus.svg"/>
</div>
CSS
#plus {
-moz-transition: transform 1s;
-webkit-transition: transform 1s;
transition: transform 0.3s;
width: 35px;
position: fixed;
top: 20px;
right: 20px;
}
.rotate {
transform: rotate(45deg);
}
Basically on the 2nd click, the class is re-adding the class "open", which is causing the menu to flicker as the two actions are conflicting with each other. Video here - https://gph.is/g/ZnNQddo
I have tried adding a delay to the class "open", but for some reason the delay is only working on the first click - on the second it's changing class instantly. This is the code I'm trying for that.
jQuery("#toggle").click(function () {
jQuery('#plus').toggleClass('rotate');
jQuery('#toggle').toggleClass('oxy-modal-close');
var el = jQuery("#toggle");
window.setTimeout(function() {
el.toggleClass('open');
}, 500);
});
You are referencing the id again within the click - you need to reference $(this)... to toggle the class on the click
Also - you need to start with one of the states - that way it can toggle the class to the other state on each click as per the snippet (the cross icon is on the right of the snippet widow as per styling ) - now when you click it rotates as intended.
$("#toggle").click(function() {
$('#plus').toggleClass('rotate');
$(this).toggleClass('open oxy-modal-close');
});
#plus {
-moz-transition: transform 1s;
-webkit-transition: transform 1s;
transition: transform 0.3s;
width: 35px;
position: fixed;
top: 20px;
right: 20px;
}
.rotate {
transform: rotate(45deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="toggle" class="open">
<img id="plus" src="http://hausse.co.uk/wp-content/uploads/2021/01/plus.svg"/>
</div>
Here's an example of what I am trying to recreate: https://www.hioscar.com/get-quote/
When a user has finished entering information into the input area or selected an option the current line will animate (using translate & opacity, I believe) and the next line will come into view.
I've started something very basic just to get a feel for how it's meant to work using on hover but I'm not sure on how to complete replicate this animation in my own form.
div {
margin-top: 500px;
}
div:hover {
transform: translate(0px, -300px);
opacity: 0.3;
transition: opacity 0.05s linear;
}
<div>
<p>Hello, I am a very basic example</p>
</div>
So you had several problems, you were only animating opacity and if you move the div from under the mouse cursor when you hover it, it won't work.
So I activated all transitions, not just opacity, made the div as tall as the browser, and used the div's internal padding.
body, html {
/* needed so that the div can also be 100% of window */
height: 100%;
}
div {
height: 100%;
padding-top: 500px;
}
div:hover {
padding-top: 300px;
transition: all 0.05s linear;
}
<div>
<p>Hello, I am a very basic example</p>
</div>
I am trying to show a div with animation using ng-hide and ng-show, it is not working properly. When I mention a specific height it is working correctly, if I mention min-height it is not working.
here is my css code
.sample-show-hide {
opacity: 1;
min-height: 180px;
}
.sample-show-hide.ng-hide-add,
.sample-show-hide.ng-hide-remove {
transition: all linear 0.5s;
}
.sample-show-hide.ng-hide {
min-height: 0px;
opacity: 0;
}
here is my example html code
<div class="row" ng-click="showDiv=true">
<h2>Click me</h2>
</div>
<div class="row sample-show-hide" ng-show="showDiv=!showDiv">
<h2>some data</h2>
<h2>some data</h2>
<h2>some data</h2>
<h2>some data</h2>
</div>
If I mention a specific height like below it is working correctly, then if I add some more extra data to that div then it is taking the height as 80px only the remaining data is not showing because of that specific height, so if I add extra text also that div has to take height automatically
.sample-show-hide {
opacity: 1;
height: 80px;
}
.sample-show-hide.ng-hide-add,
.sample-show-hide.ng-hide-remove {
transition: all linear 0.5s;
}
.sample-show-hide.ng-hide {
height: 0px;
opacity: 0;
}
So, I managed to obtain what I think you want, except that the size transition is not necessarily in sync with the opacity transition, but looks good either way.
The idea is to use max-width and the ease-in and ease-out transitions.
.sample-show-hide {
max-height: 999px;
opacity: 1;
}
.sample-show-hide.ng-hide-add {
transition: all ease-out 0.5s;
}
.sample-show-hide.ng-hide-remove {
transition: all ease-in 0.5s;
}
.sample-show-hide.ng-hide {
max-height: 0px;
opacity: 0;
}
NOTE that the speed of the size depends on the max-height that you set (e.g. 999px) - you can increase this if you expect the div to have bigger size but then also increase the transition time (you could separate the opacity transition from the size transition to make them more compatible)
Hope this helps.
Seems to work fine, I made a jsfiddle for it just in case. I added one extra line though, to be sure.
min-height: 80px;
height: auto;
It works in my example https://jsfiddle.net/c6xnv0pj/2/, maybe I'm missing something?
Maybe you didn't inject ngAnimate to your app?
angular.module('myApp', ['ngAnimate']);