CSS transform animation doesn't work in Chrome - css

The animation I created gradually slides in the element with the class of .overlay from right to left in .4 seconds by adding the .overlay-appear class to it on click. It works perfectly in Mozilla. In Chrome the slide effect doesn't take place, the element simply appears when I click that specific button. I added the vendor prefixes to keyframes, animation and transform, but the problem still persists. Maybe I'm missing something?
Here's the CSS that is relevant to the problem:
.overlay {
position: fixed;
background-color: rgb(49, 49, 49);
z-index: 100;
top: 0;
right: 0;
width: 0%;
height: calc(100vh - 25px);
display: none;
flex-direction: column;
justify-content: flex-start;
align-items: flex-end;
padding: 25px 50px 0 0;
}
.overlay-appear {
animation: appear .4s forwards;
-webkit-animation: appear .4s forwards;
width: 50%;
display: flex;
transform-origin: right;
-webkit-transform-origin: right;
}
#keyframes appear {
0% {
transform: scaleX(0%);
}
100% {
transform: scaleX(100%);
}
}
#-webkit-keyframes appear {
0% {
-webkit-transform: scaleX(0%);
}
100% {
-webkit-transform: scaleX(100%)
}
}

You missed the fact that transfrom:scale(); only takes simple integers (not measurements of any kind.). I don't know why Firefox CSS engine accepts that. But to make the code legal change the values.
#keyframes appear {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
The scaleX(1) means the actual size of the div as specified by its code. Any other measure there means the relative scale (and not any absolute measure).

Related

How can you use CSS to animate a rolling element across the screen repeatedly?

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>

I'm trying to correct the animation duration and timeline of infinite flip, rotation, spin and disappearance of three images in pure CSS

I tested with the following answers:
Pure CSS rotate animation broken while in infinite loop
Stop infinite CSS3 animation and smoothly revert to initial state
CSS Image Fade Animation Only Runs First Time,
but the animation duration and timeline (for example, from step by step, from start to end) did not work. The three images need to be in the same place at once.
I wanted to use https://codepen.io/jay-bee-why/pen/Htejl, but unfortunately I do not want to use jQuery. I am CSS and JavaScript purist.
An image is worth a thousand words. You will understand easily the image. I also provide very small snippet code box.
.flipping-images
{
align-items: center;
display: flex;
flex-flow: row nowrap;
height: 80%;
justify-content: center;
/* opacity: 0; */
position: relative;
transform: translateX(100%);
width: 22%;
}
.show-l
{
animation: show-image 5s ease-in-out 300ms infinite;
left: 0;
position: absolute;
transform-origin: left;
}
.hide-l
{
animation: hide-image 5s ease-in-out 800ms infinite;
position: absolute;
transform-origin: left;
}
.hide-l2
{
animation: hide-image 5s ease-in-out 600ms infinite;
position: absolute;
transform-origin: right;
}
#keyframes hide-image
{
0%
{
left: 0;
transform: rotateY(0deg);
}
30%
{
left: 10%;
transform: rotateY(0deg);
}
50%
{
opacity: 1;
}
100%
{
left: -100%;
opacity: 0;
transform: rotateY(90deg);
}
}
#keyframes show-image
{
0%
{
left: 100%;
transform: rotateY(90deg);
}
30%
{
left: 110%;
transform: rotateY(90deg);
}
100%
{
left: 0%;
transform: rotateY(0deg);
}
}
<div class="flipping-images">
<img class="show-l" src="https://via.placeholder.com/432x864/fdc34f/FEFEFE?text=1">
<img class="hide-l2" src="https://via.placeholder.com/432x864/3e72ff/FEFEFE?text=2">
<img class="hide-l" src="https://via.placeholder.com/432x864/222222/FEFEFE?text=3">
</div>
I'm not sure I understand your image since it says the second image should disappear but it also says the animation is infinite. I hope it's working as you intended, if not just leave a comment on what needs to be fixed.
I'm using the animationend event to control the animations.
var counter = 1;
var div = document.querySelector('.flipping-images');
var images = document.querySelectorAll('.flipping-images img');
var showNext = function () {
counter++;
if (counter > 3) counter = 1;
div.classList.remove('image1', 'image2', 'image3')
div.classList.add('image'+counter);
};
for (var img of images) {
img.addEventListener('animationend', showNext);
img.addEventListener('click', showNext);
}
document.querySelector('#next').addEventListener('click', showNext);
.flipping-images {
perspective: 300px;
}
.flipping-images img {
display: none;
animation: rotate 5s linear 1;
}
.flipping-images.image1 img:nth-child(1),
.flipping-images.image2 img:nth-child(2),
.flipping-images.image3 img:nth-child(3) {
display: block;
}
.flipping-images.image2 img:nth-child(2) {
animation: rotate 5s linear infinite;
}
#keyframes rotate {
0% { transform: rotateY(-45deg); }
100% { transform: rotateY(45deg); }
}
button {
margin: 1em;
}
<div class="flipping-images image1">
<img src="https://via.placeholder.com/100x100/fdc34f/FEFEFE?text=1">
<img src="https://via.placeholder.com/100x100/3e72ff/FEFEFE?text=2">
<img src="https://via.placeholder.com/100x100/222222/FEFEFE?text=3">
</div>
<button id="next">Next</button>

Long CSS animation easing (background-position)

I'm trying to animate a background image position smoothly with CSS over a longer period, let's say 60 seconds:
#movingbackground {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Bigsurflowers.jpg/1280px-Bigsurflowers.jpg');
overflow: hidden;
background-position: left center;
animation: zoomin 60s ease-in infinite;
}
#-webkit-keyframes zoomin {
0% { background-position: 0% center; transform: scale(1.0); }
50% {background-position: 100% center; transform: scale(1.2); }
100% { background-position: 0% center; transform: scale(1.0); }
}
#keyframes zoomin {
0% { background-position: 0% center; transform: scale(1.0); }
50% {background-position: 100% center; transform: scale(1.2); }
100% { background-position: 0% center; transform: scale(1.0); }
}
<div id="movingbackground"></div>
The small movements in the beginning and end are "jumping" a few pixel every second instead of moving slowly (may depend on screen size).
The reason for that is probably that there is not enough movement to fill the required number of frames, especially when the animation is eased. As I think I have seen this effect working smoothly somewhere I wonder how to work around this.
Here's a Fiddle as well.
Animation of background-position makes browser to do layout, paint and composite.
Re-layout and re-paint are heavy on CPU and cause "jumping".
Instead of that, you might apply your background to pseudo-element (or use <img> in your HTML) and animate its transform property using 3d transformation.
It will make browser to use GPU for the animation and animation will run in composition phase pretty smoothly.
See the snippet below:
html,
body {
margin: 0;
padding: 0
}
#movingbackground {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#movingbackground:before {
content: '';
position: absolute;
top: 0; left: 0; z-index: -1;
height: 100%;
width: 200%;
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Bigsurflowers.jpg/1280px-Bigsurflowers.jpg) 0 50% / cover;
animation: zoomin 60s ease-in infinite;
}
#keyframes zoomin {
50% {
transform: translateX(-50%) scale(1.2)
}
}
<div id="movingbackground"></div>
I did some testing and came to the conclusion that it's probably impossible. (At least with transitions or animations)
The problem is the way browsers render images on a screen. The pixels of the image apparently get lined up with those of your screen.
So the picture always "jumps" exactly one pixel at a time.
That means, that the more pixels you have in your image, the more steps it will make. But when using ease-in it will always stutter in the beginning.
As I think I have seen this effect working smoothly somewhere
That was probably not realized with css.

How to avoid sharp jumps between speeds in css animation

I need to create infinite animation that will start with fast rotation ( e.g. 1 second) then gradually slow down (within another e.g. 1 second) and then continue on the very slow speed (for the remaining e.g. 8 seconds). The problem is - rotation speed changes with very sharp jumps - on 10% and 20%.
Can I control transition between animation speeds? I tried to override speed jump by adding more percentages but it just gives second jump after 20% when speed changes.
html {
height: 100%;
}
body {
height: 100%;
background: #333;
display: flex;
align-items: center;
justify-content: center;
}
.bar {
background: cyan;
width: 100px;
height: 10px;
}
.bar {
animation: rotation 10s linear infinite;
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
10% {
transform: rotate(1600deg);
}
11% {
transform: rotate(1620deg);
}
12% {
transform: rotate(1640deg);
}
13% {
transform: rotate(1660deg);
}
14% {
transform: rotate(1680deg);
}
15% {
transform: rotate(1700deg);
}
16% {
transform: rotate(1720deg);
}
17% {
transform: rotate(1740deg);
}
18% {
transform: rotate(1760deg);
}
19% {
transform: rotate(1800deg);
}
20% {
transform: rotate(1820deg);
}
100% {
transform: rotate(2160deg);
}
}
<div class="bar"></div>
You can use multiple animations: one for the initial spin with deceleration (take a look at the easing functions. In this case I'm using ease-out which mimics basic deceleration) and a second (delayed to run after the first finishes) to be linear. You'll have to play around with the values of degrees and duration to match the speed of rotation from the first animation with the linear speed of the second, otherwise you'll see the speed jump quickly (your problem in the first place). Here's an example:
html {
height: 100%;
}
body {
height: 100%;
background: #333;
display: flex;
align-items: center;
justify-content: center;
}
.bar {
background: cyan;
width: 100px;
height: 10px;
}
.bar {
animation: rotationDecelerate 2s ease-out, rotationLinear 2s linear 2s infinite;
}
#keyframes rotationDecelerate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(2160deg);
}
}
#keyframes rotationLinear {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="bar"></div>
It's just a matter of fiddling with the numbers.
I removed all the intermediate transformations between 10 and 20%. The animation calculates the position of the element based on timing functions and the sort between the two points.
The reason why you were getting a big jump is that you were trying to control every intermediate step between 10 and 20 but the animation had to be at a certain point at 20%. Let the browser control everything between 10 and 20% since you want a smooth slowdown. The timing function takes into account where you started and where you want to end, so it tries to smooth everything out for you. The more defined every percentage point is, the more stilted the animation will be.
I also played around with the values a little bit. You can put them back how you want them, but I just wanted to see how it would affect the animation if the first sec was 5 rotations, then the next second was 1 rotation, and then last 80% was one rotation. It just seemed proportional to me, and the animation looked smoother. But, I recommend playing with the degrees until you get what you want.
html {
height: 100%;
}
body {
height: 100%;
background: #333;
display: flex;
align-items: center;
justify-content: center;
}
.bar {
background: cyan;
width: 100px;
height: 10px;
}
.bar {
animation: rotation 10s linear infinite;
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
10% {
transform: rotate(1800deg);
}
20% {
transform: rotate(2160deg);
}
100% {
transform: rotate(2520deg);
}
}
<div class="bar"></div>

Css Animation not working correct

I have to elements and I want to animate them seperatly. Element one should play animation one and element two should play animation two.
But when I test it element one plays both animations and element two none.
This is not happening if I start the animation of element two with a delay, but this is no solution...
Here's element one:
#wrapper_splashscreen #logo {
position: absolute;
left: 50%;
top: 50%;
width: 200px;
height: 200px;
margin-top: -100px;
margin-left: -100px;
-webkit-animation: logoIntro 0.5s 1; }
#-webkit-keyframes logoIntro
{
0% {
-webkit-transform: scale(0, 0);
opacity: 0;
}
80% {
-webkit-transform: scale(1.4, 1.4);
}
90% {
-webkit-transform: scale(1.1, 1.1);
}
100% {
-webkit-transform: scale(1, 1);
opacity: 1;
}
}
and here's element two:
#wrapper_splashscreen #menu {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 40px;
background: #151515;
-webkit-animation-name: menuIntro 1s 1; }
#-webkit-keyframes menuIntro
{
0%, 30% {
bottom: -40px;
}
100% {
bottom: 0px;
}
}
The logo (element one) is fadeing in and moving down and the menu (element two) is doing nothing.
In the second element you've an error:
-webkit-animation-name: menuIntro 1s 1;
It should be -webkit-animation.
I'm not sure what's the problem with the first element (please add a fiddle/demo), buy maybe setting a transform-origin will help
It seems like the animation becomes buggy when you navigate to the animated element with an anchor. The browser navigates to the element while its moving and the animation gets broken.

Resources