CSS3 keyframe animation on 100% width/height backgrounds - css

I am trying to animate background of an element that is 100% wide and tall. It is a simple CSS3 animation using steps to go through the sprite image.
The animation looks like this:
.play-intro{animation: play 2s steps(6);}
#keyframes play {
from { background-position: 0 0 ; }
to { background-position: -7800px 0 }
}
The issue is that I am seeing each sprite change, it is not working as it should be. I don't know, but I believe it is maybe due to background-size:cover property. Any advice on this?
I created a fiddle to recreate the issue:
http://jsfiddle.net/QKwjM/1/
And this is the fiddle in fullscreen, the issue is best seen there.
http://jsfiddle.net/QKwjM/1/embedded/result/

If you set
background-size: cover;
the background-size is variable (adjusts to the space) and that breaks the animation.
Since your last keyframe is -7800px, the background-size-x must be exactly that
background-size: 7800px 701px;

Related

Can divs below a css transform move along with divs above?

I am using css transitions to lay out a bunch of divs on top of each other. At any point, one of the divs may collapse. And all of the divs below it are supposed to move up to fill its spot.
Here is a codepen that describes the situation.
The css I am using is the following:
div {
height: 100px;
width: 100px;
margin: 15px;
}
.top {
background-color: red;
transform-origin: top;
animation: move 2s infinite;
}
.bottom {
background-color: blue;
}
#keyframes move {
0% {
transform: rotateX(0deg);
}
50% {
transform: rotateX(90deg);
}
}
With this, the top div will expand and contract. I want the divs below it to move up as the top one collapses.
If I switch transform for height, like this:
#keyframes move {
0% {
height 0;
}
50% {
height: 100px;
}
}
The bottom divs do move, but this is not a good solution for me because in the actual application, each div has a dynamically calculated size.
How can the bottom divs move smoothly with the top div?
With transform you won't be able to do that, as when an element is transformed, the surrounding elements won't see any change in the DOM, as DOM-wise nothing have happened.
What you can do to optimize it all, is to prepare the browser that the height will change, with the property will-change: height
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
This new CSS property aim's to do what transform does, make smoother and more optimized animations.
Do note though:
will-change is intended to be used as a last resort, in
order to try to deal with existing performance problems. It should not
be used to anticipate performance problems.
Another possible solution (read hack), is to trick the browser to use GPU instead of CPU, shown in this answer (see its p.1):
CSS `will-change` - how to use it, how it works
Updated
In case of the height is auto, or similar, this will work with the max-height trick, and here is a couple of answers of mine, showing how-to:
CSS Animation on max-height change
Can't use the same animation in reverse for class toggle
CSS transition auto width
And the last resort, if none of the above is applicable, is to use a small script and either create a styles dynamically (links below), or set them inline.
Dynamically styling pseudo-elements using jQuery or Javascript
How to prevent css from getting converted to inline css

CSS Animation in Firefox... clip-path: inset()

I have an animation that is working beautifully in Chrome but is not registering at all in Firefox. It is an animation that mimics how an old tv might turn on. Starting from the middle of the 'box' spreading into a horizontal line, and then finally spreading upwards and downwards simultaneously to fill the 'box'.
The following is my CSS.
#keyframes tvOn{
0%{
clip-path: inset(49.9% 49%);
}
45%{
clip-path: inset(49.9% 0%);
}
100%{
clip-path: inset(0% 0%);
}
}
#box{
...
animation: 1s ease tvOn;
...
}
Is inset what is not supported? I even tried 'rectangle' and 'polygon' but neither seem to work. If you know of a Firefox polyfill that can solve this problem or an alternative I appreciate it. This clip-path inset is working beautifully, I can't achieve the same result this easily with any other css property I've tried. Even animating the width and height is tricky because those grow from the top left corner, instead of the direct center/middle of a 'box'.
Also I don't want to animate the box growing a bigger size, its more about revealing a completely hidden box in a unique way slowly across both axes to make it seem like a tv turning on.

svg blurring while zooming

I've create a svg image, now the problem is i'm trying to animate that image with css3 animations
#keyframes animate {
from {transform: scale(1);}
to {transform: scale(10);}
}
but the image is blurring during the animation, and immediately become fine after the animation.
Is there any solution for not blur the image during the animation?
This happens with all elements regardless of whether or not they're SVG. The browser doesn't recalculate the dimensions and such until the element is done animating.
You can try forcing the GPU to render it by adding translate3d(0,0,0) or translateZ(1px), but I am unsure if this will actually help the rendering.
As such, you should set the initial value to the smaller one and animate to scale(1) instead. In your case the smaller value would be scale(.1)
You can try animating width and height instead of transform.
#keyframes zoomSize {
from { width: 30px; height: 30px; }
to {width: 300px; height: 300px; }
}
Here's a running example.

background-size cover fade transition without size transition

I have a div where I'm changing the background (using jQuery). These CSS3 rules allow the new background image to crossfade in nicely
transition: background-image 1s ease-in-out;
background: center center no-repeat;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
The issue is that the background size is also transitioning.
So if it switches from a portrait to a landscape background image, for example, while fading, the image gets squished vertically and then stretched horizontally. This can be a bit nauseating.
Is there any way to use background-size: cover but to only fade transition the background image itself without the background size?
I worked around the unintended size animation by:
having two divs, absolutely positioned on top of each other
cycling their opacity (eg one to 0, and the other to 1)
putting the css transition on the opacity, rather than background-image.
This achieves a cross-fade between the background images of the divs. If you have more than 2 images to cycle, either use more divs, or change the background-image of the one you are setting the opacity to 1.
That's just... weird. background-image isn't supposed to be animatable in the first place. On the other hand, background-size can be animated, but it's very clear from your CSS that you don't want to transition background-size. Yet, your browser chooses to animate it along with the image anyway.
Whatever your browser is doing, it's obviously ignoring the spec and just doing its own thing. Since background-image isn't animatable using CSS (I know Firefox and IE don't support it), and your background transition is already being handled with jQuery anyway, I suggest using jQuery instead of CSS to implement the crossfade to ensure it'll work consistently across browsers.

Repeating background gradient in Chrome

In this pen, the position of the repeating background gradient is animated. This makes Google Chrome render the background gradient wrong. It works fine in Mozilla Firefox.
How can I fix it?
For my body background gradient I used this:
background-image: repeating-linear-gradient(40deg, #d61e29 0px, #661011 40px);
and the animation is bg:
animation: bg 15s infinite linear;
I believe it's related to this bug - https://code.google.com/p/chromium/issues/detail?id=162538. If you remove your setting the background size to 200% you see the gradient clears up somewhat. If you reduce it to 50% it becomes smooth. I think you're going to have to take another approach to the animated background. Also notice setting the angle to 0 gives smooth gradient.
Try giving a fixed background size, in effect tiling it, so that the tiles seem nicely. background-size: 100px 100px; not sure the exact size to get the seems right. Here is a code pen - http://codepen.io/anon/pen/vuFod;
background-size: 100px 100px
background-image: -webkit-repeating-linear-gradient(45deg, #d61e29 0px, #661011 71px);

Resources