I'm working on CSS and web development,but just face a something which i really don't understand it:
.header{
position: absolute;
width:60%;
top: 20%;
left: 50%;
transform: translateX(-50%);<------ executed after animation
text-align: center;
animation: moveUp 2s;
animation-fill-mode: backwards;
}
#keyframes moveUp{
0%{
opacity: 0;
transform:translateY(2rem);
}
100%{
opacity: 1;
transform: translateY(0rem);
}
}
so my problem here is the indicated line doesn't apply on ".header" until the animation gets applied in other word it applies animation first then translate -50% ,is there a priority of execution here or it is different thing?
Usually the styles are parsed from top to bottom, however this isn't the issue here.
What is happening in your case is the transform is being applied initially, but then it is being overridden by the animation. Once the animation is over, the element is reverting back to its default style which has the transform.
Essentially, even though the transform is applied at first, you don't see it until the element reverts to it after the end of the animation.
The only solution if you want to have the transform during the animation, is to include it in the animation itself.
#keyframes moveUp {
0 % {
opacity: 0;
transform: translate(-50%, 2rem);
}
100 % {
opacity: 1;
transform: translate(-50%, 0);
}
}
EDIT: To clarify, the order at which the styles are applied does not matter. Whether the animation or the transform is applied first, the result will be the same.
I think a source of your confusion is that the first transform is a translateX while the animation only does translateY. In both cases what is changing is the value of the transform property of the element. Therefore which axis the translation is on doesn't matter. First you set transform: translateX(-50%), but then once the animation kicks in, transform becomes translateY(2rem). The translateX part is removed from the transform, unless you include it in the animation like I have shown.
Related
I have set up some scroll animations on many elements of a site I'm building.
I'm using these CSS rules:
.hiddenLeft {
opacity: 0;
filter: blur(5px);
transform: translateX(-090%);
transition: all 1s;
}
.hiddenRight {
opacity: 0;
filter: blur(5px);
transform: translateX(90%);
transition: all 1s;
}
.show {
opacity: 1;
filter: blur(0);
transform: translateX(0);
}
The hiddenLeft and hiddenRight classes are in the elements by default, and then when they are intersected during vertical scroll the show classes are added.
It all works fine, except it has created horizontal scroll to the right out of the width of the site into blank space.
I would like to keep the animations as they are but without the horizontal scroll.
A picture of me scrolling out to the side into the blank space for reference:
enter image description here
I made a very basic replication here:
https://codepen.io/acodeaday/pen/NWMYWNL
I can see that the offending line is
transform: translateX(90%);
But that makes the animation very aesthetically pleasing. So I'm hoping there is a way to solve it while keeping that.
Try using
max-width: 100%!important; height: auto; overflow: hidden!important;
this code whatever you put all of your animation inside. That can be a div. Hope this help~
I have two elements, and the top one's visibility is controlled by a v-if on a simple boolean.
transition(name="fade")
#element1(v-if="showFirst")
p Foo
#element2
p Bar
The first element is wrapped in a <transition> tag, exactly as per the Vue documentation.
However, while this does create a fading animation, the rest of the content on the page still jumps very jarringly.
How can I create a transition that will also smoothly transform the position of any and all siblings that follow?
A fiddle demoing this issue.
You need to use a transition-group and key your dynamic div and static div
<transition-group name="fade">
<div v-if="switc" key="dynamic" class="animated">
...
</div>
<div key="main-content" class="animated">
...
</div>
</transition-group>
And use this css classes
.fade-enter,
.fade-leave-active {
opacity: 0;
transform: translateY(-10px);
}
.fade-leave-active {
position: absolute;
}
.animated {
transition: all 0.5s;
/*display: flex;*/
width: 100%;
}
The real trick is to change position to absolute when leaving, then any other content can take correct position.
To know more about how Vue animate things please see this FLIP explanation post
And please see this working fiddle
https://jsfiddle.net/bjfhth7c/4/
Edit
By mistake I did set display: flex; in .animated class, that was causing to every inner element to render in a strange way.
So now, I completely remove .animate class, and instead apply transition: all 0.5s and width:100% to every direct inner element of .wrapper
My final scss looks like this:
.wrapper {
display: flex;
flex-direction: column;
>* {
transition: all 0.5s;
width:100%;
};
}
.fade-enter,
.fade-leave-active {
opacity: 0;
transform: translateY(-10px);
}
.fade-leave-active {
position: absolute;
}
Flex layout is a extend subject, but in short for this particular case flex-direction: column is arranging elements one bellows previous one.
If one of those elements has absolute position will be ignored in flex layout so any other elements will be redistributed on available space.
Please see this guide about flexbox and last working fiddle hope it helps.
You can use a slideDown/slideUp animation instead. For achieve this you don't need to know a height of a sliding element, the principles of max-height transition explained there.
So, as a result it will cause animated moving of elements below target.
Check out my example based on your fiddle.
vue js provides different transition classes, you have to use those properly to smooth the transition, I have tried with your example in this fiddle with some CSS, have a look.
.fade-enter-active, .fade-leave-active {
transition: all .5s;
height: 100px;
opacity: 0.5;
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
height: 0px;
opacity: 0;
}
Some details from documentation:
There are six classes applied for enter/leave transitions.
v-enter: Starting state for enter. Added before element is inserted, removed one frame after element is inserted.
v-enter-active: Active state for enter. Applied during the entire entering phase. Added before element is inserted, removed when transition/animation finishes. This class can be used to define the duration, delay and easing curve for the entering transition.
v-enter-to: Only available in versions >=2.1.8. Ending state for enter. Added one frame after element is inserted (at the same time v-enter is removed), removed when transition/animation finishes.
v-leave: Starting state for leave. Added immediately when a leaving transition is triggered, removed after one frame.
v-leave-active: Active state for leave. Applied during the entire leaving phase. Added immediately when leave transition is triggered, removed when the transition/animation finishes. This class can be used to define the duration, delay and easing curve for the leaving transition.
v-leave-to: Only available in versions >=2.1.8. Ending state for leave. Added one frame after a leaving transition is triggered (at the same time 7. v-leave is removed), removed when the transition/animation finishes.
You can as well use CSS animations where you can provide on different phases of transition what will be your css property to make your transitions more smooth, like following and demo fiddle:
.fade-enter-active {
animation: bounce-in .5s;
}
.fade-leave-active {
animation: bounce-out .5s;
}
#keyframes bounce-in {
0% {
height: 5px;
}
30% {
height: 30px;
}
50% {
height: 50px;
}
100% {
height: 100px;
}
}
#keyframes bounce-out {
0% {
height: 90px;
}
50% {
height: 50px;
}
100% {
height: 0px;
}
}
I hope that this question is not too specific so it can relate to others problems...
I have two elements, a child and a parent, with the child element rotating around the parent using CSS animations.
<div class="planet">
<div class="moon"></div>
</div>
The moons animation is set so the moon will load ontop of the planet in the same position, but is pushed out with translateX then roatated, like so:
#keyframes myOrbit {
from { transform: rotate(0deg) translateX(200px) rotate(0deg); }
to { transform: rotate(360deg) translateX(200px) rotate(-360deg); }
}
Think of it as a planet with a moon rotating around the planet.
When the user resizes the window the planets height/width will resize, but I also need the moons height/width to resize AND the distance between it and the planet needs to lower.
I have set up an example here... https://codepen.io/anon/pen/mVvYbR
Would this be possible to acheive with just CSS, or would javascript be needed? I will use jQuery if need be, (I am not great at it though) but I would think a pure CSS solution would be cleaner... maybe I'm wrong on that one.
I should also note that the way it is set up currently (with the planet div holding the moon, is so that I can have multiple children (multiple moons). However I also think that this would mean having a massive amount of different animations for moons/planets which need different translateX's... So maybe jQuery is a better solution there...
If I am not clear on anything please let me know.
Thank you!
You can try do it with just css. You can use viewport units so all values will depend on viewport size.
.planet {
width: 10vw;
height: 10vw;
background: url(http://placehold.it/940x940) no-repeat center center;
background-size: contain;
z-index: 1;
}
.moon {
position: absolute;
background: url(http://placehold.it/140x140) no-repeat center center;
background-size: contain;
width: 5vw;
height: 5vw;
-webkit-animation: myOrbit 20s linear infinite;
-moz-animation: myOrbit 20s linear infinite;
-o-animation: myOrbit 20s linear infinite;
animation: myOrbit 20s linear infinite;
}
#keyframes myOrbit {
from { transform: rotate(0deg) translateX(20vw) rotate(0deg); z-index:1}
to { transform: rotate(360deg) translateX(20vw) rotate(-360deg); z-index:2}
}
Sample -> here
Probably you will need to add some media queries to handle different screen aspect ratios. Current viewport units support -> caniuse.com
I got completely stuck on this. I have a container with background image. Inside the container are 3 little circles. What I am trying to do is to zoom the background image when I hover over it and dim the background image when I hover over any of the 3 little circles.
I got to the point where the 3 circles are properly overlapping the container and the background zooms in on hover. But I have 2 issues
no. 1 I am not very fond of the way I am achieving the overlay of the circles, which is this code
#circle_wrap{
position: absolute;
margin-top: -130px;
}
no. 2 Is that I have no clue how to dim the background. My original intention was to have a hidden black conteniner with 0.5 opacity that would be displayed when I hover over one of the circles. But I couldn't figure out how to select the overlay.
JSFIDDLE here
If anything couldn't be solved with css only, I'd accept jquery solution as well.
I'm looking for any advice/tips/solutions you guys have, I really need to get this working.
Thank you.
Finally got so angry I am not able to do it with css that I made it with jquery :(
If anyone is interested here is the result
I have at least fixed the issue no1 with better css but the second is done with jquery.
solved no.1 with
.circle_wrap{
position: absolute; bottom: 0; width: 100%; height: 100px;
}
and applying position:relative on its parent
and the solution for no.2 is
$(".circle_wrap").hover(function () {
$(this).siblings("img").css("opacity", "0.2");
},
function () {
$(this).siblings("img").css("opacity", "1");
});
EDIT: safari support
.wrap img:hover{
-moz-transition: scale(1.1) rotate(0deg);
transform: scale(1.1) rotate(0deg);
-webkit-animation-name: scaleThis;
-webkit-animation-duration:5s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function:ease-in-out;
}
#-webkit-keyframes scaleThis {
0% { -webkit-transform:scale(1) rotate(0deg); }
10% { -webkit-transform:scale(1.1) rotate(0deg); }
100% {-webkit-transform:scale(1.1) rotate(0deg); }
}
Simple (but not for me!) angularjs show/hide animation problem.
I have searched high and low but not found the solution to this specific problem, which can perhaps be best explained with an example and a "challenge".
First, the example: http://jsfiddle.net/adammontanaro/QErPe/1/
The challenge: can anyone make those images fade in and out over each other, rather than appearing below or above the currently shown image, then popping into place once the upper image's div is hidden?
The HTML:
<div>
<div data-ng-repeat="k in kitties" >
<img ng-src="{{k}}" ng-show="selectedImage==$index" ng-animate="{show:'animate-show', hide:'animate-hide'}" />
</div>
</div>
CSS:
.animate-show, .animate-hide {
-webkit-transition:all linear 1s;
-moz-transition:all linear 1s;
-ms-transition:all linear 1s;
-o-transition:all linear 1s;
transition:all linear 1s;
}
.animate-show {
opacity:0;
}
.animate-show.animate-show-active {
opacity:1;
}
.animate-hide {
opacity:1;
}
.animate-hide.animate-hide-active {
opacity:0;
}
I have been spinning my wheels on this for hours. I've seen scads of good posts demonstrating how to make a single image or div appear or disappear, but it all breaks down when I'm trying to simple cross-fade and replace. I've tried messing about with absolute/relative positioning, but to no avail.
Tried this with a switch, but wasn't able to use $index in the switch condition, so I could load my images at run-time. That is a big requirement here.
FYI - this is using angular 1.1.5
Thank you!!! Adam
You actually have it all correct! You're just missing a little CSS.
I fixed up your jsfiddle with the right stuff (a dash of position relative and absolute and a pinch of height) and it works like a charm.
The bulk of the new stuff is:
.container{
position: relative;
/* you have to add a height here if your container isn't otherwise set
becuse the absolutely positioned image divs won't calculate the height
for you */
height: 100px;
}
.image-repeat{
position: absolute;
top: 0;
left: 0;
}
With the classes applied in your HTML as needed.
Check it out: http://jsfiddle.net/QErPe/2/
Hope that helps!
This appears to actually be more of a CSS problem than an angular problem. You need to position the two divs on top of each other and make sure that they are actually occupying the same space at the same time. After that the cross-fading should be a piece of cake.
You can also do plain CSS3 on the .ng-hide class. For example:
div img {
border: medium none;
margin: 0;
padding: 0;
opacity: 1;
-webkit-transition: opacity 1s ease 0s;
-moz-transition: opacity 1s ease 0s;
-o-transition: opacity 1s ease 0s;
transition: opacity 1s ease 0s;
}
div img.ng-hide {
opacity: 0;
}
So now, when the ng-hide class is added, it will fade the opacity of the image. ngAnimate has it's place, but with simple CSS3 on the .ng-hide class, you can eliminate the frustrations.