How can i make infinite flowing background with only CSS? - html

I'm just started to web programming, cuz many cooooool pages on awwwards.com - definitely caught my mind.
anyway, the first page what i aim for make is the pinterest (www.pinterest.com); slowly moving background with blur effect, floating modal and bottom fixed footer.
with some kinda O'Reilly books, the blur, modal and footer are no more problem. but i couldn't made the background even with them yet.
so, how can i make horizontally infinite flowing background with only CSS??? (without JS)
*conditions
the page is responsive, background-image's height should fit to screen
width follow the height's size, as original image's ratio.
and here's my code.
<head>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
overflow: hidden;
}
#animatedBackground {
position: absolute;
height: 100%;
width: 100%;
background: url("http://placehold.it/1600x800");
background-repeat: repeat;
background-position: 0 0;
background-size: auto 100%;
border: 1px solid red;
animation: animatedBackground 5s linear infinite;
}
#keyframes animatedBackground {
from {
left: -50%;
}
to {
left: 50%;
}
}
</style>
</head>
<body>
<div id="animatedBackground">animatedBackground</div>
</body>
thx.

This should fit your slowly moving+infinite flowing+responsively fit to height background criteria.
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#animatedBackground {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: url("http://twibbon.s3.amazonaws.com/238/63bb30c8-2649-465e-9df1-ab2f8e5f7ecc.jpg");
background-repeat: repeat;
background-position: 0 0;
background-size: auto 100%;
/*adjust s value for speed*/
animation: animatedBackground 500s linear infinite;
}
#keyframes animatedBackground {
from {
background-position: 0 0;
}
/*use negative width if you want it to flow right to left else and positive for left to right*/
to {
background-position: -10000px 0;
}
}
<div id="animatedBackground">
</div>

You can use background-attachment:scroll and use keyframes to perform the animation. See my approach here:
CSS
html,body
{
background:url("http://twibbon.s3.amazonaws.com/238/63bb30c8-2649-465e-9df1-ab2f8e5f7ecc.jpg");
background-repeat:repeat;
background-attachment: scroll;
position:absolute;
left:0;
top:0;
animation: slideshow 10s linear infinite;
}
#keyframes slideshow
{
0% {top:0;}
100% {top:-200%;}
}
See here: jsfiddle

Try This.
<html>
<head>
<style type="text/css">
#animatedBackground {
position: absolute;
height: 100%;
width: 100%;
background: url("http://placehold.it/1600x800");
animation:5s scroll infinite linear;
border: 1px solid red;
}
#keyframes scroll{
100%{
background-position:-3000px 0px;
}
}
</style>
</head>
<body>
<div id="animatedBackground" style="text-align:center;">animatedBackground</div>
</body>
</html>

Related

HTML + CSS infinite scrolling background: Flicker on Safari at repeat

I'm creating a scene with a bunch of scrolling layers (foreground, midground, background etc...) but annoyingly I get a flicker on Safari (14.0.3) when the animation restarts. This doesn't occur on Chrome or Firefox.
I've created a minimum reproducible example here:
https://brendon.github.io/safari_flicker/index.html
Here's the code:
.animation {
position: relative;
height: 395px;
background-image: linear-gradient(#1b9dd9, #00b6ed 44%, #ffe56c 75%);
}
.animation .scrollingAnimation {
position: absolute;
overflow: hidden;
height: 100%;
width: 100%;
}
.animation .scrollingAnimation:before {
content: "";
position: absolute;
height: 100%;
width: 200%;
}
.animation .foreground:before {
/* Dimensions: */
/* width: 1696px; */
/* height: 74px; */
min-width: 6784px;
background-image: url("https://brendon.github.io/safari_flicker/foreground.png");
background-position: left bottom -11px;
background-repeat: repeat-x;
background-size: auto 74px;
transform: translateX(-1696px);
animation: foreground 10s linear infinite;
}
#keyframes foreground {
0% {
transform: translateX(-1696px);
}
to {
transform: translateX(-3392px);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="animation">
<div class="foreground scrollingAnimation"></div>
</div>
</body>
</html>
Here is a video of the issue:
https://github.com/brendon/safari_flicker/raw/main/flicker_video.mp4
I've tried many things to get rid of the issue. It seems to sometimes go away depending on the window width, but I'm looking for a solid solution :D
The issue also exists on iOS Safari.
I should mention that I don't want to animate the background-position property as this causes performance problems and isn't accelerated by the GPU.
Have you thought about using 2 elments with the same image and animation, and offsetting - using delay - the first elements animation by -duration / 2 ?
The idea being that at all times there's one of them on screen and any render delay shouldn't be visible.
See below, I'm animating two pseudo elements.
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.animation, .foreground {
height: 100%;
width: 100%;
background: black;
}
.foreground:before, .foreground:after {
height: 100%;
width: 200%;
position: absolute;
top: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 50vmin;
}
.foreground {
position: relative;
overflow-x: hidden;
}
.foreground:before {
content: 'A';
background: red;
animation: 10s linear -5s infinite foreground;
}
.foreground:after {
content: 'B';
background: blue;
animation: 10s linear 0s infinite foreground;
}
#keyframes foreground {
0% {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
<div class="animation">
<div class="foreground scrollingAnimation"></div>
</div>
I ended up using GSAP fromTo() to manage the transition work instead of relying on the CSS animation:
<div class="foreground scrollingAnimation"><div></div></div>
gsap.fromTo(
'.foreground > div',
{ xPercent: -25 },
{ xPercent: -50, duration: 10, repeat: -1, ease: 'none' }
)
.scrollingAnimation {
position: absolute;
overflow: hidden;
height: 100%;
width: 100%;
> div {
position: absolute;
height: 100%;
}
}
.foreground {
> div {
width: calc(1696px * 4);
background: {
image: url("https://brendon.github.io/safari_flicker/foreground.png");
position: left bottom;
repeat: repeat-x;
size: auto 74px;
}
}
}
It breaks down on very wide screens, but really, if you're rocking a 6000px wide window, good luck to you sir.
The way GSAP animates is that it changes the translateX value via javascript during a requestAnimationFrame (I think) so it's nice and smooth, and the flicker problem doesn't exist in this context.

How to animate the div from top to bottom ? Like a shooting star

How can I animate this div element so it starts at the top and ends at the bottom and then disappears something like a shooting star effect?
Currently, this code is going from top to bottom but it returns from bottom to top(I do not want this effect), I will like to start always from top all the way to the bottom, any suggestion?
css
div {
width: 100px;
height: 100px;
background: blue;
}
.St {
width: 5px;
height: 100px;
background: green;
position: relative;
animation: animateDiv 1s infinite;
}
#keyframes animateDiv {
0% {bottom: 0px; top: 50px; }
}
html
<!DOCTYPE html>
<html>
<head>
<body>
<div>
<div class="St"></div>
</div>
</body>
</html>
You should probably use animation-fill-mode:forwards which will end at the last frame. But you also need to better define your keyframes (add 100%), and finally it suits your case better to use position:fixed instead of relative.
https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode
div {
width: 100px;
height: 100px;
background: blue;
}
.St {
width: 5px;
height: 100px;
background: green;
position: fixed;
animation: animateDiv 1s forwards;
}
#keyframes animateDiv {
0% {top:0;}
100%{top:100%}
}
<div>
<div class="St"></div>
</div>

How do I fix disappearing div while scrolling?

The red element is disappearing while scrolling and I don't know what to do.
I am trying to do a custom scroll by element linked to parts of body.I don't know why this is happening. How do I fix it?
html{
margin: 0;
padding: 0;
height: 400%;
}
> This part of the code is working on a moving background stars
#keyframes move-twink-back {
from {background-position:0 0;}
to {background-position:-10000px 5000px;}
}
#-webkit-keyframes move-twink-back {
from {background-position:0 0;}
to {background-position:-10000px 5000px;}
}
#-moz-keyframes move-twink-back {
from {background-position:0 0;}
to {background-position:-10000px 5000px;}
}
#-ms-keyframes move-twink-back {
from {background-position:0 0;}
to {background-position:-10000px 5000px;}
}
::-webkit-scrollbar {
display:none;
}
.stars, .twinkling, .clouds {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
width:100%;
height:400vh;
display:block;
}
.stars {
background:#000 url(stars-bg.png) repeat top center;
z-index:0;
}
.twinkling{
background:transparent url(twinkling-bg.png) repeat top center;
z-index:1;
-moz-animation:move-twink-back 600s linear infinite;
-ms-animation:move-twink-back 900s linear infinite;
-o-animation:move-twink-back 900s linear infinite;
-webkit-animation:move-twink-back 900s linear infinite;
animation:move-twink-back 900s linear infinite;
}
**code of far right element**
.cont{
height: 50%;
width: 96.5%;
float: left;
}
.conm{
height: 50%;
width: 3.5%;
float: left;
background-color: #0a0a0a;
top: 0;
position: sticky;
}
.point-tb{
height: 10px;
width: 10px;
border-radius: 100%;
border: 6.5px solid #f00;
position: relative;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 50%;
}
.scroll-1{
height: 100px;
width: 8px;
background-color: #f00;
position: relative;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: -5%;
}
<!DOCTYPE HTML>
<html lang="pl">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link rel="stylesheet" href="styles.css">
<script src="https://kit.fontawesome.com/b5945c3b13.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="stars"></div>
<div class="twinkling">
<div class="cont"></div>
<div class="conm">
<div class="point-tb"></div>
<div class="scroll-1"></div>
</div>
</div>
</div>
</body>
</html>
The red element is scrolling because of the following CSS properties.
html{
margin: 0;
padding: 0;
height: 400%; /* This Here */
}
.stars, .twinkling, .clouds {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 400vh; /* and this here */
display: block;
}
Setting the html element to beyond 100% height is considered bad practice. Remove the height attribute from each and this will fix your problem.
html{
margin: 0;
padding: 0;
}
.stars, .twinkling, .clouds {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
display: block;
}
Why is this happening? Most browsers by default will enable user scrolling whenever the HTML document extends passed 100% of the height or 100% the width. Since you are setting the html element and .stars, .twinkling, and .clouds to have a height value beyond 100%, the user can scroll down. When the user scrolls down the red element is moved up. The red element never moves, the page does.
If you attempting to create a custom slider I would wrap everything in a div, like this:
<div class="container">
<div class="scrollbar">
<!-- Scroll bar style elements. -->
</div>
<div class="content">
<!-- Content to be scrolled. -->
</div>
</div>
Then set the .content class to have a height property of beyond 100%. Then you can use JavaScript to animate your scrollbar element based on content scrolling offset. This method will require JavaScript and use of the position: fixed; or position: absolute; CSS property. This essentially will attach the element to a particular area on the screen and prevent it from moving unless you tell it to. You will also need to use overflow: hidden; to disable the browsers auto scroll functionality for the content element. You can read more about the position property and overflow property here by w3schools: https://www.w3schools.com/cssref/pr_class_position.asp,
https://www.w3schools.com/cssref/pr_pos_overflow.asp
--
Alternatively, if you main goal is just to style a custom scrollbar, look into ::scrollbar pseudo selector. You can read more about this here: https://www.w3schools.com/howto/howto_css_custom_scrollbar.asp
--
In addition to the element, use /* Comment Here */ to insert CSS comments. Use <!-- Comment Here --> to insert HTML comments. I believe this was added after copying and pasting into stack overflow, but not using comments correctly can cause rendering issues.
Try to use position:fixed in you css.

How to take a break during a CSS animation to pause at the center point of the transition?

I made a sort of header with an animated information banner (on 3 lines)
starting at each end. (ex: for the 1st and 3rd line, from left to right and for the 2nd line from right to left). What I would like is to take a break of a few seconds when the 3 bands are
all aligned (in the center) then continue the animation.
I would prefer a solution without using javascript but unfortunately I think it seems impossible?
Problem: The 1st and 3rd banner always start to appear before the 2nd and therefore when they are aligned, they are never in the center.
<!DOCTYPE html>
<HTML>
<head>
<title> VIDEO LIBRARY </title>
<meta charset="utf-8"/>
<style type="text/css">
.bandeau
{
height: 120px;
width: 100%;
padding-top: 5px;
border-radius: 25px;
background: rgb(26,133,230);
}
#keyframes defilement {
from {
left: 0;
}
to {
left: 1000px;
}
}
.defil {
margin: 10px;
position: relative;
height: 20px;
background-color: black;
border: 1px solid black;
overflow: hidden;
text-align: center;
}
.defil div {
position: absolute;
top: 0;
left: 0;
width: 250px;
height: 20px;
background-color: blue;
opacity: 1;
}
.ex1 div {
animation: defilement 20s linear infinite;
}
.ex2 div {
top:0;
right:0;
background-color: white;
animation: defilement 20s linear infinite reverse;
}
.ex3 div {
background-color: red;
animation: defilement 20s linear infinite ;
}
</style>
</head>
<body>
<div class="bandeau" >
<div class="defil ex1">
<div>MANAGEMENT</div>
</div>
<div class="defil ex2">
<div>OF MY</div>
</div>
<div class="defil ex3">
<div>VIDEO LIBRARY</div>
</div>
</div>
</body>
</HTML>
Instead of using from and to in your keyframes, you can set steps using percentages.
In the code below, from 0% to 45% of animation, the animation moves from 0 to 500px. Then from 45 - 55% it stays at 500px (i.e. pauses). Then from 55 - 100% it moves from 500 - 1000px:
#keyframes defilement {
0% {left: 0;}
45% {left: 500px;}
55% {left: 500px;}
100% {left: 1000px;}
}
Responsive solution: blocks will stop in the centre an any size screen.
If you do not have fixed width and would like a more responsive way to calculate the midpoint, you can use percentages: Start at 0%, end at 100%, then 50% for the centre.
However if you position the left of the block at the very centre, it will be a bit too far right. The correct position for the left of the block is actually 50% - 125px (half of the width of the div). And we can actually use using the CSS calc function to do this!
Also to make all blocks appear at the same time, we need to change the starting point for -250px so the 3 blocks all start off the screen and then slide in together.
#keyframes defilement {
0% { left: -250px;}
45% { left: calc(50% - 125px); }
55% { left: calc(50% - 125px); }
100% { left: 100%;}
}
Working example:
.bandeau {
height: 120px;
width: 100%;
padding-top: 5px;
border-radius: 25px;
background: rgb(26, 133, 230);
}
#keyframes defilement {
0% { left: -250px; }
45% { left: calc(50% - 125px); }
55% { left: calc(50% - 125px); }
100% { left: 100%; }
}
.defil {
margin: 10px;
position: relative;
height: 20px;
background-color: black;
border: 1px solid black;
overflow: hidden;
text-align: center;
}
.defil div {
position: absolute;
top: 0;
width: 250px;
height: 20px;
background-color: blue;
opacity: 1;
}
.ex1 div {
animation: defilement 20s linear infinite;
}
.ex2 div {
top: 0;
right: 0;
background-color: white;
animation: defilement 20s linear infinite reverse;
}
.ex3 div {
background-color: red;
animation: defilement 20s linear infinite;
}
<div class="bandeau">
<div class="defil ex1">
<div>MANAGEMENT</div>
</div>
<div class="defil ex2">
<div>OF MY</div>
</div>
<div class="defil ex3">
<div>VIDEO LIBRARY</div>
</div>
</div>
For more information on keyframes, take a look at Mozilla MDN Docs for CSS3 Keyframes

Background image fixed to container edge

Is it possible to have a body background image aligned to the edge of a container element?
Using boostrap 3, I want a background to the page that is fixed to a container edge, so when resizing, the background moves with the container (ie, in the example below, the background image centered over the container edge):
(source: nfx.nz)
Is this possible with a background image, or would I have to add a new absolutely positioned layer / or javascript...?
There are several solutions to your question, and it really depends on if you require dynamic sizing of the background. The example I have shown will animate the container dynamically, so you can see how it works.
Approach No. 1: Offset background position with known value
One is if you know the exact dimensions of the image, then you can simply position it negatively along the x-axis (i.e. moving it to the left) by half the width of the image. This is assuming that you are not dynamically sizing your background image:
* {
margin: 0;
padding: 0;
}
div {
background-color: steelblue;
background-image: url('http://placehold.it/400x200');
background-repeat: no-repeat;
background-position: -200px 0;
width: 50%;
margin: 0 auto;
height: 500px;
animation-name: pulse;
animation-duration: 3s;
animation-iteration-count: infinite;
}
#keyframes pulse {
0% {
width: 50%;
}
50% {
width: 100%;
}
100% {
width: 50%;
}
}
<div>
Background image dimension: 400x200
</div>
Approach No. 2: Use pseudo/dummy element
If your background size is dynamic (i.e. changes with the size of the container), you are better off using an absolutely positioned pseudo-element or a dummy element:
* {
margin: 0;
padding: 0;
}
div {
background-color: steelblue;
width: 50%;
margin: 0 auto;
height: 500px;
animation-name: pulse;
animation-duration: 3s;
animation-iteration-count: infinite;
position: relative;
overflow: hidden;
}
div::before {
background-image: url('http://placehold.it/400x200');
background-repeat: no-repeat;
background-size: 100%;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: -50%;
right: 50%;
}
div > * {
position: relative;
}
#keyframes pulse {
0% {
width: 50%;
}
50% {
width: 100%;
}
100% {
width: 50%;
}
}
<div>
<p>Background image dimension: 400x200</p>
</div>