CSS3 full-width background animation if body height changes - css

I am trying to get a full-width css3 animation which animates the background. This works fine as long as the height of the body stays at the viewport height. If the content changes and the user needs to scroll, the animation breaks at the bottom:
I already tried to change the css styles of html and body according to some tutorials and ended up with this:
I also tried to set body to 100vh but I think the problem is with the animation itself not scaling properly.
The css for the animation is this:
html {
height: 100%;
}
body {
min-height: 100%;
}
.rememberly-animation {
background: linear-gradient(41deg, #53b5fe, #7abfb4, #5e9793);
-webkit-animation: rememberly-background 30s ease infinite;
-moz-animation: rememberly-background 30s ease infinite;
animation: rememberly-background 30s ease infinite;
}
#-webkit-keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#-moz-keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<html>
<body class="rememberly-animation">
</body>
</html>
The class .rememberly-animation is added to the body-tag.
I somehow need the animation to scale the full height if the viewport (the content) is changing and the user needs to scroll down.
Any hints on this?

This is due to background propagation and your background is moving to the html that you have set to be height:100%.
Here is to illustrate the issue:
html {
height:50px;
}
body {
height:100px;
border:2px solid;
margin:0;
}
body {
background: linear-gradient(41deg, #53b5fe, #7abfb4, red);
animation: rememberly-background 30s ease infinite;
}
#keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
Note how the background is strangely repeating each 50px inside the whole document and not only the body.
To avoid this add a background to the html element:
html {
height:50px;
background:#fff;
}
body {
height:100px;
border:2px solid;
margin:0;
}
body {
background: linear-gradient(41deg, #53b5fe, #7abfb4, red);
animation: rememberly-background 30s ease infinite;
}
#keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
Your final code can be:
html {
background:#fff;
}
body {
min-height:100vh;
margin:0;
}
body {
background: linear-gradient(41deg, #53b5fe, #7abfb4, #5e9793);
animation: rememberly-background 30s ease infinite;
}
#keyframes rememberly-background {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<div style="height:150vh;">to add scroll</div>
From this you are having another issue explained here: Using percentage values with background-position on a linear gradient
You have to specify a background-size for the animation to work
html {
background:#fff;
}
body {
min-height:100vh;
margin:0;
}
body {
background: linear-gradient(41deg, #53b5fe, #7abfb4, red);
background-size:200% 200%;
animation: rememberly-background 3s ease infinite;
}
#keyframes rememberly-background {
0%,100% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
}

Related

How to infinite zoom in and out smoothly with background image in CSS

The background image isn't smooth when it comes to animate it (some kind of blink) and I can't make it zoom from the image center.
This is for my personnal website I'm trying to make.
*{margin: 0;padding: 0;}
body
{
background-color: #0C090A;
background-image: url(../abstract-bg.png);
animation: zoom 30s infinite;
-webkit-animation: zoom 30s infinite;
}
#keyframes zoom {
0% {
background-size: 100%;
}
50% {
background-size: 105%;
}
100% {
background-size: 100%;
}
}
I would like to get the background image (which is 1920*1080) zoom slowly to 105% of it's original size (or something like that), and then go back to 100%. Also, if it's possible, make it zoom from the center, and not the top left corner. Thanks for those who can help.
yes of course you can :)
just add
background-position:center center;
background-repeat:no-repeat;
in the body css
and add
html{
height: 100%;
}
full css code:
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
background-color: #0C090A;
background-image: url(https://images.pexels.com/photos/556416/pexels-photo-556416.jpeg);
animation: zoom 30s infinite;
-webkit-animation: zoom 30s infinite;
background-position: center center;
background-repeat: no-repeat;
}
#keyframes zoom {
0% {
background-size: 100%;
}
50% {
background-size: 150%;
}
100% {
background-size: 100%;
}
}
you can test the code:
https://playcode.io/358401
It's choppy because the animation duration is too long for 5% of the width of the image. either increase the size or decrease the duration of the animation or use a bigger image.
Or you can use scale() which make use of the GPU i believe, However this time we won't be using the image as a background.
body{
overflow-x:hidden;
}
img {
transform-origin: center center;
animation: zoom 30s infinite;
max-width: 100%;
}
#keyframes zoom {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
/* equals 105% */
}
100% {
transform: scale(1);
}
}
<img src="https://picsum.photos/id/238/1920/1080">

setting intervals with CSS3 animations

I am trying to create a sort of slideshow with CSS. I set several background images which gradually fade in one after another.
What I cannot do, though, is setting an interval of some seconds between an image and the other one, so they do not start fading as soon they are fully rendered.
I do not want to include JQuery otherwise the project would be already complicated since I am already using React. Any ideas?
CSS
.App {
text-align: center;
background-size: initial;
animation: animatedBird 60s infinite;
}
#keyframes animatedBird {
0% { background-image: url('../images/arch1.jpg');}
25% { background-image: url('../images/computer.jpg');}
50% { background-image: url('../images/arch2.jpg');}
75% { background-image: url('../images/computer.jpg');}
100% { background-image: url('../images/arch1.jpg');}
}
An idea is to initially load all the images using multiple background so that you won't have any delay on the animation:
body {
background-image:
url('https://picsum.photos/800/800?image=1040'), /*put the first one on the Top*/
url('https://picsum.photos/800/800?image=1069'),
url('https://picsum.photos/800/800?image=1042');
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
25% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
50% {
background-image: url('https://picsum.photos/800/800?image=1042');
}
75% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
}
Here is without intial load to see the difference:
body {
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0% {
background-image: url('https://picsum.photos/800/800?image=1041');
}
25% {
background-image: url('https://picsum.photos/800/800?image=1068');
}
50% {
background-image: url('https://picsum.photos/800/800?image=1043');
}
75% {
background-image: url('https://picsum.photos/800/800?image=1068');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1041');
}
}
UPDATE
And to keep the image for a period of time you can try this:
body {
background-image:
url('https://picsum.photos/800/800?image=1040'), /*put the first one on the Top*/
url('https://picsum.photos/800/800?image=1069'),
url('https://picsum.photos/800/800?image=1042');
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0%,20% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
25%,45% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
50%,70% {
background-image: url('https://picsum.photos/800/800?image=1042');
}
75%,95% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
}
You can try this:
body {
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0%, 25% {
background-image: url('https://picsum.photos/800/800?image=1082');
}
50%, 75% {
background-image: url('https://picsum.photos/800/800?image=1083');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1082');
}
}

2 Background images with separate animations?

This is bugging me, because I know that this is possible, I just don't really know how to write it properly. Here's an image of my vision:
So far in my css, I've implemented the cloud animation
#home{
margin: 0;
padding-top: 327px;
height: 57.78vh;
background: #6bbfff url('../images/clouds.png') repeat-x fixed 50% 10%;
text-align: center;
-webkit-animation: cloudmove 180s infinite linear;
animation: cloudmove 180s infinite linear;
}
#keyframes cloudmove{
0% { background-position: 0% 10%; }
100% { background-position: 100% 10%; }
}
#-webkit-keyframes cloudmove{
0% { background-position: 0% 10%; }
100% { background-position: 500% 10%; }
}
I've been trying to add the landscape illustration in the image shown above as background image number 2, but I'm having trouble. How do I get the css animation to not apply to it?
Thanks!
You do it like this:
Fiddle
Your pertinent CSS relies on some new features of backgrounds in CSS3.
Layered background images
You can instantiate these like so:
.my-rule {
background-image: url(image1.png), url(image2.png);
background-position: 0 0, 50% 50%;
}
It's pretty simple! You just need to separate all rules for each respective background image with commas. That goes straight down to your animations as well, like so:
#keyframes cloudmove{
0% { background-position: 0% 10%, 0% 0%; }
100% { background-position: 100% 10%, 100% 0%; }
}
#-webkit-keyframes cloudmove{
0% { background-position: 0% 10%, 0% 0%; }
100% { background-position: 500% 10%, 100% 0%; }
}
Hope that helps!

CSS 3 Animation - Sliding Across Screen

I have this: http://d.pr/i/A2b3 which acts as the divider between the header and the main content.
The image is set as the background image, repeat-x, of the header container.
<header> <--- image is background of this
<div id="container"></div>
</header>
I want the image to slide across the screen slowly almost in a wave like effect. Is this possible with CCS3 animations? If so can someone help?
Thanks
I would suggest using jQuery and a simple image slider with a shortened image pause so the image keeps on switching. As far as i know its not possible to get a video to appear in a slider (not without a play button of some sort). http://www.catchmyfame.com/2009/06/04/jquery-infinite-carousel-plugin/ would be an example of what i would use.
Try this!
CSS:
header {
width: 100%;
height: 150px;
background-image: url(http://www.scottishheritageusa.org/imgs/header_separator.png); //replace with your image
background-position: 0px;
background-repeat: repeat-x;
-webkit-animation: myanim 5s infinite linear;
-moz-animation: myanim 5s infinite linear;
-o-animation: myanim 5s infinite linear;
animation: myanim 5s infinite linear;
}
#-webkit-keyframes myanim {
0% { background-position: 0px; }
100% { background-position: 100px; } /* set this to the width of the image */
}
#-moz-keyframes myanim {
0% { background-position: 0px; }
100% { background-position: 100px; } /* set this to the width of the image */
}
#-o-keyframes myanim {
0% { background-position: 0px; }
100% { background-position: 100px; } /* set this to the width of the image */
}
#keyframes myanim {
0% { background-position: 0px; }
100% { background-position: 100px; } /* set this to the width of the image */
}
I created a Fiddle for you to play with here:
http://jsfiddle.net/e3WLD/3/

Changing Background Image with CSS3 Animations

Why this isn't working? What am I doing wrong?
CSS
#-webkit-keyframes test {
0% {
background-image: url('frame-01.png');
}
20% {
background-image: url('frame-02.png');
}
40% {
background-image: url('frame-03.png');
}
60% {
background-image: url('frame-04.png');
}
80% {
background-image: url('frame-05.png');
}
100% {
background-image: url('frame-06.png');
}
}
div {
float: left;
width: 200px;
height: 200px;
-webkit-animation-name: test;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: linear;
}
DEMO
http://jsfiddle.net/hAGKv/
Updated for 2020: Yes, it can be done! Here's how.
Snippet demo:
#mydiv{ animation: changeBg 1s infinite; width:143px; height:100px; }
#keyframes changeBg{
0%,100% {background-image: url("https://i.stack.imgur.com/YdrqG.png");}
25% {background-image: url("https://i.stack.imgur.com/2wKWi.png");}
50% {background-image: url("https://i.stack.imgur.com/HobHO.png");}
75% {background-image: url("https://i.stack.imgur.com/3hiHO.png");}
}
<div id='mydiv'></div>
Background image [isn't a property that can be animated][1] - you can't tween the property.
Original Answer: (still a good alternative)
Instead, try laying out all the images on top of each other using position:absolute, then animate the opacity of all of them to 0 except the one you want repeatedly.
It works in Chrome 19.0.1084.41 beta!
So at some point in the future, keyframes could really be... frames!
You are living in the future ;)
Works for me.
Notice the use of background-image for transition.
#poster-img {
background-repeat: no-repeat;
background-position: center;
position: absolute;
overflow: hidden;
-webkit-transition: background-image 1s ease-in-out;
transition: background-image 1s ease-in-out;
}
This is really fast and dirty, but it gets the job done: jsFiddle
#img1, #img2, #img3, #img4 {
width:100%;
height:100%;
position:fixed;
z-index:-1;
animation-name: test;
animation-duration: 5s;
opacity:0;
}
#img2 {
animation-delay:5s;
-webkit-animation-delay:5s
}
#img3 {
animation-delay:10s;
-webkit-animation-delay:10s
}
#img4 {
animation-delay:15s;
-webkit-animation-delay:15s
}
#-webkit-keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
#keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
I'm working on something similar for my site using jQuery, but the transition is triggered when the user scrolls down the page - jsFiddle
I needed to do the same thing as you and landed on your question. I ended up taking finding about the steps function which I read about from here.
JSFiddle of my solution in action (Note it currently works in Firefox, I'll let you add the crossbrowser lines, trying to keep the solution clean of clutter)
First I created a sprite sheet that had two frames. Then I created the div and put that as the background, but my div is only the size of my sprite (100px).
<div id="cyclist"></div>
#cyclist {
animation: cyclist 1s infinite steps(2);
display: block;
width: 100px;
height: 100px;
background-image: url('../images/cyclist-test.png');
background-repeat: no-repeat;
background-position: top left;
}
The animation is set to have 2 steps and have the whole process take 1 second.
#keyframes cyclist {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -202px; //this should be cleaned up, my sprite sheet is 202px by accident, it should be 200px
}
}
Thiago above mentioned the steps function but I thought I'd elaborate more on it. Pretty simple and awesome stuff.
Your code can work well with some adaptations :
div {
background-position: 50% 100%;
background-repeat: no-repeat;
background-size: contain;
animation: animateSectionBackground infinite 240s;
}
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
Here is the explanation of the percentage to suit your situation:
First you need to calculate the "chunks". If you had 8 differents background, you need to do :
100% / 8 = 12.5% (to simplify you can let fall the decimals) => 12%
After that you obtain that :
#keyframes animateSectionBackground {
00% { background-image: url(/assets/images/bg-1.jpg); }
12% { background-image: url(/assets/images/bg-2.jpg); }
25% { background-image: url(/assets/images/bg-3.jpg); }
37% { background-image: url(/assets/images/bg-4.jpg); }
50% { background-image: url(/assets/images/bg-5.jpg); }
62% { background-image: url(/assets/images/bg-6.jpg); }
75% { background-image: url(/assets/images/bg-7.jpg); }
87% { background-image: url(/assets/images/bg-8.jpg); }
}
If you execute this code, you will see the transition will be permanantly. If you want the backgrounds stay fixed while a moment, you can do like this :
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
That mean you want :
bg-1 stay fixed from 00% to 11%
bg-2 stay fixed from 12% to 24%
etc
By putting 11%, the transtion duration will be 1% (12% - 11% = 1%).
1% of 240s (total duration) => 2.4 seconds.
You can adapt according to your needs.
The linear timing function will animate the defined properties linearly. For the background-image it seems to have this fade/resize effect while changing the frames of you animation (not sure if it is standard behavior, I would go with #Chukie B's approach).
If you use the steps function, it will animate discretely. See the timing function documentation on MDN for more detail. For you case, do like this:
-webkit-animation-timing-function: steps(1,end);
animation-timing-function: steps(1,end);
See this jsFiddle.
I'm not sure if it is standard behavior either, but when you say that there will be only one step, it allows you to change the starting point in the #keyframes section. This way you can define each frame of you animation.
Like the above stated, you can't change the background images in the animation. I've found the best solution to be to put your images into one sprite sheet, and then animate by changing the background position, but if you're building for mobile, your sprite sheets are limited to less than 1900x1900 px.
I needed to do the same thing recently. Here's a simple implementation
#wrapper { width:100%; height:100%; position:relative; }
#wrapper img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; }
#wrapper .top { animation:fadeOut 2s ease-in-out; animation-fill-mode:forwards; }
#keyframes fadeOut {
0% { opacity:1; }
100% { opacity:0; }
}
<div id="wrapper">
<img src="img1.jpg" class="top" style="z-index:2;">
<img src="img2.jpg" style="z-index:1;">
</div>
You can use animated background-position property and sprite image.
You can follow by this code:
#cd{
position: relative;
margin: 0 auto;
height: 281px;
width: 450px;
}
#cf img{
left: 0;
position: absolute;
-moz-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf img.top:hover{
opacity: 0;
}
<div id="cf">
<img class="button" src="Birdman.jpg" />
<img src="Turtle.jpg" class="top" />
</div>
You can use the jquery-backstretch image which allows for animated slideshows as your background-images!
https://github.com/jquery-backstretch/jquery-backstretch
Scroll down to setup and all of the documentation is there.
Well I can change them in chrome. Its simple and works fine in Chrome using -webkit css properties.

Resources