Adding a bounce effect using CSS animation - css

I'm playing round with CSS animation by trying to replicate the following new google ads logo - example.
What is the best way to add the bounce effect on the green ball?
My current animation:
#keyframes greenblock {
0% {
top: 0px;
}
50% {
top: 45px;
}
100% {
bottom: 0px;
}
}
My code (fiddle):
.wrap {
border: 1px solid red;
height: 300px;
width: 300px;
position: relative
}
.blue-shape {
position: absolute;
left: 100px;
top: 0px;
width: 45px;
height: 45px;
background: #4285F4;
display: block;
border-radius: 45px;
animation: blueblock 2s forwards;
transform-origin: top center;
}
.yellow-shape {
position: absolute;
left: 122px;
top: 0px;
width: 45px;
height: 45px;
background: #FBBC04;
display: block;
border-radius: 45px;
animation: yellowblock 2s forwards;
transform-origin: top center;
}
.green-ball {
position: absolute;
border-radius: 45px;
width: 45px;
height: 45px;
background: #34A853;
animation: greenblock 1.5s forwards;
}
#keyframes blueblock {
0% {
height: 45px;
}
25% {
height: 140px;
transform: rotate(0deg);
}
50% {
transform: rotate(-30deg);
}
100% {
height: 140px;
transform: rotate(-30deg);
}
}
#keyframes yellowblock {
0% {
height: 45px;
opacity: 0;
}
25% {
height: 140px;
transform: rotate(0deg);
opacity: 0;
}
50% {
transform: rotate(30deg);
}
100% {
height: 140px;
transform: rotate(30deg);
opacity: 100;
left: 122px;
}
}
#keyframes greenblock {
0% {
top: 0px;
}
50% {
top: 45px;
}
100% {
bottom: 0px;
}
}
<div class="wrap">
<div class="yellow-shape">
<div class="green-ball">
</div>
</div>
<div class="blue-shape">
</div>
</div>

I've tried with this animation
animation: greenblock .6s ease-in-out .5s forwards;
and this set of keyframes
#keyframes greenblock {
0% { top: 0px; }
75% { top: calc(100% - 55px); }
50%, 100% { top: calc(100% - 45px); }
}
Demo
.wrap {
border: 1px solid red;
height: 300px;
width: 300px;
position: relative
}
.blue-shape {
position: absolute;
left: 100px;
top: 0px;
width: 45px;
height: 45px;
background: #4285F4;
display: block;
border-radius: 45px;
animation: blueblock 2s forwards;
transform-origin: top center;
}
.yellow-shape {
position: absolute;
left: 122px;
top: 0px;
width: 45px;
height: 45px;
background: #FBBC04;
display: block;
border-radius: 45px;
animation: yellowblock 2s forwards;
transform-origin: top center;
}
.green-ball {
position: absolute;
border-radius: 45px;
width: 45px;
height: 45px;
background: #34A853;
animation: greenblock .6s ease-in-out .5s forwards;
}
#keyframes blueblock {
0% {
height: 45px;
}
25% {
height: 140px;
transform: rotate(0deg);
}
50% {
transform: rotate(-30deg);
}
100% {
height: 140px;
transform: rotate(-30deg);
}
}
#keyframes yellowblock {
0% {
height: 45px;
opacity: 0;
}
25% {
height: 140px;
transform: rotate(0deg);
opacity: 0;
}
50% {
transform: rotate(30deg);
}
100% {
height: 140px;
transform: rotate(30deg);
opacity: 100;
left: 122px;
}
}
#keyframes greenblock {
0% { top: 0px; }
75% { top: calc(100% - 55px); }
50%, 100% { top: calc(100% - 45px); }
}
<div class="wrap">
<div class="yellow-shape">
<div class="green-ball">
</div>
</div>
<div class="blue-shape">
</div>
</div>

Related

How to run CSS animation of two keyframes continuously

I would like to run my animation consisting of two keyframes to mimic the motion of a closing garage door, but the animation stops after one execution. Adding animation-iteration-count: 10; just flashes the 'door', doesn't rerun the whole animation. What could be the issue? Thank you in advance!
.house {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 150px;
}
.house .front {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 5.2em;
height: 4em;
border-left: 0.5em solid grey;
border-right: 0.5em solid grey;
}
.house .front .gable {
position: absolute;
top: -3.5em;
left: 50%;
width: 0;
height: 0;
transform: translateX(-50%);
border-left: 3.1em solid transparent;
border-right: 3.1em solid transparent;
border-bottom: 3.5em solid grey;
}
.house .front .door {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 4.2em;
height: 0.4em;
background: grey;
border-radius: 2px 2px 0 0;
overflow: hidden;
}
.house .front .door:before {
content: '';
display: block;
width: 40%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: black;
}
.house .front #d1 {
transform: translateX(-50%) translateY(-80%);
}
.house .front #d2 {
transform: translateX(-50%) translateY(-300%);
}
.house .front #d3 {
transform: translateX(-50%) translateY(-540%);
}
.house .front #d4 {
transform: translateX(-50%) translateY(-800%);
}
.house .front .doors .door {
animation-name: hide, up;
animation-duration: 1.6s;
animation-timing-function: ease-in;
animation-iteration-count: 1;
opacity: 1;
}
.house .front .doors #d4 {
animation-delay: 0s, 0s;
}
.house .front .doors #d3 {
animation-delay: 0s, 0.3s;
}
.house .front .doors #d2 {
animation-delay: 0s, 0.6s;
}
.house .front .doors #d1 {
animation-delay: 0s, 0.9s;
}
#keyframes hide
{
from { opacity: 0; } to { opacity: 0 }
}
#keyframes up
{
0% { opacity: 0; }
1% { opacity: 1; }
100% { opacity: 1; }
}
<div class="house">
<div class="front">
<div class="gable"></div>
<div class="doors">
<div id="d1" class="door"></div>
<div id="d2" class="door"></div>
<div id="d3" class="door"></div>
<div id="d4"class="door"></div>
</div>
</div>
</div>
sorry about this part, but SO wouldn't let me post this question unless more text is added.

CSS skewY transition bug in Safari (desktop and mobile)

The issue is visible when animating the skewY() property. Looks like the element's width shrinks down a little and no longer touches the sides of an equally wide container.
The same does not happen when animating with skewX() - the height is animated as expected.
I'm experiencing the bug in Safari only, both desktop and mobile browsers. Firefox and Chrome work as expected. This issue is visible during transition or animations only.
GIF previews:
Animation in Firefox/Chrome
Animation in Safari
.arrow {
position: absolute;
top: 20px;
left: 20px;
bottom: 20px;
right: 20px;
background-color: rgb(230, 230, 230);
}
.rect-x {
position: absolute;
left: calc(50vw - 50px);
top: 0;
width: 100px;
height: 100%;
background-color: blue;
animation: skew-x 1s linear alternate infinite;
transform-origin: center;
}
.rect-y {
position: absolute;
left: 0;
top: calc(50vh - 50px);
width: 100%;
height: 100px;
background-color: red;
animation: skew-y 1s linear alternate infinite;
transform-origin: center;
}
#keyframes skew-x {
0% { transform: skewX(15deg) skewY(0); }
to { transform: skewX(-15deg) skewY(-0);}
}
#keyframes skew-y {
0% { transform: skewX(0) skewY(15deg); }
to { transform: skewX(0) skewY(-15deg); }
}
<div class="arrow">
<div class="rect-y"></div>
<div class="rect-x"></div>
</div>
Try to use browser prefix.
.arrow {
position: absolute;
top: 20px;
left: 20px;
bottom: 20px;
right: 20px;
background-color: rgb(230, 230, 230);
}
.rect-x {
position: absolute;
left: calc(50vw - 50px);
top: 0;
width: 100px;
height: 100%;
background-color: blue;
animation: skew-x 1s linear alternate infinite;
-webkit-animation: skew-x 1s linear alternate infinite;
transform-origin: center;
-webkit-transform-origin: center;
}
.rect-y {
position: absolute;
left: 0;
top: calc(50vh - 50px);
width: 100%;
height: 100px;
background-color: red;
animation: skew-y 1s linear alternate infinite;
-webkit-animation: skew-y 1s linear alternate infinite;
transform-origin: center;
-webkit-transform-origin: center;
}
#keyframes skew-x {
0% { transform: skewX(15deg) skewY(0); }
to { transform: skewX(-15deg) skewY(-0);}
}
#-webkit-keyframes skew-x {
0% { -webkit-transform: skewX(15deg) skewY(0); }
to { -webkit-transform: skewX(-15deg) skewY(-0);}
}
#keyframes skew-y {
0% { transform: skewX(0) skewY(15deg); }
to { transform: skewX(0) skewY(-15deg); }
}
#-webkit-keyframes skew-y {
0% { -webkit-transform: skewX(0) skewY(15deg); }
to { -webkit-transform: skewX(0) skewY(-15deg); }
}
<div class="arrow">
<div class="rect-y"></div>
<div class="rect-x"></div>
</div>

Change slideshow speed CSS

I currently have a slideshow on my website but it is sliding too fast, I would like to make it slower but I dont know how can I do that, everytime I try to change some things I end up ruining everything.
I wanted to get like 5/6 seconds each slide.
I would be extremely grateful if someone could help me.
.topSlider {
display: block;
width: 100%;
height: 100%;
background-color: #1f1f1f;
overflow: hidden;
position: absolute; }
.topSlider span {
position: absolute;
color: white;
z-index: 1;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center; }
.topSlider .slide {
position: absolute;
display: block;
width: 100%;
height: 100%;
-webkit-animation: slide 12s infinite;
animation: slide 10s infinite;
overflow: hidden; }
.topSlider .slide:nth-child(2) {
left: 0%;
-webkit-animation-delay: -1s;
animation-delay: -0.5s;
background-color: black;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(3) {
left: 100%;
-webkit-animation-delay: 2s;
animation-delay: 2s;
background-color: red;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(4) {
left: 100%;
-webkit-animation-delay: 5s;
animation-delay: 4.5s;
background-color: white;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(5) {
left: 100%;
-webkit-animation-delay: 8s;
animation-delay: 7s;
background-color: blue;
background-size: cover;
background-position: center; }
.topSlider p {
text-align: center;
display: inline-block;
width: 100%;
margin-top: 340px;
color: white; }
#-webkit-keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
#keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
<div class="topSlider">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
You can change the seconds
-webkit-animation-delay: -1s;
animation-delay: -0.5s;
for each child.
but also make sure that the main slider time is proportional to the interval between the seconds in the slider children. Have a look at my example below and compare it to yours to see what I mean.
main slider time in your example:
-webkit-animation: slide 12s infinite;
animation: slide 10s infinite;
.topSlider {
display: block;
width: 100%;
height: 100%;
background-color: #1f1f1f;
overflow: hidden;
position: absolute; }
.topSlider span {
position: absolute;
color: white;
z-index: 1;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center; }
.topSlider .slide {
position: absolute;
display: block;
width: 100%;
height: 100%;
-webkit-animation: slide 20s infinite;
animation: slide 20s infinite;
overflow: hidden; }
.topSlider .slide:nth-child(2) {
left: 0%;
-webkit-animation-delay: -1s;
animation-delay: -0.5s;
background-color: black;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(3) {
left: 100%;
-webkit-animation-delay: 5s;
animation-delay: 4.5s;
background-color: red;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(4) {
left: 100%;
-webkit-animation-delay: 10s;
animation-delay: 9.0s;
background-color: white;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(5) {
left: 100%;
-webkit-animation-delay: 15s;
animation-delay: 13.5s;
background-color: blue;
background-size: cover;
background-position: center; }
.topSlider p {
text-align: center;
display: inline-block;
width: 100%;
margin-top: 340px;
color: white; }
#-webkit-keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
#keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
<div class="topSlider">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
You can change the duration part of the -webkit-animation and animation properties ("2s"):
-webkit-animation: slide 2s infinite;
animation: slide 2s infinite;
.topSlider {
display: block;
width: 100%;
height: 100%;
background-color: #1f1f1f;
overflow: hidden;
position: absolute; }
.topSlider span {
position: absolute;
color: white;
z-index: 1;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center; }
.topSlider .slide {
position: absolute;
display: block;
width: 100%;
height: 100%;
-webkit-animation: slide 6s infinite;
animation: slide 6s infinite;
overflow: hidden; }
.topSlider .slide:nth-child(2) {
left: 0%;
-webkit-animation-delay: 6s;
animation-delay: 6s;
background-color: black;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(3) {
left: 100%;
-webkit-animation-delay: 6s;
animation-delay: 6s;
background-color: red;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(4) {
left: 100%;
-webkit-animation-delay: 6s;
animation-delay: 6s;
background-color: white;
background-size: cover;
background-position: center; }
.topSlider .slide:nth-child(5) {
left: 100%;
-webkit-animation-delay: 6s;
animation-delay: 6s;
background-color: blue;
background-size: cover;
background-position: center; }
.topSlider p {
text-align: center;
display: inline-block;
width: 100%;
margin-top: 340px;
color: white; }
#-webkit-keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
#keyframes slide {
0% {
left: 100%;
width: 100%; }
5% {
left: 0%; }
25% {
left: 0%; }
30% {
left: -100%;
width: 100%; }
31% {
left: -100%;
width: 0%; }
100% {
left: 100%;
width: 0%; } }
<div class="topSlider">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>

Css Animation - animation delay

Update - The pen below has been updated to show the end results.
I am trying to mimic signal animation using css animation but I cant seem to grasp the idea of animation delay. If you look here
http://codepen.io/anon/pen/YwZOmK?editors=110
.real-time-animation {
margin-top: 20px;
position: relative;
transform: scale(0.5) rotate(45deg);
transform-origin: 5% 0%;
}
.real-time-animation>div {
animation: sk-bouncedelay 3s infinite forwards;
}
.circle1 {
animation-delay: 2s;
}
.circle2 {
animation-delay: 1s;
}
#keyframes sk-bouncedelay {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.circle {
position: relative;
width: 16em;
height: 16em;
border-radius: 50%;
background: transparent;
border: 20px solid transparent;
border-top-color: darkblue;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.circle2 {
top: 40px;
width: 12em;
height: 12em;
left: 33px;
}
.circle3 {
top: 80px;
width: 8em;
height: 8em;
left: 66px;
}
<div class="real-time-animation">
<div class="circle circle1"> </div>
<div class="circle circle2"> </div>
<div class="circle circle3"> </div>
</div>
You should be able to understand what I am trying to accomplish. I want to start from showing nothing, then after 1 sec show the first bar, then after 1 sec, show the 2nd bar and finally after another 1 sec show the 3rd bar.
My solution:
http://codepen.io/anon/pen/JGWmJg?editors=110
.real-time-animation{
margin-top: 20px;
position: relative;
transform: scale(0.5) rotate(45deg);
transform-origin: 5% 0%;
}
.circle1, .circle2, .circle3{
animation: 4s infinite ease-in;
animation-delay: 1s;
}
.circle1{
animation-name: circle1;
}
.circle2{
animation-name: circle2;
}
.circle3{
animation-name: circle3;
}
#keyframes circle1 {
0%{
opacity: 0;
}
25%{
opacity: 0;
}
50%{
opacity: 0;
}
75%{
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes circle2 {
0%{
opacity: 0;
}
25%{
opacity: 0;
}
50%{
opacity: 1;
}
75% {
opacity: 1;
}
100%{
opacity: 0;
}
}
#keyframes circle3 {
0%{
opacity: 0;
}
25%{
opacity: 1;
}
50%{
opacity: 1;
}
75% {
opacity: 1;
}
100%{
opacity: 0;
}
}
.circle {
position: relative;
width: 16em; height: 16em;
border-radius: 50%;
background: transparent;
border: 20px solid transparent;
border-top-color: darkblue;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.circle2{
top: 40px;
width: 12em;
height: 12em;
left: 33px;
}
.circle3{
top: 80px;
width: 8em;
height: 8em;
left: 66px;
}
You can change the speed of the animation duration: "animation: 4s infinite ease-in;"
As I understand your question animated opacity needs to be like this:
Progress \ Element
.circle1
.circle2
.circle3
0%
0
0
0
25%
0
0
1
50%
0
1
1
75%
1
1
1
100%
0
0
0
The opacity property is clamped which means if you set negative values, it will have the same effect as setting it to 0. The same goes for values larger than 1.
Using this property, we can subtract a constant value from predefined CSS variables and use that as opacity.
.real-time-animation {
zoom: 10;
width: 8px;
height: 8px;
position: relative;
display: inline-block;
}
.real-time-animation>.circle {
animation: circle 4s infinite ease-in;
}
.circle1 {
--circle: 1;
}
.circle2 {
--circle: 2;
}
.circle3 {
--circle: 3;
}
#keyframes circle {
0%, 100% {
opacity: 0;
}
25% {
opacity: calc(var(--circle) - 2);
}
50% {
opacity: calc(var(--circle) - 1);
}
75% {
opacity: 1;
}
}
.circle {
border-radius: 50%;
background: transparent;
border: 1px solid transparent;
border-top-color: darkblue;
position: absolute;
margin: 0;
box-sizing: border-box;
top: 100%;
left: 0%;
width: calc(16px - (var(--circle) - 1)*4px);
height: calc(16px - (var(--circle) - 1)*4px);;
transform: rotate(45deg) translate(-50%, -50%);
transform-origin: 0 0;
}
<div class="real-time-animation">
<div class="circle circle1"> </div>
<div class="circle circle2"> </div>
<div class="circle circle3"> </div>
</div>

CSS3 transform: translateX equivalent for right

I want to do this: -webkit-transform: translateX(300px) but from the right instead of having the origin on left.
I tried -webkit-transform-origin: 100% 100% and even top right and it didn't affect it.
Is there a way to do it?
By the power of CSS:
body {
padding: 0;
margin: 0;
}
#page {
position: absolute;
width: 100%;
height: 100%;
background-color: black;
z-index:2;
right:0;
}
#left_drawer {
background-color: #222222;
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 100%;
z-index: 1;
}
#toggle {
width: 50px;
height: 50px;
background-color: red;
float: right;
}
.open_drawer {
-webkit-animation: open_drawer 300ms ease-in-out;
-webkit-animation-fill-mode: forwards;
-webkit-transform: translateX(0);
}
#-webkit-keyframes open_drawer {
to {
-webkit-transform: translateX(-300px);
}
}
This will make it slide in from the right. Fiddle.

Resources