Ok, maybe stackoverflow can help? :)
I'm trying, without any luck, to create a page transition effect with an svg image.
When the user clicks on a link in Page 1, a diamond shaped svg fades in like a portal into Page 2.
The basic idea is to recreate the space travel in the intro of the Alphaville - Forever Young video: https://www.youtube.com/watch?v=t1TcDHrkQYg
:)
Maybe the diamond also fades in from blue to transparent (but that is the next step).
Diamond svg: https://www.onlinewebfonts.com/icon/413
I suggest you use clip-path instead of a svg since animating an svg that big will be really slow and really laggy. You can change the clip path to show what you want. Bennet Feely created a nice generator that helps with this.
For the animation itself you can increase the width and height to fit your screen. Then fill the remainder by animating the Z axes.
Animation looks better in fullscreen then in the smaller preview
const links = document.querySelectorAll(".page-transition");
const overlay = document.querySelector(".overlay__diamond");
for(const link of links) {
link.addEventListener("click", (event) => {
event.preventDefault();
overlay.classList.add("overlay__diamond--animate");
setTimeout(() => window.location.reload(), 1000);
// This one is correct, one above is for the demo
// setTimeout(() => (window.location.href = link.href), 1000); // Same time as animation duration
});
}
.page {
background: green;
/* For demontrational purposes only, just to increase page size */
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
pointer-events: none;
perspective: 500px; /* Needed for translateZ to work */
}
.overlay__diamond {
width: 100%;
height: 100%;
background: blue;
animation: fadeout 1s linear forwards;
}
.overlay__diamond--animate {
animation: zoom 1s linear forwards;
clip-path: polygon(50% 0%, 75% 50%, 50% 100%, 25% 50%);
}
#keyframes fadeout {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes zoom {
0% {
width: 0;
height: 0;
transform: translateZ(0);
}
100% {
width: 100%;
height: 100%;
transform: translateZ(400px); /* Can't go higher then the perspective */
}
}
<div class="page">
<!-- Replace #link with your actual urls -->
<a class="page-transition" href="#link">Link</a>
<a class="page-transition" href="#link">Link</a>
<a class="page-transition" href="#link">Link</a>
<div class="overlay">
<div class="overlay__diamond"></div>
</div>
</div>
Related
I managed with the help of the ScrollMagic library to change my background img for my section three-section-container depending on scroll position. Additionally, I managed to add an overlay that will appear only when I am on a certain section of my page.
My issue now is that I would like to animate how background image changes (I want to come from right to left and stay positioned in the middle/ as you can see in code the background is changing 2 times). I tried with `transform: translateY(40px);
property in CSS but the result was inconsistent because the image would not be 100% of my screen. Also, I want my overlay to come from left to right, and I am quite confused how.
HTML
<div id="bigSection" class="three-section-container ">
<div id="target-overlay" class=" "></div>
<div class="sec1 " id="project01"></div>
<div class="sec2 " id="project02"></div>
<div class="sec3" id="project03"></div>
</div>
CSS
.three-section-container{
position: relative;
background-color: black;
transition: all 3s ease;
background-image: url('../../Assets/Images/graphic/last/poza-augmented-reality.png');
background-repeat: no-repeat;
background-color: black;
background-size: 100% 100vh;
background-attachment: fixed;
}
.fade-img1{
transition: all 1s ease;
background-image: url('../../Assets/Images/graphic/last/poza-augmented-reality.png');
background-repeat: no-repeat;
background-color: black;
background-size: 100% 100vh;
background-attachment: fixed;
// transform: translatey(20px);
opacity: 1;
margin: 0;
z-index: 999;
}
.fade-img2{
background-image: url('../../Assets/Images/graphic/last/2.png');
background-repeat: no-repeat;
background-color: black;
background-size: 100% 100vh;
background-attachment: fixed;
opacity: 1;
transition: all 1s ease;
margin: 0;
z-index: 999;
}
.fade-img3{
background-image: url('../../Assets/Images/graphic/last/poza-interior.png');
background-repeat: no-repeat;
background-color: black;
background-size: 100% 100vh;
background-attachment: fixed;
// transform: translateY(40px);
opacity: 1;
transition: all 0.3s ease;
margin: 0;
z-index: 999;
}
.sec1, .sec2, .sec3{
height: 100vh;
}
.overlay {
transition: 0.3s linear all;
position: absolute; /* Sit on top of the page content */
width: 40%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5); /* Black background with opacity */
z-index: 999; /* Specify a stack order in case you're using a different order for other elements */
}
JS
$(document).ready(function(){
var controller=new ScrollMagic.Controller()
// build a scene
var ourScene= new ScrollMagic.Scene({
triggerElement:'#project01',
duration:"100%"
})
.setClassToggle('#bigSection', 'fade-img1')
.addIndicators({
name:'fade scene',
colorTRigger:'black',
indent:200,
colorStart:'#75c695'
})
.addTo(controller)
var ourScene= new ScrollMagic.Scene({
triggerElement:'#project02',
duration:"100%"
})
.setClassToggle('#bigSection', 'fade-img2')
.addIndicators({
name:'fade scene',
colorTRigger:'black',
indent:200,
colorStart:'#75c695'
})
.addTo(controller)
var ourScene= new ScrollMagic.Scene({
triggerElement:'#project03',
duration:"200%"
})
.setClassToggle('#bigSection', 'fade-img3')
.addIndicators({
name:'fade scene',
colorTRigger:'black',
indent:200,
colorStart:'#75c695'
})
.addTo(controller)
var ourScene= new ScrollMagic.Scene({
triggerElement:'#project01',
// duration:"200%"
})
.setClassToggle('#target-overlay', 'overlay')
.addIndicators({
name:'overlay',
colorTRigger:'black',
indent:200,
colorStart:'#75c695'
})
.addTo(controller)
})
Any help is welcomed. Thank You
I'm not familiar with the ScrollMagic API but I think this code snippet can make things a little cleared from the JS and CSS prospective involved in the animation.
In fact most of them can be done without the need of externals API but just triggering back an forth a CSS class !
Hope this helps you a little bit:
let animationDone = false;
window.addEventListener("scroll", () => {
/*
* IF you scrolled more than a certain amount:
* in this case i choose half a page height's (50vh),
* you trigger the slide animation by adding the onscreen class to the background2 div.
* Otherwise if you previously triggered the animation and
* you scrolled in the opposite direction: the animation is triggered backwards.
*/
if(window.scrollY > window.innerHeight / 2) {
document.getElementsByClassName("background2")[0].classList.add("onscreen");
document.getElementById("secondPage").classList.add("onscreen");
animationDone = true; //We makes sure that we always know the state of our animation
} else if(animationDone) {
document.getElementsByClassName("background2")[0].classList.remove("onscreen");
document.getElementById("secondPage").classList.remove("onscreen");
animationDone = false; //We makes sure that we always know the state of our animation
}
}, {passive:true});
body {
color:white;
margin: 0;
width:100vw;
height:200vh; /* 200vh is only for demo purposes: it allows to scroll the html body even thought there's nothing inside */
}
#mainContent {
text-align: center;
z-index: 99;
position: absolute;
}
#mainContent > * {
display: flex;
justify-content: center;
align-items: center;
}
#firstPage {
width: 100vw;
height: 100vh;
}
#secondPage {
width: 100vw;
height: 100vh;
opacity: 0; /* This makes our background2 div transparent as soon as its hidden */
transform: translateX(-100vw); /* This shifts our background to the left by 100vw (its width) */
transition: 1s; /* The page content animation's duration */
}
#secondPage.onscreen {
/*
* This cancels the second page's previous shift (to left) when the onscreen class is applied to secondPage div
* in 0.3s so that it won't snap-> the left to right transition is realized !
*/
transform: translateY(0);
opacity: 1; /* This makes our background2 fades from transparent (its original state) to opaque */
}
.background1 {
z-index: 1; /* Lower stacking index than the other background to hide it */
position: fixed;
width: 100vw;
height: 100vh;
background: red;
}
.background2 {
z-index: 2; /* Higher stacking index than the other background to show it*/
position: fixed;
width: 100vw;
height: 100vh;
background: blue;
opacity: 0; /* This makes our background2 div transparent as soon as its hidden */
transform: translateX(100vw); /* This shifts our background to the right by 100vw (its width) */
transition: 0.3s; /* The background2 animation's duration */
}
.background2.onscreen {
/*
* This cancels the background's previous shift when the onscreen class is applied to background2
* in 0.3s so that it won't snap-> the right to left transition is realized !
*/
transform: translateY(0);
opacity: 1; /* This makes our background2 fades from transparent (its original state) to opaque */
}
<body>
<div id = "mainContent">
<h1 id = "firstPage">The main content goes here</h1>
<h1 id = "secondPage">Animation Triggered !</h1>
</div>
<div class = "background1"></div>
<div class = "background2"></div>
</div>
</body>
So i made a svg logo preloader, made some css animations for it also. But my main problem is how do i make the preloader load different animation on refresh/new page loading using javascript. Like for example on one page loading the logo should use the bounce animation and upon a page refreh or on another tab opening the preloader to use the rotate animation i made, etc.
var strings = [
'animation1.',
'animation2.',
'animation3.'
];
var rand = strings[Math.floor(Math.random() * strings.length)];
document.getElementById('loading-animation').innerHTML = rand;
.loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
background: #ddd;
padding-top: 200px;
}
.svg {
display: block;
width: 80px;
height: 80px;
background: #aaa;
margin: 10px auto;
}
.animation1 {
just an example
}
.animation2 {
just an example
}
.animation2 {
just an example
}
<div id="container" class='loading' >
<div id='loading-animation' class='loading-animation'>Processing</div>
<svg>just an example svg in inserted in the html, no external src link to it</svg>
</div>
I'm pretty sure that .innerHTML shouldn't be there since the javascript file will be external linked in the head section. And i know i haven't linked all of the codes used just because it's to much code to paste here so i made a mini example, hope i can make myself understood. Thanks.
You can use JavaScript to randomly assign a CSS class to the element you want to animate. Here is an example.
var animationClasses = [
'animation1',
'animation2',
'animation3'
];
var choosenAnimation = animationClasses[~~(Math.random() * animationClasses.length)];
document.getElementById('elementToAnimate').classList.add(choosenAnimation);
#keyframes grow {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fly-down {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
.animation1 {
width: fit-content;
animation: grow 1s;
}
.animation2 {
animation: fade 1s;
}
.animation3 {
animation: fly-down 1s;
}
<div id="elementToAnimate">This will get a random animation</div>
A random class in the array animationClasses is assigned to elementToAnimate. Each class contains CSS for a different animation, allowing for a random animation each time.
I am trying to mimic the CSS animations from a website here: https://stanographer.com/
I want to copy the way the site:
starts by showing a full screen black div sliding away to the right
"loads" the black background (div tags) behind text (as in "Hi, I'm Stanley Sakai"), expanding left to right and
"loads" the text over the black background div, expanding left to right.
Now you might ask, "Why not just inspect the page, look at the classes on the divs and text, then inspect the CSS sheet in the network tab?" And I've tried that. The CSS looks weird. My friend said it is pre-processed by SASS, whatever that means. Anyway, I cannot decipher the code.
I've been to a few different StackOverflow pages (here's one) & over a dozen different pages on Google. I learned about using keyframes but I haven't figured out how to recreate the effect on Stanographer.com. My friend, who owns the website, also provided this example, but I don't get how to apply it to individual divs. He said something about using the z-index but I just don't see it.
I know that to make the page start with a full black screen & then slide out, I have to trigger a class change using JavaScript. I have:
let blackStuff = document.getElementById("blackness");
window.addEventListener("load", () => {
console.log("loaded");
blackStuff.setAttribute("class", "black-box-out");
},
false
);
.black-box {
position: fixed;
float: left;
top: 0;
width: 100%;
height: 100%;
bottom: 0;
background-color: #000;
z-index: 999999;
-webkit-animation: powerslide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: powerslide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes powerslide {
100% {
left: 0;
}
}
#keyframes powerslide {
100% {
left: 0;
}
}
.black-box-out {
margin-left: 100%;
animation: slide 0.5s forwards;
-webkit-transition: slide 0.5s forwards;
transition: slide 0.5s forwards;
}
<div id="blackness" class="black-box"></div>
But this just makes the "blackness" div disappear instantly on page load. I want it to slide out. Clearly, I don't get how to use CSS animations.
If you are interested in seeing more of what doesn't work, read on. Otherwise, you can skip this section: it only shows my failed trials.
I've learned how to make a CSS animation expand horizontally from 0:
.wrapper {
position: relative;
overflow: hidden;
width: 500px;
height: 50px;
border: 1px solid black;
}
.slide-custom {
width: 500px;
height: 50px;
background: cyan;
position: relative;
-webkit-animation: slideIn 2s forwards;
animation: slideIn 2s forwards;
}
/* moz and webkit keyframes excluded for space */
#keyframes slideIn {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
<div class="wrapper slide-custom">
<h1 class="slide-custom">
<span>MEET ROLY POLY.</span>
<!-- expands horizontally from 0 width to 100% width -->
</h1>
</div>
And I've learned to make text "slide in" from the left, though it starts at 100% width when I want it to start at 0% width:
/* CSS */
.test-slide {
animation-duration: 3s;
animation-name: testSlide;
}
#keyframes testSlide {
from {
margin-left: 0%;
width: 50%;
}
to {
margin-left: 100%;
width: 100%;
}
}
<div class="test-slide">
<h1><span>ABOUT.</span></h1>
<!-- will slide in from the left -->
</div>
There's more -- unfortunately none of it mimics the website I'm trying to copy.
Explanation
There are multiple ways to achieve what you want actually. I did not opt to animate width. The first few frames of the animation will be not as expected.
So instead, we can use clip-path. What clip-path basically does is masking. You can "crop" a div such that only a part of it is visible. We will utilise clip-path and ::before or ::after pseudo-element (either is fine) to create this animation. What we need to do:
Create the pseudo-element and position it such that it covers (is on top) the whole animatable element (position: absolute)
Set the pseudo-element's background to black
Using clip-path, mask the animatable element to display no parts of the element (this will also cause the pseudo-element to not be displayed as it is part of the element). The direction of the clipping is important. The direction here is from the right side to the left side.
Using animation and #keyframes, unmask the previously masked div. This will reveal it slowly from the left side to the right side (because initially, we masked it from the right to left; upon unmasking, the reverse direction happens)
Upon unmasking the element, the pseudo-element will be on top of the text we want to display
After a short while later, mask the pseudo-element (not the whole element) from the right direction to the left direction, again using clip-path so that the text seems revealed slowly
It works! However, I recommend reading about clip-path. Also, one really handy clip-path CSS generator I really like to use is this (if you want to clip from the right to left, you should drag the points from the right to left). I also highly recommend reading about CSS positioning (a staple in good CSS animations). You needn't be using z-index: 9999; you generally want to keep track of the z-index you use.
Solution
Here's a working solution using the described method. Try running it.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Helvetica;
}
body,
html {
width: 100%;
height: 100%;
}
#wrapper {
background: #555555;
width: 100%;
height: 100%;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#wrapper * {
margin: 5px;
}
.heading {
font-size: 3em;
padding: 10px 5px;
}
.caption {
font-size: 1em;
padding: 5px;
font-family: Courier;
}
.animatable {
position: relative;
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1s 1 reveal forwards;
}
.animatable::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #20262b;
padding: inherit;
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1.75s 1 hideBlack forwards;
}
#keyframes reveal {
from { clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); }
to { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
}
#keyframes hideBlack {
from { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
to { clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%); }
}
<div id="wrapper">
<div class="heading animatable">Hi, I am Richard!</div>
<div class="caption animatable">I am a person.</div>
</div>
Although the simple animation you wanted can be created using merely CSS, I still suggest you read about how to make animations using JavaScript and the various libraries it has in making animations. This is because once there are many animations and transitions going on, it becomes hard to keep track of animations (especially when you want animations to start after another animation ends). A good library is anime.js (do explore more options before settling on one). Furthermore, notice how the animations only appear upon scrolling down in the website you provided? That's doable only with JS (one such method is using IntersectionObserver API provided by most browsers).
Here you have some CSS3 animations, you trigger that animation when the .entrance-animation gets the .active class.
You'll need an observer to watch when the item gets into view and, when the item is visible, you add the .active class to it.
Hope it helps!
setTimeout(() =>
{
let animate = document.querySelectorAll('.entrance-animation');
animate.forEach(item => item.classList.add('active'));
}
,1000);
.entrance-animation
{
position: relative;
color: blueviolet;
white-space: nowrap;
font-size: 24px;
width: 0;
overflow: hidden;
transition: width 0.5s ease;
}
.entrance-animation::before
{
content: '';
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
background-color: black;
z-index: 10;
transition: width 0.5s ease;
transition-delay: 0.5s;
}
.entrance-animation.active
{
width: 100%;
}
.entrance-animation.active::before
{
width: 0%;
}
<p class="entrance-animation">
Hello
</p>
<p class = "entrance-animation">
Here we are
</p>
You can use CSS3 transitions or maybe CSS3 animations to slide in an element.
For browser support: http://caniuse.com/
I made two quick examples just to show you how I mean.
CSS transition (on hover)
Demo One
Relevant Code
.wrapper:hover #slide {
transition: 1s;
left: 0;
}
In this case, Im just transitioning the position from left: -100px; to 0; with a 1s. duration. It's also possible to move the element using transform: translate();
CSS animation
Demo Two
#slide {
position: absolute;
left: -100px;
width: 100px;
height: 100px;
background: blue;
-webkit-animation: slide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: slide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes slide {
100% { left: 0; }
}
#keyframes slide {
100% { left: 0; }
}
Same principle as above (Demo One), but the animation starts automatically after 2s, and in this case I've set animation-fill-mode to forwards, which will persist the end state, keeping the div visible when the animation ends.
Like I said, two quick example to show you how it could be done.
EDIT: For details regarding CSS Animations and Transitions see:
Animations
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
Transitions
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Hope this helped.
We need to create a screensaver where image should roll over again and again continuously to the left. We coded as shown below.
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
.animator {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
animation: move-background 2s linear infinite;
position: absolute;
width: 100%;
height: 100%;
}
html,
body {
position: relative;
width: 100%;
height: 100%;
}
#keyframes move-background {
0% {
background-position: 0%, 0%;
}
100% {
background-position: 100%, 0%;
}
}
</style>
</head>
<body>
<div class="animator"></div>
</body>
</html>
The image is rolling over again and again as expected but every 2seconds, we are getting flickering effect. Please see the demo here.
As a fiddle
Can any one please help me to fix this or is there any way to achieve the effect of rolling one image over and over continuously using javascript?
I tried with javascript as below.
<script type="text/javascript">
var bdg_img = document.getElementById('bdgimg');
var animate;
function moveRight()
{
bdg_img.style.left = bdg_img.style.left || 0;
bdg_img.style.left = parseInt(bdg_img.style.left) + 10 + 'px';
animate = setTimeout(moveRight,40); // call moveRight in 20msec
}
moveRight();
</script>
But this is only moving the image to right. The image is not rolling over.
The percentage value in background-position: xxx% is relative to the element's size, not to your actual image's.
So if you want to keep the original background-image-size, you will have to set this background-position relative to your media's size:
.animator {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
background-position: 0% 50%;
animation: move-background 2s linear infinite;
width: 100vw;
height: 100vh;
}
#keyframes move-background {
to {
/* the image is 1225*800px */
background-position: -1225px 50%;
}
}
<div class="animator"></div>
Also note that when you do
background-position: 100%, 0%;
You are actually setting two background-position rules, which would be used only if you did set two background-image rules, and is indeed a short-hand for :
background-position-x: 100%, 0%;
background-position-y: 100%, 0%;
you can use very long animation time and repeat background to produce the effect.
*this animation play more than 10day (and may flicker once), but you can make it longer if you want.
*of course you can do the same thing (modify the style) in javascript by setInterval or alike. and have real infinity duration (at least until it reach numeric limit).
.canvas{
width: 300px;
height: 100px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
background-size: auto 100%;
background-repeat: repeat-x;
animation: move-background 1000000s linear infinite;
}
#keyframes move-background {
0% {
background-position: 0 0;
}
100% {
background-position: -20000000px 0;
}
}
<div class="canvas"></div>
I'm playing around with CSS animation, and I was wondering if there's a way to make a vertical line (with certain height) to grow in length automatically when the page loads. Idealy I want the vertical line to grow from the middle and grow from both top and bottom to a specific height. So far I can only make it increase its length from top to bottom. Here's what I have:
.vertical-line {
margin-left: 100px;
background: red;
width: 8px;
border-radius: 4px;
animation: grow 4s forwards;
}
#keyframes grow {
0% {
height: 10px;
}
100% {
height: 100px;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Creating Vertical borders using animation/javascript</title>
</head>
<body>
<div class="vertical-line"></div>
</body>
</html>
what is wrong witn your code is you are simply increasing the height.
In order to grow on both side while increasing height you have to move that element towards the opposite side
Example: if you are increasing height 100px then you have to move opposite for 50px
CSS:
#cool
{
height:10px;
width:10px;
border-radius:4px;
margin-left:10%;
background-color:#431;
margin-top:20%;
animation:grow 3s forwards;
position:relative;
}
#keyframes grow
{
0% {
height: 0px;
top:0;
}
100%{
height: 200px;
top:-100px;
}
}
</style>
HTML:
<div id=cool>
</div>
</body>
for height 100px moving the element top -50px . Taken half of it, because to show the growth on both side. if top -100px then it will grow from the bottom.
I hope this helps
One way you could accomplish this would be to set the initial position of the line in the very center, and then have it extend towards the top and the bottom of the viewport.
.myLine {
position: absolute;
left: 50vw;
top: 50vh;
width: 1px;
height: 1px;
}
You can then add a class, extended, via JavaScript that changes the position and height, thus making it appear to extend vertically from the center.
.extended {
top: 0vh;
bottom: 100vh;
height: 100%;
transition: all 3s ease;
}
Using JavaScript, as I've done here, you can set a brief timeout, and add the class after the timeout has finished.
var el = document.querySelector('.myLine');
setTimeout(function() {
el.classList.add('extended');
}, 300);
See my example codepen.
Try this,
<div class="vertical-line"></div>
<style>
.vertical-line {
position: absolute;
top: 0;
border: 5px solid red;
width: 10px;
border-radius: 4px;
animation: grow 3s infinite alternate;
}
#keyframes grow {
0% {
width: 0px;
height: 0px;
}
100% {
width: 20px;
height: 100%;
}
}
</style>