CSS Animation Sequence - html

I've been coding a very simple "Traffic Light" program and have run into a problem where it doesn't run after the first #keyframes section completes correctly. From my own research online I'm guessing that I would need a transition(?) so that when the first #keyframes is complete, the next one would be run. However my inexperience with this I'm not sure if its whats required here. Essentially is there a "trigger" I'm missing or is it just something obvious I've left out?
Please excuse the rough code. Its does work as I described above
body {
background-color: #4d4d00
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
#red {
position: absolute;
left: 50px;
text-align: center;
padding: 30px;
background-color: #e60000;
margin: 10px auto;
width: 50px;
height: 50px;
border-radius: 200px;
animation: red 4s 1s 3 linear;
}
#amber {
position: absolute;
left: 1px;
text-align: center;
padding: 30px;
background-color: #ff3300;
margin: 10px auto;
width: 50px;
height: 50px;
border-radius: 200px;
animation: amber 4s 1s 3 linear;
}
#green {
position: absolute;
left: 1px;
text-align: center;
padding: 30px;
background-color: #009933;
margin: 10px auto;
width: 50px;
height: 50px;
border-radius: 200px;
animation: green 4s 1s 3 linear;
}
#keyframes red {
from {
background-color: #e60000;
}
to {
background-color: #000000;
}
#keyframes amber {
from {
background-color: #ff3300;
}
to {
background-color: #000000;
}
#keyframes green {
from {
background-color: #009933;
}
to {
background-color: #000000;
}
}
<div class="container">
<div class="row">
<div id="red">
<br>
<br>
<div id="amber">
<br>
<br>
</div>
</div>
</div>
</div>

you may use animation-delay.
here is a short/minimal code example.
.red {
background: red;
}
.orange {
background: orange
}
.green {
background: lime;
}
/* layout */
div {
display: flex;
height: 150px;
width: 50px;
flex-direction: column;
border-radius: 1em;
background: #555;
margin: 1em;
}
b {
flex: 1;
margin: 5px;
border-radius: 50%;
animation: fade 9s steps(2, end) infinite;
box-shadow: 0 0 5px white
}
/* animation */
#keyframes fade {
66%,
100% {
background: gray;
box-shadow: 0 0
}
}
.red {
animation-delay: -12s
}
.orange {
animation-delay: -6s;
}
<div class=trafficLights>
<b class=red></b>
<b class=orange></b>
<b class=green></b>
</div>
here is a codepen to play with : https://codepen.io/gc-nomade/pen/YVWeQq

You have two way to do this
1) is use animation-delay and set an higher delay to elements you would like to animate after.
animation-delay: 1s;
-webkit-animation-delay:1s;
2) trigger an element.addClass("animatedClass"); with the end of a css animation using animationonend jquery function.
$(".animatedElement").one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(event) {
$(".animatedElement").addClass("newAnimatedClass");
});

Related

Blur the edges of a backdrop-filter element with CSS

document.querySelector( 'style' ).innerHTML += `
div {
width: 40rem;
height: 1rem;
background-color: #444;
}
.earth_orbit, .moon {
width: 15rem;
margin-left: 100%;
background-color: #222;;
}
.earth_orbit::before {
width: 5rem;
height: 5rem;
background-color: #08f;
}
.moon {
width: 2.5rem;
height: 2.5rem;
background-color: #ddd;
}
section {
right: 5%;
width: 37.5%;
height: 50%;
font-size: 5rem;
font-weight: bold;
text-align: center;
backdrop-filter: blur( 2rem );
-webkit-backdrop-filter: blur( 2rem );
/* filter: blur( 1rem ); */ /* Only blur inside element, ignoring the paremter */
}
`;
*, * ::before, * ::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, main {
overflow: hidden;
height: 100%;
background-color: #111;
color: #eee;
}
html {
font-family: Arial;
font-size: 1.5vmin;
}
main, div, section {
display: flex;
justify-content: center;
align-items: center;
}
div, div::before, section {
position: absolute;
z-index: auto;
width: 10rem;
height: 10rem;
background-color: #f90;
border-radius: 5rem;
content: '';
}
.moon::before {
display: none;
}
<style>
.sun_orbit, .earth_orbit, section {
background-color: transparent;
}
span {
color: #ccc;
font-size: 4rem;
}
.rotate {
animation-name: rotate;
animation-duration: 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes rotate {
0% { transform: rotate( 0deg ); }
100% { transform: rotate( 360deg ); }
}
.offset {
animation-duration: 1s;
}
</style>
<main>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
<section>
<p>blurred overlay<br><span>( backdrop-filter )</span></p>
</section>
</main>
Where the CSS property backdrop-filter is used there are always sharp edges along the elements border. However to blur the edges themselves along with all content underneath is the desired result. setting filter: blur( *value* ) on the target element doesn't seem to do the trick in any browser i've tested.
There's this question asked over a year ago with no answer and perhaps not as clear an example of what is trying to be accomplished here. Every time the 'planets' go behind the blurred div you can see a clear edge of where the div begins and ends - like crisp glass. I'd like to find a way to maintain all the effects here but blur that edge or border along the 'glass' or backdropped overlay.
The only work-around I found was faking backdrop-filter blur by duplicating all elements to be affected then creating a "window" overlapping the background positioned to it's exact location with a regular filter: blur( n ) applied.
document.querySelector( 'style' ).innerHTML += `
.earth_orbit, .moon {
width: 15rem;
margin-left: 100%;
background-color: #222;;
}
.earth_orbit::before {
width: 5rem;
height: 5rem;
background-color: #08f;
}
.moon::before {
display: none;
}
.moon {
width: 2.5rem;
height: 2.5rem;
background-color: #ddd;
}
.sun_orbit, .earth_orbit {
background-color: transparent;
}
footer {
right: 5%;
width: 20rem;
height: 20rem;
background-color: transparent;
}
.rotate {
animation-name: rotate; animation-duration: 4s;
animation-timing-function: linear; animation-iteration-count: infinite;
}
`;
*, * ::before, * ::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, main {
overflow: hidden;
height: 100%;
background-color: #111;
color: #eee;
}
html {
font-family: Arial;
font-size: 1.5vmin;
}
main, div, footer {
display: flex;
justify-content: center;
align-items: center;
}
div, div::before, footer {
position: absolute;
z-index: auto;
width: 10rem;
height: 10rem;
background-color: #f90;
border-radius: 5rem;
content: '';
}
div {
width: 40rem; height: 1rem;
background-color: #444;
}
<style>
footer .sun_orbit { top: 9.5rem; left: -13.25vmax; }
section { width: 70%; height: 70%; }
p {
position: relative; z-index: 10; font-size: 2rem; left: 30vh;
}
footer {
overflow: hidden; background-color: #111;
z-index: 10; filter: blur( 1rem ); left: 54.5vmax;
}
#keyframes rotate {
0% { transform: rotate( 0deg ); }
100% { transform: rotate( 360deg ); }
}
.offset { animation-duration: 1s; }
</style>
<main>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
<footer>
<section>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
</section>
</footer>
<p>backdrop overlay<br>with faded edges</p>
</main>
Added benefit is this whole effect now works in Firefox when at first it didn't. Also: This could be made responsive if so desired.

Expands background on a circle shape

I'm trying to do a circle that expands-change color from the center, and i want it to expand it with border-radius: 50%, you'll understand what i'm talking about if you watch the example i made
Checkout the sample i made for better understanding
Thanks for any help
You could run a transition over an inset box-shadow, like so
div {
width: 300px;
height: 300px;
display: flex;
color: #FFF;
justify-content: center;
align-items: center;
border-radius: 50%;
background: #03BF60;
cursor: pointer;
transition: box-shadow .75s 0s, color .5s 0s;
box-shadow: inset 0 0 0 0 #DCEDC8;
}
div p {
color: inherit;
text-align: center;
}
div:hover {
color: #444;
box-shadow: inset 0 0 0 150px #DCEDC8;
}
<div>
<p>
Responsive design. I get this certificate by
learning HTML, CSS, web design, media query plus
animations using keyframes, declaring variables
on css and a lot of CSS components.
</p>
</div>
You could to use Keyframes...
<div class="shape">
<div class="to-animate animate"></div>
</div>
.shape {
border-radius: 50%;
width: 200px;
height: 200px;
background: red;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.to-animate {
width: 0;
height: 0;
background: blue;
}
.animate {
animation: my-animation 1s forwards;
}
#keyframes my-animation {
to {
width:200px;
height: 200px;
}
}
https://jsfiddle.net/hernangiraldo89/ba3ne675/
Keyframes are a powerful tool, here its documentation:
https://developer.mozilla.org/en-US/docs/Web/CSS/#keyframes

animate border bottom length from 0 to 100

i need to animate the border bottom of the div using keyframe animation without using :before or :after or modifying the current html structure
div{
padding:3px 6px;
display:inline-block;
position:relative;
border-bottom: 2px solid black;
}
<div><h1>Lorem Ipsum</h1></div>
You can simulate it like below. Hope that helps.
.container {
padding: 3px 6px;
display: inline-flex;
flex-direction: column;
}
.underline {
height: 2px;
max-width: 0%;
background-color: black;
animation: drawBorder 2s ease forwards;
}
#keyframes drawBorder {
from {
max-width: 0%;
}
to {
max-width: 100%;
}
}
<div class="container">
<h1>Lorem Ipsum</h1>
<div class="underline"></div>
</div>
Use gradient:
div.box {
padding: 3px 6px;
display: inline-block;
position: relative;
background: linear-gradient(#000, #000) bottom/0% 2px no-repeat;
transition:1s all;
}
div.box:hover {
background-size: 100% 2px;
}
<div class="box">
<h1>Lorem Ipsum</h1>
</div>

CSS progress bar animation

I am having a progess bar which should become filled up by 50% width.
This is my current html and css for the progress bar.
HTML:
<div id="ProgressBar">
<div id="Progress"></div>
</div>
CSS:
#ProgressBar {
width: 100%;
height: 30px;
border: 1px solid black;
border-radius: 7px;
padding: 4px;
}
#Progress {
width: 10%;
background-color: #4A90E2;
height: 100%;
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
border-color: #4A90E2;
-webkit-transition: width 2s; /* For Safari 3.1 to 6.0 */
transition: width 2s;
}
#Progress:hover {
width: 50%;
}
As you can see the transition is starting after a hover over the progress. My goal is to have this transaition starting directly after the page loads. I know there are some examples in the internet but they are all having fade-in effects only and I can't figure it out.
I appreciate your help.
Here my fiddle:
https://jsfiddle.net/Anokrize/ssL9fjy9/
(I would like to avoid any javascript or jquery, if that is possible)
How about doing it with keyframes, like this:
#ProgressBar {
width: 100%;
height: 30px;
border: 1px solid black;
border-radius: 7px;
padding: 4px;
}
#Progress {
width: 50%;
background-color: #4A90E2;
height: 100%;
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
border-color: #4A90E2;
animation-name: progressBar;
animation-iteration-count: 1;
animation-duration: 2s;
}
#keyframes progressBar {
0% {
width: 10%;
}
100% {
width: 50%;
}
}
<div id="ProgressBar">
<div id="Progress"></div>
</div>
A straight forward way of getting this done is through jquery:
$(window).load(function() {
$("#Progress").css("width", "50%");
});
Usually you'd want something feeding a progress bar so it's actually showing progress... but if you just want it to start on load, you can use the animation property with keyframes.
#ProgressBar {
width: 100%;
height: 30px;
border: 1px solid black;
border-radius: 7px;
padding: 4px;
}
#Progress {
width: 10%;
background-color: #4A90E2;
height: 100%;
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
border-color: #4A90E2;
animation: progress 1s ease-out forwards;
}
#keyframes progress {
from { width: 10%; }
to { width: 50%; }
}

How to pause an animation at the last keyframe

I'm trying to let the animation pause in the last keyframe, so if the lines are at 50% of the page they will stay there and not go back to the first keyframe.
Also is css the best way to do this or is there a easier way to solve this?
The css:
body, html {
height: 100%;
text-align: center;
margin: 0;
}
body {
background-color: royalblue;
}
.loader {
display: inline-block;
width: 30px;
height: 30px;
position: relative;
border: 4px solid white;
top: 50%;
animation: loader 4s ease;
}
.line1 {
position: relative;
display: inline-block;
top: 0;
width: 5px;
height: 10px;
border: 2px solid #fff;
background-color: #fff;
left: 20%;
animation: lines 5s infinite ease;
}
.line2 {
position: relative;
display: inline-block;
top: 0;
width: 5px;
height: 10px;
border: 2px solid #fff;
background-color: #fff;
right: 20%;
animation: lines 5s infinite ease;
}
#keyframes lines {
0% { height: 10px; }
25% { height: 10px; }
50% { height: 50%; }
75% { height: 50%; }
100% { height: 50%;
-webkit-animation-play-state: paused; /* Chrome, Safari, Opera */
animation-play-state: paused; }
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Loader1 - by Thom</title>
<!-- Custom loading-thom -->
<link href="style.css" rel="stylesheet">
</head>
<body>
<span class="line1"></span>
<span class="line2"></span>
</body>
</html>
You could use animation-fill-mode property with forwards as value.
CSS
.line1{
position: relative;
display: inline-block;
top: 0;
width: 5px;
height: 10px;
border: 2px solid #fff;
background-color: #fff;
left: 20%;
animation: lines 5s forwards ease;
}
.line2{
position: relative;
display: inline-block;
top: 0;
width: 5px;
height: 10px;
border: 2px solid #fff;
background-color: #fff;
right: 20%;
animation: lines 5s forwards ease;
}
DEMO HERE
What you are looking for is something called animation-fill. You can read more about it here: http://www.w3schools.com/cssref/css3_pr_animation-fill-mode.asp
So essentially:
.line1,
.line2 {
animation-fill: forwards;
}
Also make sure that the animation-fill is declared after the animation rule.
SOLUTION 1:
Your can change animation-fill to forward
SOLUTION 2:
use jquery
<script>
$(document).ready(function(){
var half = $(document).height()/2;
setTimeout(function(){
$('.line1 , .line2').animate({height:half});
},1000);
});
In DEMO below, press Run in jsFiddle;
DEMO: https://jsfiddle.net/0andyke4/5/