Animate CSS background-position with smooth results (sub-pixel animation) - css

I'm trying to animate the background-position of a div, slowly, but without it having jerky movement. You can see the result of my current efforts here:
http://jsfiddle.net/5pVr4/2/
#-webkit-keyframes MOVE-BG {
from {
background-position: 0% 0%
}
to {
background-position: 187% 0%
}
}
#content {
width: 100%;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
text-align: center;
font-size: 26px;
color: #000;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}
I have been at this for hours and can't find anything that will animate slowly and smoothly at a sub-pixel level. My current example was made from the example code on this page: http://css-tricks.com/parallax-background-css3/
The smoothness of animation I'm after can be seen on this page's translate() example:
http://css-tricks.com/tale-of-animation-performance/
If it can't be done with the background-position, is there a way to fake the repeating background with multiple divs and move those divs using translate?

Checkout this example:
#content {
height: 300px;
text-align: center;
font-size: 26px;
color: #000;
position:relative;
}
.bg{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
animation-name: MOVE-BG;
animation-duration: 100s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes MOVE-BG {
from {
transform: translateX(0);
}
to {
transform: translateX(-187%);
}
}
<div id="content">Foreground content
<div class="bg"></div>
</div>
http://jsfiddle.net/5pVr4/4/

Animating background-position will cause some performance issues. Browsers will animate transform properties much cheaply, including translate.
Here is an example using translate for an infinite slide animation (without prefixes):
http://jsfiddle.net/brunomuller/5pVr4/504/
#-webkit-keyframes bg-slide {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.wrapper {
position:relative;
width:400px;
height: 300px;
overflow:hidden;
}
.content {
position: relative;
text-align: center;
font-size: 26px;
color: #000;
}
.bg {
width: 200%;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) repeat-x;
position:absolute;
top: 0;
bottom: 0;
left: 0;
animation: bg-slide 20s linear infinite;
}

You should adjust your HTML and CSS little bit
Working Demo
HTML
<div id="wrapper">
<div id="page">
Foreground content
</div>
<div id="content"> </div>
</div>
CSS
#-webkit-keyframes MOVE-BG {
from { left: 0; }
to { left: -2000px; }
}
#wrapper {
position:relative;
width:800px;
height: 300px;
overflow:hidden;
}
#page {
text-align: center;
font-size: 26px;
color: #000;
}
#content {
width: 2000px;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
position:absolute;
top: 0;
left: 0;
z-index:-1;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}

Related

keyframes animations not returning to first point or repeating

I'm trying to use a keyframe that will not return to first position, I mean if I have a transition from left to right, to stay right not return to the left side.
Code
div {
width: 100px;
height: 100px;
background-color: red;
position: relative;
-webkit-animation-name: example;
-webkit-animation-duration: 4s;
animation-name: example;
animation-duration: 4s;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes example {
0% {
background-color: red;
left: 0px;
top: 0px;
}
100% {
background-color: yellow;
left: 200px;
top: 0px;
}
}
/* Standard syntax */
#keyframes example {
0% {
background-color: red;
left: 0px;
top: 0px;
}
100% {
background-color: yellow;
left: 200px;
top: 0px;
}
}
<div></div>
You just need to add animation-fill-mode: forwards; to the div.
div {
width: 100px;
height: 100px;
background-color: red;
position: relative;
-webkit-animation-name: example;
-webkit-animation-duration: 4s;
-webkit-animation-fill-mode: forwards;
animation-name: example;
animation-duration: 4s;
animation-fill-mode: forwards;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes example {
0% {background-color:red; left:0px; top:0px;}
100% {background-color:yellow; left:200px; top:0px;}
}
/* Standard syntax */
#keyframes example {
0% {background-color:red; left:0px; top:0px;}
100% {background-color:yellow; left:200px; top:0px;}
}
<div></div>
You just need to add 'animation-iteration-count: 1' it will work single time or if you want to take it in the loop then can try 'animation-iteration-count: infinite' into the div.
div {
width: 100px;
height: 100px;
background-color: red;
position: relative;
-webkit-animation-name: example;
-webkit-animation-duration: 4s;
animation-name: example;
animation-duration: 4s;
animation-iteration-count: 1; /*value can be infinite if you want to it in loop */
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes example {
0% {
background-color: red;
left: 0px;
top: 0px;
}
50%{
background-color: yellow;
left: 200px;
top: 0px;
}
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
/* Standard syntax */
#keyframes example {
0% {
background-color: red;
left: 0px;
top: 0px;
}
50%{
background-color: yellow;
left: 200px;
top: 0px;
}
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
<div></div>

CSS - ::after pseudo element positioning and dimension issue

I have 2 images with transparent background and need to put one on top of each other with the same positioning:
1 spinning (underneath)
1 fixed (above)
I need to have the whole image composition to be centered and to have its size adjusted depending on the window size.
I used an ::after pseudo element for the fixed one but couldn’t get its position and size to follow the spinning one.
I suppose the background-size property should be involved but didn’t manage to use it properly.
Would appreciate any advice, even if it involves going with a totally different approach than the ::after pseudo class.
Many thanks.
body{
width: 100%;
height: 100%;
background-color: #000;
text-align: center;
color: #fff;
}
.main-container{
background-color: #00f;
width: 50%;
margin: 0 auto;
}
.engine-container{
}
.engine-complete{
position: relative;
width: 100%;
height: auto;
margin: 0 auto;
}
.engine-complete::after{
content: "";
position: absolute;
width: 191px;
height: 192px;
top: 1px;
left: 0;
background-image: url(https://image.ibb.co/jOqNma/engine1_crpd.png);
}
.engine-rotating{
width: 50%;
height: auto;
}
.spin {
animation-duration: 15s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function:linear;
animation-play-state: running;
}
#keyframes spin {
from {
transform:rotate(360deg);
}
to {
transform:rotate(0deg);
}
}
<div class="main-container">
<h1>spinning engine</h1>
<div class="engine-container">
<div class="engine-complete">
<img src="https://image.ibb.co/nwOKXF/engine1.png" width=191 height=192 class="engine-rotating spin"/>
</div>
</div>
</div>
Something like this?
EDIT: Instead of setting the image as a background using the ::after pseudo-class, I added the fixed image into the html. I also eliminated one of your containers.
I centred the animated image using text-align:center and centred the fixed image using position: absolute
I set both images to 30% width relative their parent .engine-container
The fixed image has a higher z-index than the animated image so that it always appears over it. The images also change size accordingly, relative to window size.
body {
width: 100%;
height: 100%;
background-color: #000;
text-align: center;
color: #fff;
}
.main-container {
background-color: #00f;
width: 50%;
margin: 0 auto;
}
.engine-container {
text-align: center;
position: relative;
}
.engine-rotating,
.engine-fixed {
width: 30%;
}
.engine-fixed {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
z-index: 5000;
}
.spin {
animation-duration: 15s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: running;
}
#keyframes spin {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
<div class="main-container">
<h1>spinning engine</h1>
<div class="engine-container">
<img src="https://image.ibb.co/nwOKXF/engine1.png" class="engine-rotating spin" />
<img src="https://image.ibb.co/jOqNma/engine1_crpd.png" class="engine-fixed" alt="">
</div>
</div>
UPDATE
Heres what I came up with:
A similar effect using ::after. I was able to achieve this by inserting the image url into the content: rule, rather than setting a background image.
body {
width: 100%;
height: 100%;
background-color: #000;
text-align: center;
color: #fff;
}
.main-container {
background-color: #00f;
width: 50%;
margin: 0 auto;
}
.engine-container{
text-align: center;
position: relative;
}
.engine-rotating{
}
.engine-container::after{
content: url('https://image.ibb.co/jOqNma/engine1_crpd.png');
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
z-index: 5000;
}
.spin{
animation-duration: 15s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: running;
}
#keyframes spin{
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
<div class="main-container">
<h1>spinning engine</h1>
<div class="engine-container">
<img src="https://image.ibb.co/nwOKXF/engine1.png" class="engine-rotating spin" />
</div>
</div>
Set position for .engine-complete::after to relative
.engine-complete::after {position: relative}
body{
width: 100%;
height: 100%;
background-color: #000;
text-align: center;
color: #fff;
}
.main-container{
background-color: #00f;
width: 50%;
margin: 0 auto;
}
.engine-container{
}
.engine-complete{
position: relative;
width: 100%;
height: auto;
margin: 0 auto;
}
.engine-complete::after{
content: "";
position: relative; /* this was changed */
width: 191px;
height: 192px;
top: 1px;
left: 0;
background-image: url(https://image.ibb.co/jOqNma/engine1_crpd.png);
}
.engine-rotating{
width: 50%;
height: auto;
}
.spin {
animation-duration: 15s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function:linear;
animation-play-state: running;
}
#keyframes spin {
from {
transform:rotate(360deg);
}
to {
transform:rotate(0deg);
}
}
<div class="main-container">
<h1>spinning engine</h1>
<div class="engine-container">
<div class="engine-complete">
<img src="https://image.ibb.co/nwOKXF/engine1.png" width=191 height=192 class="engine-rotating spin"/>
</div>
</div>
</div>

How can i create an animation like this in css

I'm trying to create an animated text like bellow using css, how can i do this?
I already tried this:
span1 {
display: inline-block;
color: #e74c3c;
position: relative;
white-space: nowrap;
top: 0;
left: 0;
-webkit-animation: move 5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-delay: 1s;
}
#keyframes move {
0% {
top: 0px;
}
20% {
top: -50px;
}
40% {
top: -100px;
}
60% {
top: -150px;
}
80% {
top: -200px;
}
100% {
top: -300px;
}
}
<span1>
web developer<br /> css cowboy<br /> self-facilitating media node<br /> box inside a box<br /> part of the problem
</span1>
but it has a delay after last text that i need to remove!
See This:
*{
box-sizing: border-box;
}
body {
background-color: skyblue;
}
div {
overflow: hidden;
color: #fff;
text-align: center;
font-size: 20px;
position: relative;
height: 100px;
margin-top: 100px;
}
div p {
height: 100px;
animation: move 7s infinite linear;
position: relative;
bottom: -100px;
font-size: 36px;
margin: 0;
}
#keyframes move {
0% {bottom: -100px;}
10%, 20% {bottom: 0px}
40%,50% {bottom: 100px;}
70%,80% {bottom: 200px;}
100% {bottom: 300px}
}
<div>
<p>50% OFF</p>
<p>Some Text</p>
<p>Write by: Ehsan Taghdisi</p>
</div>
.anim1 {
animation: anim1 1.5s infinite;
}
.anim2 {
animation: anim2 1.5s infinite;
}
#keyframes anim1 {
0% {
transform: translateY(-10px);
}
50% {
transform: translateY(-80px);
}
100% {
transform: translateY(-10px);
}
}
#keyframes anim2 {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-80px);
}
100% {
transform: translateY(0px);
}
}
<div style="height:40px;overflow:hidden">
<h1 class="anim1">Hello animation 1</h1>
<h1 class="anim2">Hello animation 2</h1>

Create playing drums by css3 animation

I want to create a animation for a man playing drums(Dhol). So I cannot understand how to rotate hand end only on drum. Please see my Fiddle here
My html:
<div class="man_body"></div>
<div class="man_hand"></div>
<div class="man_shadow"></div>
My css:
.man_body {
position:absolute;
height:225px;
width: 137px;
background-image:url('http://i60.tinypic.com/2ag7uwk.png');
z-index:1;
}
.man_hand {
width:37px;
height:96px;
background-image:url('http://i61.tinypic.com/2ntfmdh.png');
position:absolute;
z-index:2;
left:30px;
top:65px;
-webkit-animation-name: man_hand-rotate;
-webkit-animation-duration: .5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear; /* Just another timing function */
-webkit-animation-direction: alternate; /* Lets do in alternate fashion */
}
#-webkit-keyframes man_hand-rotate {
from{-webkit-transform:rotate(0deg);}
to{-webkit-transform:rotate(50deg);}
}
You would need to adjust the transform-origin point about which the rotation occurs. By default this is the center point of the element.
I've appoximated at:
transform-origin:center top;
but you can adjust this to suit.
Note: I've adjusted the position of the 'arm` slightly and set the rotattion to 15deg on both keyframes (as these were different in your original code).
.drumer {
position: absolute;
width: 100%;
height: 350px;
overflow: hidden;
}
.man_body {
position: absolute;
height: 225px;
width: 137px;
background-image: url('http://i60.tinypic.com/2ag7uwk.png');
z-index: 1;
}
.man_hand {
width: 37px;
height: 96px;
background-image: url('http://i61.tinypic.com/2ntfmdh.png');
position: absolute;
z-index: 2;
left: 33px;
top: 65px;
transform-origin: center top;
-webkit-animation-name: man_hand-rotate;
-webkit-animation-duration: .5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
/* Just another timing function */
-webkit-animation-direction: alternate;
/* Lets do in alternate fashion */
}
/* Chrome / Safari */
#-webkit-keyframes man_hand-rotate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(15deg);
}
}
/* Old Firefox */
#-moz-keyframes man_hand-rotate {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(15deg);
}
}
/* new Firefox & supporting broswers */
#keyframes man_hand-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(15deg);
}
}
.man_shadow {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
top: 227px;
box-shadow: -5px 10px 45px 2px #000000;
left: 7px;
position: absolute;
width: 136px;
}
<div class="man_body"></div>
<div class="man_hand"></div>
<div class="man_shadow"></div>

CSS Animation Starting From Middle

I have a pretty simple animation that has borders that I created animate in width, in height, and then the center fades in.
The issue I'm having is I can't figure out how to animate from the center, rather than left to right (for the top and bottom borders) and top to bottom (for the side borders).
Is there any simple way to get the animation to happen from the middle?
Example of the code for the top and bottom animation:
#keyframes tb {
0% {width: 0;}
100% {width: 800px}
}
JSFiddle of the code.
You need to animate the left and top, too. For the horizontal bars, set the property left to 400px (50%) on the first keyframe, and to 0px on the last keyframe. Same goes for the vertical bars. Here is your fixed example:
#import url(https://fonts.googleapis.com/css?family=Montserrat:700);
html{
background: black;
}
#holder{
width: 800px;
display: block;
position: relative;
}
#follower {
display: block;
text-align: center;
padding: 20px;
font-family: 'Montserrat', sans-serif;
font-size: 30px;
line-height: 70px;
color: #fff;
background: rgba(255,255,255,.1);
animation: main 2s ease-out;
-webkit-animation: main 2s ease-out;
}
#keyframes main {
0% {opacity: 0}
50% {opacity: 0}
100%{opacity: 1}
}
#-webkit-keyframes main {
0% {opacity: 0}
50% {opacity: 0}
100%{opacity: 1}
}
#t, #b {
width: 800px;
height: 2px;
background: #fff;
position: absolute;
display: block;
animation: tb .5s 1 ease-out;
-webkit-animation: tb .5s 1 ease-out;
}
#t {
top: 0;
left: 0;
}
#b{
bottom: 0;
left: 0;
}
#r, #l {
width: 2px;
height: 110px;
background: #fff;
position: absolute;
display: block;
animation: rl 1s 1 ease-out;
-webkit-animation: rl 1s 1 ease-out;
}
#r{
left: 0;
top: 0;
}
#l {
right: 0;
top: 0;
}
#keyframes tb {
0% {
width: 0;
left: 400px;
}
100% {
width: 800px
left: 0;
}
}
#keyframes rl {
0% {height: 0}
50% {
height: 0;
top: 55px;
}
100% {
height: 110px;
top: 0;
}
}
<div id="holder">
<div id="t"></div>
<div id="b"></div>
<div id="r"></div>
<div id="l"></div>
<div id="follower">
Super Long Text Goest Here!
</div>
</div>
You can play around with your timing, and make it start at right point in your animation... using an animation-delay.
E.g.
#keyframes makeFatter {
0% {width: 0;}
100% {width: 800px}
}
#makeMeFat {
animation-name: makeFatter;
animation-duration: 5s;
animation-delay: -2.5s; /* Makes it start at 50% of your animation, i.e. width: 400px */
/* blah blah... rest of the CSS code */
}

Resources