I want to create an infinitely scrolling (to the left) image animation, where the container is full width and the background image is repeated horizontally. So it will always be like a ticker style - the same image just infinitely moves to the left with no gaps.
Ideally I'd like it to be pure html and css if possible.
This is my attempt - https://jsfiddle.net/7Ljz82n9/
At the moment it moves to the left but there's a gap at the end and it jumps, where am I going wrong?
Html
<div class="tech-slideshow">
<div class="mover-1"></div>
</div>
CSS
.tech-slideshow {
height: 102px;
width:100%;
margin: 0 auto;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.tech-slideshow > div {
width: 1440px;
background: url(http://placehold.it/1440x102);
position: absolute;
top: 0;
left: 0;
height: 100%;
transform: translate3d(0, 0, 0);
background-repeat:repeat-x;
}
.tech-slideshow .mover-1 {
animation: moveSlideshow 12s linear infinite;
}
#keyframes moveSlideshow {
100% {
transform: translateX(-66.6666%);
}
}
If you are willing to use two divs inside the "slideshow" you could do something like this:
.tech-slideshow {
height: 102px;
width: 100%;
max-width: 1440px; /* Can be at most the width of the image */
margin: 0 auto;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.wrapper {
height: 102px;
width: 2880px;
}
.wrapper div {
position: absolute;
width: 1440px;
height: 102px;
background: url('http://placehold.it/1440x102') top right no-repeat;
margin: 0;
padding: 0;
animation: movediv 12s linear infinite;
}
.wrapper div.second {
padding-left: 1440px;
animation: movediv 12s linear infinite;
}
#keyframes movediv {
0% { margin-left: 0px; }
100% { margin-left: -1440px; }
}
<div class="tech-slideshow">
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
</div>
</div>
This will move the divs to the left until a full rotation is made and the second picture is "in the same spot" the first slide and can now be shown again. The padding on the second div is to make it align after the first div. You can alter this to use something else etc.
Here's also a fiddle to play around with: https://jsfiddle.net/thepio/7Ljz82n9/4/
EDIT:
I thought to myself why would this not be possible with using pseudo-elements. And it is! Here's an example of using the pseudo-element ::after with only one div. I think you can figure out the widths, margins and paddings etc (1 x image width or 2 x image width).
.tech-slideshow {
height: 102px;
width: 100%;
max-width: 1440px; /* Can be at most the width of the image */
margin: 0 auto;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.wrapper {
height: 102px;
width: 2880px;
}
.wrapper div {
position: absolute;
width: 1440px;
height: 102px;
background: url('http://placehold.it/1440x102') top right no-repeat;
margin: 0;
padding: 0;
animation: movediv 12s linear infinite;
}
.wrapper div::after {
display: block;
content: '';
width: 1440px;
height: 102px;
padding-left: 1440px;
background: url('http://placehold.it/1440x102') top right no-repeat;
}
#keyframes movediv {
0% { margin-left: 0px; }
100% { margin-left: -1440px; }
}
<div class="tech-slideshow">
<div class="wrapper">
<div class="first"></div>
</div>
</div>
And also a fiddle about it: https://jsfiddle.net/thepio/05w6ceue/1/
Related
I am trying to move the image from right to left and loop it (by sliding it). Currently, the image isn't showing up in the browser. This is the code I was testing:
Html:
<div class="slideshow">
<div class="imgslide"></div>
</div>
CSS:
.slideshow {
position: relative;
overflow: hidden;
}
.imgslide {
background: url(images/image.png);
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 300%;
animation: slideshow 10s linear infinite;
}
#keyframes slideshow {
0% { left: 0; }
100% { left: -200%; }
}
You don't see the picture because your containers have no width and height definitions. Here is your code with size definitions.
.slideshow {
position: relative;
overflow: hidden;
/* Here is where you set a size so it will be visible. */
width: 200px;
height: 300px;
}
.imgslide {
background: url(https://picsum.photos/200/300);
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 300%;
animation: slideshow 10s linear infinite;
}
#keyframes slideshow {
0% {
left: 0;
}
100% {
left: -200%;
}
}
<div class="slideshow">
<div class="imgslide"></div>
</div>
However, I want to suggest a change. Since you have a background image, why not simply set the animation to the background itself and not the container?
.imgslide {
background: url(https://picsum.photos/200/300);
width: 200px;
height: 300px;
animation: slideshow 10s linear infinite;
}
#keyframes slideshow {
0% {
background-position-x: 0;
}
100% {
background-position-x: -200px;
}
}
<div class="slideshow">
<div class="imgslide"></div>
</div>
Instead of giving the width and height for the .imgslide as a percentage, give it in px or em. You could also delete the overflow:hidden; from the .slideshow.
This will show if your image is not appearing or if it is appearing and being hidden.
I am working a project on my favorite science stories animated using HTML. While I was working on it By just changing the position to fixed or nothing position of all my objects was changing. If you remove the position property from #Guy, you will notice that the image of Galileo will shift drastically. I just want to know why this happens.
:root {
--initX: 280px;
--initY: 70px;
--finalY: 600px;
}
body {
background-color: aqua;
padding: 0px;
margin: 0px;
}
#Guy {
z-index: 4;
height: 200px;
position: fixed;
width: auto;
transform: translate(800px, 450px);
}
#Galilo {
height: 50px;
width: auto;
z-index: -1;
transform: translate(290px, 5px) rotateZ(4deg);
}
#tower {
height: 650px;
width: 150px;
z-index: 0;
transform: translate(250px, 50px) rotateZ(4deg);
position: absolute;
background-color: grey;
}
#Lball {
height: 40px;
width: 40px;
z-index: 2;
border-radius: 50%;
transform: translate(var( --initX), var(--initY));
background-color: blue;
position: absolute;
animation: lite 2s linear 1s infinite forwards;
}
#Hball {
height: 50px;
width: 50px;
z-index: 3;
transform: translate(calc(var( --initX) + 75px), var(--initY));
border-radius: 50%;
background-color: red;
position: absolute;
animation: heavy 2s linear 1s infinite forwards;
}
#floor {
height: 25%;
width: 100%;
background-color: green;
position: absolute;
z-index: -1;
transform: translate(0px, 565px);
}
#hide {
height: 12%;
width: 100%;
background-color: green;
position: absolute;
z-index: 1;
transform: translate(0px, 650px);
}
#keyframes lite {
0% {
transform: translate(var( --initX), var(--initY))
}
90% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
100% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
}
#keyframes heavy {
0% {
transform: translate(calc(var( --initX) + 75px), var(--initY))
}
90% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
100% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
}
<div id="tower"></div>
<div id="Hball"></div>
<div id="Lball"></div>
<div id="floor"></div>
<div id="hide"></div>
<img src="stick fidure.png" alt="Dude thinking" id="Guy">
<img src="galileo-galilei.png" alt="gallilo" id="Galilo">
P.S.
The link for the image of Galileo is https://cdn.images.express.co.uk/img/dynamic/109/590x/galileo-galilei-819977.jpg and the stick figure was made in Paint 3D
position: fixed takes the element out of the document flow and places it in relation to the viewport/window. Usually that also causes this element to overlap other elements. The other elements however will be rearranged in a way like the fixed element wouldn't be there (it's not in the document flow). So adding/removing position: fixed to/from an element will have all these effects on the overall document.
I have slideshow on my page, but I have small bug in animation and I can't find it.
I use slideshow according to this tutorial: https://www.youtube.com/watch?v=TzAshjkhFQw .
But I want to have only 3 slides not 4.
First 3 slides are ok, but instead of the fourth there is an empty background. I want only 3 slides and after that repeat slideshow.
/* Slider */
.slider {
display: block;
height: 100%;
width: 100%;
z-index: -1;
background-color: #1f1f1f;
overflow: hidden;
position: absolute;
top: 0px;
right: 0px;
border-bottom: 10px solid rgb(121, 0, 0);
}
.slider > * {
position: absolute;
display: block;
width: 100%;
height: 100%;
background-color: #1f1f1f;
animation: slide 12s infinite;
overflow: hidden;
}
.slide:nth-child(1) {
left: 0%;
animation-delay: -1s;
background-image: url(img/slide1.jpg);
background-size: cover;
background-position: center;
}
.slide:nth-child(2) {
left: 100%;
animation-delay: 2s;
background-image: url(img/slide2.png);
background-size: cover;
background-position: center;
}
.slide:nth-child(3) {
left: 100%;
animation-delay: 5s;
background-image: url(img/slide3.jpg);
background-size: cover;
background-position: center;
}
.slide p {
font-size: 2rem;
text-align: center;
display: inline-block;
width: 100%;
margin-top: 340px;
color: #fff;
}
#keyframes slide {
0% { left: 100%; width: 100%; opacity: 1;}
5% { left: 0%;}
25% { left: 0%;}
30% { left: -100%; width: 100%; opacity: 1;}
30.0001% { left: -100%; width: 0%; opacity: 0;}
100% { left: 100%; width: 0%; opacity: 0;}
}
<div class="slider">
<div class="slide">
<p>Slide1</p>
</div>
<div class="slide">
<p>Slide2</p>
</div>
<div class="slide">
<p>Slide3</p>
</div>
</div>
Thank you in advance for your advice!
You need to change the percentages in the animations as well as the timings on the individual slides
#keyframes slide {
0% { left: 100%; width: 100%; opacity: 1;}
6.667% { left: 0%;}
33.334% { left: 0%;}
40% { left: -100%; width: 100%; opacity: 1;}
40.0001% { left: -100%; width: 0%; opacity: 0;}
100% { left: 100%; width: 0%; opacity: 1;}
}
.slide:nth-child(2) {
animation-delay: 3s;
}
.slide:nth-child(3) {
animation-delay: 7s;
}
The animation was initially designed for 4 slides in 12 seconds, i.e. one slide every 3 seconds. If you want to change that to one slide every 4 seconds, you need to space the animations further apart (change the animation delay), and also change the animation so that the slide is visible for a longer time (multiply each percentage by 4/3).
This way of animating slides seems really inflexible however, so you might want to look at some other approach, which allows you to add or remove slides more easily.
I have simple css animation and I use max-width to make horizontal scroll bar to not scroll.
Element need be visible only this what is in 1200px not more not less.
I tried following max-width but not working.
section {
max-width: 1200px;
}
.box {
width: 100%;
max-width: 540px;
position: relative;
z-index: -1;
top: 0px;
transform: rotate(80deg);
left: 1500px;
}
.wave {
position: absolute;
opacity: .4;
width: 1500px;
height: 1300px;
margin-left: -150px;
margin-top: -250px;
border-radius: 43%;
}
#keyframes rotate {
from { transform: rotate(0deg); }
from { transform: rotate(360deg); }
}
.wave.-one {
animation: rotate 9000ms infinite linear;
opacity: .1;
background: #6FC4FF;
}
.wave.-two {
animation: rotate 5000ms infinite linear;
opacity: .1;
background: #319DE8;
}
.wave.-three {
animation: rotate 9500ms infinite linear;
background-color: #0087E5;
}
<section>
<div class='box'>
<div class='wave -one'></div>
<div class='wave -two'></div>
<div class='wave -three'></div>
</div>
</section>
I use max-width to make horizontal scroll bar to not scroll.
You need to use overflow-x property to hide the horizontal scroll
section {
overflow-x: hidden;
width:1200px;
}
A simple way to solve this, if it causes no side effects to you, is to add overflow: hidden to body:
body {
overflow: hidden;
}
I want to create a rectangle and animate the drawing of lines. The lines should grow vertically up and down from the rectangle. Totally, I want to have 2 lines growing up, and 2 lines growing down.
This is my current script:
.content {
position: fixed;
background-color: #dd8341;
top: 40%;
width: 100%;
height: 20%;
padding: 20px;
}
.vertline {
width: 2px;
margin-left: 10%;
background-color: #dd8341;
top: 40%;
animation:lineup 3s forwards;
position: relative;
}
#keyframes lineup {
0% {
height: 0px;
}
100% {
height: 200px;
}
}
<div class="content"></div>
<div class="vertline"></div>
I cannot align all elements correctly. What is the correct way to do this simple task?
You can do it without additional elements, using the :before and :after pseudo-elements to grow up and down, and background: linear-gradient() to create two lines:
.content {
position: fixed;
background-color: #dd8341;
top: 40%;
width: 100%;
height: 20%;
padding: 20px;
}
.content:before,
.content:after {
content: "";
width: 6px; /* color white ("no color") color (each 2px wide); here you can adjust the width */
height: 0;
background: linear-gradient(to right, #dd8341, #dd8341 33.33%, #fff 33.33%, #fff 66.66%, #dd8341 66.66%); /* here you can adjust the spacing */
margin-left: 10%;
position: absolute; /* needs to be absolute */
top: 0;
animation: lineup 3s forwards;
}
.content:after {
top: 100%;
animation: linedown 3s forwards;
}
#keyframes lineup {100% {top: -200px; height: 200px}}
#keyframes linedown {100% {height: 200px}}
<div class="content"></div>
Addition:
/* recommended */
* {box-sizing: border-box}
body {margin: 0}
.content {
position: fixed;
background-color: #dd8341;
top: 40%;
width: 100%;
height: 20%;
padding: 20px;
}
.content:before,
.content:after,
.linedown1,
.linedown2 {
content: "";
width: 2px;
height: 0;
background: #dd8341;
left: 20%;
position: absolute;
top: 0;
animation: lineup 3s forwards;
}
.linedown1, .linedown2 {top: 100%; animation: linedown 3s forwards}
.content:after, .linedown2 {left: 80%; animation-delay: 1s}
#keyframes lineup {100% {top: -200px; height: 200px}}
#keyframes linedown {100% {height: 200px}}
<div class="content">
<span class="linedown1"></span>
<span class="linedown2"></span>
</div>
Here is an idea with only background and gradient:
.content {
position: fixed;
width:100%;
height:100vh;
background-image:
linear-gradient(#dd8341,#dd8341),
linear-gradient(#dd8341,#dd8341),
linear-gradient(#dd8341,#dd8341);
background-position:center, 10% center,calc(10% + 4px) center;
background-size:100% 40%,2px 0,2px 0;
background-repeat:no-repeat;
animation:lineup 2s forwards linear;
}
#keyframes lineup {
to {
background-size:100% 40%,2px 100%,2px 100%;
}
}
<div class="content"></div>
UPDATE
To add delay simple add more states to the animation:
.content {
position: fixed;
width:100%;
height:100vh;
background-image:
linear-gradient(#dd8341,#dd8341),
linear-gradient(#dd8341,#dd8341),
linear-gradient(#dd8341,#dd8341);
background-position:center, 20% center,80% center;
background-size:100% 40%,2px 0,2px 0;
background-repeat:no-repeat;
animation:lineup 2s forwards linear;
}
#keyframes lineup {
50% {
background-size:100% 40%,2px 100%,2px 0%;
}
to {
background-size:100% 40%,2px 100%,2px 100%;
}
}
<div class="content"></div>