I was trying to create a pure css3 image slider with infinite continuous slide animation. I was able to do the animation using CSS3 but a small issue facing at the end of last slide. After last slide it gets suddenly to the first slide without css3 smooth transform effect. Any simple possible way to fix this ?
Here is the code
#slideshow{
position: relative;
width: 200px;
height: 400px;
overflow: hidden;
border: 5px solid #fff;}
#slideshow img{
position: absolute;
left: 0;
top: 0;
animation: slide 5s infinite;
}
#keyframes slide{
0%{ transform:translateX(0px) }
33%{ transform:translateX(-200px) }
66%{ transform:translateX(-400px) }
100%{ transform:translateX(-600px) }
}
<div id="slideshow"><img src="http://oi67.tinypic.com/24mia39.jpg"></div>
jsFiddle link
You haven't animation after last side because your animation is finish. Maybe add a transform effect like :
#keyframes slide{
0%{ transform:translateX(0px) }
25%{ transform:translateX(-200px) }
50%{ transform:translateX(-400px) }
75%{ transform:translateX(-600px) }
100%{ transform:translateX(0px) }
}
jsFiddle link
Related
I'm trying to make a div that appear and disappear on touch, like the navigation bar of android phones.
Should I use transition for this or is animation ok? In the fiddle example i use the mouse click and the setTimeout to simulate the touches and the auto disappear if you dont touch the screen for some seconds.
.custom-row{
position: fixed;
width: 100%;
height: 50px;
bottom: -100px;
left: 0px;
background-color: yellow;
opacity: 0;
}
.slidein {
animation: slidein 1s ease-in forwards;
}
.slideout {
animation: slideout 1s ease-in forwards;
}
#keyframes slidein {
0% {
}
100% {
bottom: 0px;
opacity: 1;
}
}
#keyframes slideout {
0% {
bottom: 0px;
opacity: 1;
}
100% {
bottom: -100px;
opacity: 0;
}
}
https://jsfiddle.net/1rm64q8z/1/
For this use case, transition seems to be a better solution. With animation, alerting position is a compute-intensive approach. The CSS will also be much more readable and scalable with transitions in this case.
const bar = document.getElementById("bottom-bar");
bar.addEventListener("click", (el) => {
el.target.classList.toggle("slide-out");
setTimeout(() => {
el.target.classList.toggle("slide-out");
el.target.classList.toggle("slide-in");
}, 2000)
})
body {
overflow: hidden;
}
#bottom-bar {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
background: yellow;
padding: 16px;
text-align: center;
transform-origin: bottom;
transition: transform 0.4s ease-in-out;
}
.slide-in {
transform: translateY(0%);
}
.slide-out {
transform: translateY(100%);
}
<div id="bottom-bar">
Hello
</div>
The performance of CSS transitions and animations should be almost the same as they are both hardware accelerated so on most modern browsers the behaviour should be the same.
Animations are often used to create a more complex series of movements and they do not lift the rendering process to the GPU and resulting in being slower than transitions.
This article gives a great breakdown of when to use animations vs transitions.
This is my first time asking a question on here and I've found questions that are somewhat similar, but haven't worked for my issue.
I am trying to spin a word across the screen from off-screen left to off-screen right. The center of the word should be it's rotation point (ie word spins in place from left side of screen to right). I have tried using variations of translateX and rotate, but it either rotates in place or moves left to right. When it does move from the left to right off the screen, it keeps extending the bounds of my screen and stretching it before it loops back to the left side. Any ideas how I can solve this? Seems simple, but I'm terrible with animations.
.move {
position: absolute;
animation: moveword 10s infinite linear;
}
.spin {
position: absolute;
animation: spin 7s infinite linear;
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes moveword {
from {
left: -10%;
}
to {
left: 95%;
}
}
Based on code that you provide, I assume you could make something like this.
overflow: hidden needs to be applied to separate element, not the <body> because it restricts scrolling.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.page {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.word {
position: absolute;
top: 5px;
left: 5px;
animation: word-anim 10s infinite linear;
}
#keyframes word-anim {
0% {
transform: translateX(0px) rotateZ(0deg);
}
70% {
transform: translateX(70vw) rotateZ(360deg);
}
100% {
transform: translateX(100vw) rotateZ(360deg);
}
}
<div class="page">
<span class="word">A word</span>
</div>
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 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.