I'm working on a website (that I didn't design, someone else gave me the HTML/CSS) as a developer and We've got a nice spinner animation for async loading components. It's forever-spinning animation is defined by this CSS rule:
animation: spinning 1s infinite linear; (it has also vendor prefix versions but it's irrelevant).
The spinning animation is defined as:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
Our designer has put a position: absolute !important attribute to the spinning element. I was trying to position it inside some other element and I've thought that attribute was irrelevant. As soon as I removed position: absolute, the spinner stopped spinning. When I added it again, spinner started spinning again.
I've tried other position values too, it seems that absolute and fixed are working okay (in regards to spinning animation) while relative and static cause the animation to stop.
Why would CSS position attribute affect a spinner animation?
Here is a snippet reproducing the problem:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
#first{
position: absolute;
}
#second{
position: relative; /* or don't specify it at all */
}
<div style='background:yellow;width:400px;height:100px;'>
<span id='first' style='animation:spinning 1s infinite linear'>hello</span>
</div>
<div style='background:lime;width:400px;height:100px;'>
<span id='second' style='animation:spinning 1s infinite linear'>hello</span>
</div>
It's because a span is an inline-element by default and so is not affected by transforms.
Setting the position to absolute imparts a block formatting to the span.
Just add display:inline-block:
#keyframes spinning {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
div.one {
background: yellow;
width: 400px;
height: 100px;
}
div.two {
background: lime;
width: 400px;
height: 100px;
}
#first {
position: absolute;
animation: spinning 1s infinite linear
}
#second {
position: relative;
/* or don't specify it at all */
animation: spinning 1s infinite linear;
display: inline-block;
}
<div class="one">
<span id='first'>hello</span>
</div>
<div class="two">
<span id='second'>hello</span>
</div>
Related
Try to do what should be a basic text animation. I have an H1 with three words. Each one has a span with a class in it. That way each word can animate individually.
The second and third are supposed to fade in, and that works, but the first is supposed to slide up and no matter what settings I create in my CSS, it only fades.
So the H1 looks something like this:
<h1><span class="word-one">Word One</span> <span class="word-two">Word Two</span> <span class="word-three">Word Three</span></h1>
And the CSS looks like this:
.word-one { bottom: -200px; animation: slideIn 1s ease-in-out forwards; }
#keyframes slideIn {
100% {
opacity: 0;
}
100% {
bottom: 0;
opacity: 1;
}
}
So why can't I get the text to slide up?
With your code a quick solution can be something like that:
h1 {width: 600px; position: relative;} /* add position so the span will be part of the the header */
h1 span:nth-child(2) {padding-left: 180px;} /* make place for the first word */
.word-one { bottom: -200px; animation: slideIn 1s ease-in-out forwards; position: absolute; } /* added position so the bottom attribute would work */
#keyframes slideIn {
100% {
opacity: 0;
}
100% {
bottom: 0;
opacity: 1;
}
}
<h1><span class="word-one">Word One</span> <span class="word-two">Word Two</span> <span class="word-three">Word Three</span></h1>
I am not seeing anything in your posted code to try and make it slide up, as the CSS makes it fade in/out. I believe there are some JQuery functions to make an element slide up/down if you would like to look into those though. You can also possibly use the position attribute or even margin to do this in pure CSS. The reason that the current code you have posted isn't working though, is because you have 100% for both entries in #keyframes slideIn. To fix this, simply change the top one to 0% like so:
#keyframes slideIn {
0% {
opacity: 0;
}
100% {
bottom: 0;
opacity: 1;
}
}
The problem is that you are using <span>.
<span> by default are display: inline which means it wont respect top/bottom margins. You need to use divs and use float: left. Then use padding-top to keep word-one at the bottom and then animate to top by giving padding-top: 0
Here is your solution.
.word-one {
padding-top: 200px;
animation: slideIn 1s ease-in-out forwards;
}
.word-one, .word-two, .word-three {
float: left;
}
#keyframes slideIn {
0% {
opacity: 0;
}
100% {
padding-top: 0;
opacity: 1;
}
}
<h1>
<div class="word-one">Word One</div>
<div class="word-two">Word Two</div>
<div class="word-three">Word Three</div>
</h1>
I have a div element, which has an animation to play when starting the page. I want to make it have another animation to play when I'm hovering over it. It works just fine, but when I get my mouse out of the div element, it plays the starting animation again (fades in from out of the screen).
#keyframes div{
0%{
opacity: 0;
}
}
#keyframes divHover{
50%{
top: 200px;
}
100%{
top: 0px;
}
}
#div{
opacity: 1;
animation: div 1s;
position: absolute;
left: 0px;
top: 0px;
}
#div:hover{
animation: divHover 1s linear 0s infinite;
}
<div id="div"> abc </div>
Expected:
Div starts invisible and fades in. When hovering div, it goes up and down, and keeps doing it while hovering. After stopping the hover, div stops the animation and keeps its full opacity
Actual:
After stopping the hover, div stops the animation but returns to 0 opacity, then takes one second to display the starting animation again.
https://jsfiddle.net/odq125Lu/6/
The issue is due to the fact that you are overriding the first opacity animation with the up & down one then when you unhover you active the first one again.
You can use multiple animations and consider animation-play-state to activate the second one:
#keyframes div {
0% {
opacity: 0;
}
}
#keyframes divHover {
50% {
top: 200px;
}
100% {
top: 0px;
}
}
#div {
opacity: 1;
animation:
div 1s,
divHover 1s linear 0s infinite;
animation-play-state:running,paused;
position: absolute;
left: 0px;
top: 0px;
background:red;
padding:20px;
}
#div:hover {
animation-play-state:running,running;
}
<div id="div"> abc </div>
I'm no expert, but it may have something to do with the fact that you haven't set a 100% value for the animation "divHover"?
#keyframes div{
0%{
opacity: 0;
}
100% {
opacity: 1;
}
}
I have a problem and the answer I found are not precise enough.
I have 2 DIV. A div at left:-100%; and a div at left:100%;
I would like in ONE animation, animate those div to smoothly go from their actual Left, to left:0%;
i tried adding just
.animSlide{
animation-duration: 0.5s;
animation-iteration-count: 1;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-name: anim;
}
#keyframes anim {
to {
left: 0%;
}
}
But this brake all steps on animation. I mean, after 0.5s my div go from actual left to 0%;
So, is there a way to say
#keyframes anim {
from{
left:current%;
}
to {
left: 0%;
}
}
Thx for help
EDIT : The ABOVE code should work. So my problem come from another part of the code...
This is what i do basically : https://jsfiddle.net/Crocsx/rwyt400n/
Answer based on the JSFiddle provided in comment by the author.
This is not a very good answer because I only have an hypothesis about the problem, however I have a solution.
The problem, I think, is that the value of left after the animation is "virtual". When you start the second animation (by putting the class "slide_to_right") it look at the real value which is still 100%, even though you see it as 0%, and start the animation from this point (that's why it is not animated from 0%).
Because you are using JS to change the state of the elements, instead of using animations, you can use transitions. It will allow your element to be animated automatically when changing between the 2 states and it is easier to set in this case (less code).
Thanks to this property, all you have to do is set the transition property on your sliding element. And then change its state in JS. In this case you want to alternate between left:100% and left:0%. So the transition property is written like this : transition: left 5s;.
To set the different left values, you can directly change the style in JS. Or have a class prepared in your css and add this class to your element. In this case, 2 classes .left and .right work great.
The transition will take care of the animation.
Here is the code : https://jsfiddle.net/rwyt400n/4/ (I changed the id to classes).
I think this is what you're looking for:
#-moz-keyframes dropHeader {
0% {
-moz-transform: translateY(-100px);
}
100% {
-moz-transform: translateY(0);
}
}
#-webkit-keyframes dropHeader {
0% {
-webkit-transform: translateY(-100px);
}
100% {
-webkit-transform: translateY(0);
}
}
#keyframes dropHeader {
0% {
transform: translateY(-100px);
}
100% {
transform: translateY(0);
}
}
you can specify a css property value that you want the animation to begin with, and end with. you can also split this keyframe into more than just 0% and 100%.
For ex.
#keyframes dropHeader {
0% {
transform: translateY(-100px);
}
25% {
transform: translateY(-75px);
}
50% {
transform: translateY(-50px);
}
75% {
transform: translateY(-25px);
}
100% {
transform: translateY(0);
}
}
See this fiddle.
HTML:
<div class="wrapper">
<div class="div1"></div>
<div class="div2"></div>
</div>
CSS:
.wrapper {
height: 200px;
width: 100px;
margin-left: 100px;
}
.div1 {
width: 100px;
height: 100px;
background: red;
position: relative;
left: -100%;
animation: anim 5s;
}
.div2 {
width: 100px;
height: 100px;
background: black;
position: relative;
left: 100%;
animation: anim 5s;
}
#keyframes anim {
to {
left: 0;
}
}
heyo fellows gotta question, i have to make a picture that gets a bit transparent (like opacity 0,4), then it size increases like 2x and becomes untransparent again (opacity 1)
and the text all that time doesnt change its position.
img {
opacity: 1;
width: 250;
}
img:hover {
opacity: 0.4;
filter: alpha(opacity=40);
width: 500px;
transition-property: width;
transition-duration: 4s;
}
i've made a css code only for size increasing and transparency, however no idea how to make it opacity 1 again after my 4sec animation and no idea how to make the text stay in the very same position after image size increases.
Here is one solution but without more information it's hard to give you the best possible answer. You can only apply effect on hover with css, which means that picture will go back to normal once the picture is not hovered anymore. If you want a solution that will go back to normal automatically after 4s then you should use javascript.
.wrapper {
width: 100%;
}
figure {
display: inline-block;
width: 120px; /* It has to be bigger than twice the size of your picture if you don't want the text to move */
}
img {
width: 50px;
height: auto;
-webkit-transition: width, 0, 4s;
transition: width, 0, 4s;
}
img:hover {
width: 100px; /* twice the original size */
opacity: .4;
}
.text {
display: inline-block; /* so that your text is aligned with picture */
vertical-align: top; /* so that your text doesn't move */
}
<div class="wrapper">
<figure>
<img src="http://lorempixel.com/100/100">
</figure>
<div class="text">
Some text...
</div>
</div>
Hi I did not understand your problem properly. But here I think you wanted something like this.
HTML
<img src="http://t3.gstatic.com/images?q=tbn:ANd9GcTCrT41Zwh43blojDO5tgu1qnsCXbz1Eu6dBiHipmGKjw-oAr7s8Q" alt>
CSS
#keyframes lI{
0%{opacity:1; transform: scale(1);}
50%{opacity:0.4; transform: scale(1.3);}
100%{opacity:1; transform: scale(1.3);}
}
#-webkit-keyframes lI{
0%{opacity:1; -webkit-transform: scale(1);}
50%{opacity:0.4; -webkit-transform: scale(1.3);}
100%{opacity:1; -webkit-transform: scale(1.3);}
}
img{
display: block;
opacity: 1;
transform: scale(1);
-webkit-transform: scale(1);
}
img:hover{
animation: lI 4s linear 1 forwards;
-webkit-animation: lI 4s linear 1 forwards;
}
Please check this Fiddle http://jsfiddle.net/e7zfwncn/1/. It uses CSS3 animation.
Make sure you add your transition in CSS to the img and not hover, then you will get the transition to work on both the mouse in and mouse out.
http://jsfiddle.net/shannabarnard/v7c9y6qj/
HTML
<img src="http://www.w3schools.com/tags/smiley.gif" alt="Smiley face" height="42" width="42">
CSS
img {
opacity: 1;
transition: all 4s ease;
}
img:hover {
opacity: 0.4;
filter: alpha(opacity=40);
width: 84px; /* twice the original size */
height: 84px; /* twice the original size */
}
I have read about how using translate has better performance, but it seems they behave slightly differently: using left:100% moves the animated object all the way to the end of the screen, whereas translate(100%) only moves the animated object as far as its length. That is, it moves 100% of the screen versus 100% of the object.
Can explain why this is, and what can be done to reproduce the same behavior when using translate?
You can see a demo here: http://jsfiddle.net/32VJV/1/
.slide_1 {
top: 0px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_1 {
-webkit-animation: slide 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
.slide_2 {
top: 25px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_2 {
-webkit-animation: slide2 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
#-webkit-keyframes slide {
0% {
-webkit-transform: translate(0%);
}
50% {
-webkit-transform: translate(100%);
}
100% {
-webkit-transform: translate(0%);
}
}
#-webkit-keyframes slide2 {
0% {
left 0%;
}
50% {
left:100%;
}
100% {
left:0%;
}
}
<div style="font-size:18px;">
<div class=""> <span class="slide_1" id="dimensions">ABC</span> <span class="slide_2" id="dimensions">ABC</span>
</div>
</div>
The difference between the two is that animating a property like left will keep the element in the flow of the document whereas translate does not.
For more information on why you might use one or the other, Paul Irish has an excellent write up (with links to more information): Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
There's also a lot of great information on browser performance at jankfree.org
Solution for the translate animation: make the element as wide as the window:
Example
slide_1 {
top: 0px;
left:0%;
right: 0;
position: absolute;
overflow: hidden;
font-size: 30px;
}
An interesting exercise: Open your devtools and what what happens when you activate one animation at a time.
In Chrome:
The translate animation has basically nothing going on except a periodic GC
The Left animation you will see repeatedly:
Recalculate Style
Layout
Pain Setup
Paint
Composite Layers
In this case, the overhead it pretty small, but that can change quickly depending on what is being moved around the screen.