Pause and reverse CSS animation on hover - css

I have a 11 frame png spritesheet. When you hover it will play the animation until the last frame and then pause, and when you hover out it will reverse the animation back to the first frame. I have this so far:
.intern {
width: 328px;
height: 187px;
background-image: url("http://i.imgur.com/zNsJCnM.png");
-webkit-animation: in 0.5s steps(11);
}
.intern:hover {
-webkit-animation: out 0.5s steps(11);
}
#-webkit-keyframes in {
from {
background-position: 0px 0px;
}
to {
background-position: 0px -2057px;
}
}
#-webkit-keyframes out {
0% {
background-position: 0px 0px;
}
100% {
background-position: 0px -2057px;
}
}
<div class="intern"></div>
JS Fiddle: http://jsfiddle.net/os2jm4h5/
Can someone help me out? I would like to do this with CSS (no JavaScript please) and preferably should use only one div.

This is possible with a few changes to CSS:
Add background-position: 0px -1683px; to .intern:hover. This will ensure that the animation "pauses" on the final frame. Currently when the hover animation finishes background-position goes back to 0px 0px;.
Reverse background-position in from and to for #-webkit-keyframes in
Reverse background-position in 0% and 100% for#-webkit-keyframes out
.intern {
width: 328px;
height: 187px;
background-image: url("http://i.imgur.com/zNsJCnM.png");
-webkit-animation: in 0.5s steps(11);
}
.intern:hover {
-webkit-animation: out 0.5s steps(11);
background-position: 0px -1683px;
}
#-webkit-keyframes in {
from {
background-position: 0px -2057px;
}
to {
background-position: 0px 0px;
}
}
#-webkit-keyframes out {
0% {
background-position: 0px 0px;
}
100% {
background-position: 0px -2057px;
}
}
<div class="intern"></div>
Note that background-position: 0px -1683px; is used because the last image in the sprite sheet (background-position: 0px -2057px;) is actually a copy of the first frame.

Related

Define CSS variables inside animation and trigger inner animation from variable inside animation

I'm investigating if I can create a glow effect to jQuery Terminal underline cursor animation that is created with box-shadow.
TL;DR at the bottom there is a demo that is my attempt to define CSS variables inside the animation.
The way to change the animation in jQuery Terminal is to set variable:
:root {
--animation: terminal-underline;
}
and underline animation look like this:
#keyframes terminal-underline {
0%, 50% {
box-shadow: 0 2px 0 #aaa;
box-shadow: 0 2px 0 var(--original-color, #aaa);
}
50.1%, 100% {
box-shadow: none;
}
}
See Demo
To keep the current API of setting animation, my first attempt was to create an inner pseudo-element that will have a height of 2px that will be in the same place as a current underline cursor. To animate it I came up with this hack:
:root {
--size: 1.4;
--glow: 1;
--animation: terminal-underline-2;
}
#keyframes terminal-underline-2 {
0%, 50% {
--terminal-underline: terminal-underline-pseudo 1s infinite linear;
}
50.1%, 100% {
--terminal-underline: terminal-underline-pseudo 1s infinite linear;
}
}
.cmd-cursor [data-text] {
position: relative;
}
.cmd-cursor [data-text]::before {
position: absolute;
content: '';
display: block;
width: 100%;
z-index: 100;
height: 2px;
bottom: -2px;
animation: var(--terminal-underline);
}
#keyframes terminal-underline-pseudo {
0%, 50% {
box-shadow: 0 2px 0 #aaa;
box-shadow: 0 2px 0 var(--original-color, #aaa),
0 2px calc(var(--glow) * 5px) var(--original-color, #aaa);
}
50.1%, 100% {
box-shadow: none;
}
}
But it doesn't work. If I set the animation terminal-underline-pseudo manually it works fine, but I need to trigger it when the main CSS variable --animation is set to terminal-underline.
this works:
.cmd-cursor [data-text]::before {
animation: terminal-underline-pseudo 1s infinite linear;
}
But I need that animation to be conditional.
I also can't use terminal-underline-pseudo as my main animation because box-shadow is outside of the cursor box, not around the border. The original animation use trick where box-shadow x is 0 so only the bottom part of the box-shadow is visible.
Here is the POC of this, but it doesn't work. In Chrome, it shows the color as red but in Firefox it doesn't work at all:
#keyframes animation-var {
0%, 100% {
--anim: animation-inner 1s infinite linear;
--color: red;
}
}
#keyframes animation-inner {
0%, 50% {
background: black;
color: white;
}
50.1%, 100% {
background: white;
color: black;
}
}
.foo {
animation: animation-var 1s infinite linear;
}
.bar {
color: var(--color);
animation: var(--anim);
}
<div class="foo">
<div class="bar">xxxx</div>
</div>
Do have any idea how to make this work? Or maybe how to create

CSS: repeated animated background

I'm trying to create a repeated background existing out of two parts. Each part is a gradient and while the one moves up, the other moves down.
The best I got is this:
html {
background: black;
color: #4c4c4c;
}
body {
margin: 30vh auto;
max-width: 80vw;
}
.wave {
background: none;
height: 1rem;
width: 50%;
position: absolute;
z-index: 2;
animation: move 700ms 0ms steps(2) infinite both;
}
.color::after,
.color::before {
content: "";
position: absolute;
left: 0;
right: 0;
height: 100%;
top: 0;
}
.color {
background-image: linear-gradient(#fe0000 50%, #6531ff 0 100%);
}
.color::after {
background: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
}
.wave,
.color::after,
.color::before {
background-size: 5rem 1rem;
background-repeat: repeat-x;
}
#keyframes move {
0% {
margin-top: -3rem;
}
100% {
margin-top: -3.25rem;
}
}
<div class="color wave"></div>
I get why this doesn't work, but not sure how to proceed.
Since it is difficult to describe, here is an image of what I'm looking for:
At first (position 1), all odd blocks are higher than the even blocks. After the first animation, it's the other way around (position 2) and so on.
Maybe like below:
.box {
height:100px;
background:linear-gradient(red,blue,yellow,red) 0 0/100% 200%;
animation:y 2s linear infinite;
}
.box::after {
content:"";
display:block;
height:100%;
background:linear-gradient(green,lightblue,pink,green) 0 0/100% 200%;
animation:inherit;
animation-direction: reverse;
-webkit-mask:linear-gradient(90deg,#fff 50%,transparent 0) 0 0/20% 100%;
}
#keyframes y {
to {
background-position:0 -200%;
}
}
<div class="box"></div>
UPDATE: This is an interesting problem. I'm surprised to find that I don't have an obvious or particularly elegant solution to having a gradient running vertically while repeating with horizontal gaps.
Far more elusive than I initially expected.
Best I could come up with is to put one of the gradients in a pseudo element and apply a mask-image. This won't work in IE, but it appears to be supported everywhere else.
See updated demo below.
If I understand what you're trying to do, I think you could accomplish it by animating the background positions:
.demo {
height: 200px;
background-image:
linear-gradient(#f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%);
animation: move 0.7s infinite alternate;
background-size: 3rem;
position: relative;
}
.demo::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(#042a2b, transparent);
/* This is the magic part: using a horizontal repeating-linear-gradient
to mask out "columns", allowing the container's background gradient to
show through */
-webkit-mask-image: repeating-linear-gradient(to right, black 0 3rem, transparent 3rem 6rem);
background-size: 3rem;
/* run the same animation in reverse to animate up instead of down */
animation: move 0.7s infinite alternate-reverse;
}
#keyframes move {
from {
background-position: 0 0;
}
to {
background-position:
0 200px;
}
}
<div class="demo"></div>
It's difficult to infer exactly what you're trying to do, but here's another sample (very similar to #ray hatfield's answer) that will move the first background down while the second background moves up:
.sample {
width: 250px;
height: 50px;
position: relative;
background-image: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
animation: move 1s infinite linear;
}
#keyframes move {
0%, 100% {
background-position: 0 -75px, 0 0;
}
50% {
background-position: 0 0, 0 -75px;
}
}
<div class="sample"></div>

How do i make a CSS animation run infinitely

I'm tryin to make a infinte animation but at some point it seems to hop back to the start.
Thats the code
h1 {
background: url(Pepesad.png) repeat-x;
width: 90%;
margin: 1em auto;
max-width: 600px;
height: 512px;
animation: flybirds 1s linear infinite;
}
#keyframes flybirds {
from {
background-position: 0px 0px
}
to {
background-position: 300px 0px
}
}
Some of the CSS rules you mentioned for h1 seems unnecessary for your purpose. Mentioning the width gives the animation very less space. Consider providing the h1 a container/ wrapper and set appropriate width for it.
h1 {
background: url(Pepesad.png) repeat-x;
height: 512px;
width: 5076px;
animation: flybirds 1s linear infinite;
}
Also in the keyframes you have mentioned the x-axis to 300px which cause the breaking effect during the animation. I suggest you update it
#keyframes flybirds {
from {
background-position: 0px 0px
}
to {
background-position: -100% 0px
}
}
Another alternative you could use is :
#keyframes flybirds {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-1692px, 0, 0);
}
}
Note: the reason why I suggest to use an additional at all, rather than animating background-position on h1, is so that we can use an animated transform to do the movement, which is much more performant.

How to play specific keyframes with css animation

I want to play keyframes 1, 2, 3, 2, 1 with css animation:
This doesn't work:
#keyframes play-specific {
0% {
background-position: 0px;
}
25% {
background-position: -50px;
}
50% {
background-position: -100px;
}
75% {
background-position: -50px;
}
100% {
background-position: -0px;
}
}
with animation:
.hi {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play-specific 1s steps(4) infinite;
}
see http://jsfiddle.net/CGmCe/12960/
steps() will break animation from a keyframes to another. it can be used to avoid to set each keyframes.
When keyframes are set , 1 will mean jump from a keyframe to another without transition.
.hi {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play-specific 1s steps(1) infinite;
}
.ho {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play 1s steps(10) infinite;
}
#keyframes play-specific {/* steps() will be applied in between each keyframes, 1 is to jump from a keyframe to another without transition */
0% {
background-position: 0px;
}
25% {
background-position: -50px;
}
50% {
background-position: -100px;
}
75% {
background-position: -50px;
}
100% {
background-position: -0px;
}
}
#keyframes play {/* steps here need to be adapted in order to break the linearity of animation */
from { background-position: 0px; }
to { background-position: -500px; }
}
<div class="hi"></div>
<div class="ho"></div>
see on W3C
For a keyframed animation, the 'animation-timing-function' applies between keyframes, not over the entire animation. For example, in the case of an ease-in-out timing function, an animation will ease in at the start of the keyframe and ease out at the end of the keyframe. A 'animation-timing-function' defined within a keyframe block applies to that keyframe, otherwise the timing function specified for the animation is used.

Stop CSS3 animation jumping

I have the following fiddle (Wekbit/Chrome only).
Just watch the animation for a while and you will see it "stop" for a millisecond and then continues again. Could it be the svg file itself? If that is the case, how can I fix this file so the hiccup is gone?
HTML
<div class="tile10"></div>
CSS
#-webkit-keyframes move {
0% {
background-position: 6px 0;
}
100% {
background-position: 6px 80px;
}
}
.tile10 {
width: 80px;
height: 80px;
position: absolute;
background: url(http://www.mauricederegt.nl/loopband.svg);
background-repeat: repeat-y;
-webkit-animation: move 3s linear infinite;
z-index: -1;
}
It was indeed in the image. Your rows are about 6px heigh. 80 is not dividable by 6, so there will be a little displacement. 78 however is dividable by 6.
http://jsfiddle.net/rtS5U/5/
So instead of moving it 80px down, move it 78px down.
#-webkit-keyframes move {
0% {
background-position: 6px 0;
}
100% {
background-position: 6px 78px;
}
}

Resources