I am trying to create animation with this arrow that will move up and down and also rotate or change its direction on 0% and 100%. But what I got so far is that arrow will rotate for sec on 100% and then return back to previous direction. So basically what I am trying to do is, arrow should point up on its way up and point down on return or on its way down. Can I do this with just CSS animations?
DEMO
On way up arrow should have this direction and on way down this one
Also I want to animate that rotation on 100% and 0% with rotate if its possible.
Just Change the animation with below code
#keyframes bounceAndRotate {
0% {
transform:rotate(0deg);top:-20px;
}
25% {
transform:rotate(00deg);top:-10px;
}
50% {
transform:rotate(0deg);top:0px;
}
75% {
transform:rotate(180deg);top:10px;
}
100% {
transform: rotate(180deg);top:20px;
}
}
For Demo
CLICK HERE For Demo
Just do away with the alternating direction setting and adjust the keyframe settings such that for the first 50% duration the upward movement and spin is done and then for the next 50% it comes down with the arrow facing downwards. The animation-duration should be doubled because the alternate effect is produced by the keyframes itself.
But doing this would spoil one part of your current animation where the arrow spins to face downward and then spins back to face upwards. Also removing alternate would make the reverse rotation on 100% not happen. But that can be overcome by adding an extra keyframe. This extra keyframe must mirror the initial position of the element (which is no rotation).
.arrow {
height: 50px;
position: relative;
width: 10px;
background: black;
margin: 100px;
display: inline-block;
animation: bounceAndRotate 2s infinite linear;
}
.arrow:before {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(50deg);
left: -10px;
}
.arrow:after {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(-50deg);
right: -10px;
}
#keyframes bounceAndRotate {
0% {
transform: translateY(0) rotate(0deg);
}
12.5% {
transform: translateY(-10px);
}
25% {
transform: translateY(-20px);
}
37.5% {
transform: translateY(-30px);
}
50% {
transform: translateY(-40px) rotate(180deg);
}
90% {
transform: translateY(0px) rotate(180deg);
}
100% {
transform: translateY(0px);
}
}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div class="arrow"></div>
If you want that part also to be maintained before the downward move then add extra keyframes like in the below snippet. Here the sequence of events is as follows:
Arrow goes upwards with arrow head pointing upwards.
When it reaches the topmost point, it rotates 180deg such that the arrow head points downwards.
Once the rotation is complete, it again rotates back to its original position (arrow head pointing up while maintaining the position)
Once this is complete, it again rotates 180deg such that the arrow head points downwards.
Arrow moves downwards with the arrow head pointing downwards.
.arrow {
height: 50px;
position: relative;
width: 10px;
background: black;
margin: 100px;
display: inline-block;
animation: bounceAndRotate 2s infinite linear;
}
.arrow:before {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(50deg);
left: -10px;
}
.arrow:after {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(-50deg);
right: -10px;
}
#keyframes bounceAndRotate {
0% {
transform: translateY(0) rotate(0deg);
}
12.5% {
transform: translateY(-10px);
}
25% {
transform: translateY(-20px);
}
37.5% {
transform: translateY(-30px);
}
45% {
transform: translateY(-40px) rotate(180deg);
}
55%, 60%{
transform: translateY(-40px);
}
67.5%{
transform: translateY(-40px) rotate(180deg);
}
90% {
transform: translateY(0px) rotate(180deg);
}
100% {
transform: translateY(0px);
}
}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div class="arrow"></div>
You can do like following way:
.arrow {
height: 50px;
position: relative;
width: 10px;
background: black;
margin: 100px;
display: inline-block;
animation: bounceAndRotate 2s infinite linear alternate;
}
.arrow:before {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(50deg);
left: -10px;
}
.arrow:after {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(-50deg);
right: -10px;
}
#keyframes bounceAndRotate {
0% {
transform: translateY(10px) rotate(0deg);
}
20% {
transform: translateY(-20px);
}
50% {
transform: translateY(-40px) rotate(180deg);
}
60% {
transform: translateY(-30px) rotate(180deg);
}
80% {
transform: translateY(-20px) rotate(180deg);
}
100% {
transform: translateY(0px) rotate(180deg);
}
}
<div class="arrow"> </div>
Hope it helps. Working Fiddle
Edit:
And if you want 360 degree rotation then do like following by removing alternative:
.arrow {
height: 50px;
position: relative;
width: 10px;
background: black;
margin: 100px;
display: inline-block;
animation: bounceAndRotate 2s infinite linear;
}
.arrow:before {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(50deg);
left: -10px;
}
.arrow:after {
content: " ";
width: 10px;
background: black;
height: 35px;
position: absolute;
top: -10px;
transform: rotate(-50deg);
right: -10px;
}
#keyframes bounceAndRotate {
0% {
transform: translateY(10px) rotate(0deg);
}
20% {
transform: translateY(-20px);
}
50% {
transform: translateY(-40px) rotate(180deg);
}
60% {
transform: translateY(-30px) rotate(180deg);
}
80% {
transform: translateY(-20px) rotate(180deg);
}
100% {
transform: translateY(0px) rotate(360deg);
}
}
<div class="arrow"> </div>
Thanks for all anwsers, but this is what i ended up with
DEMO
#keyframes bounceAndRotate {
0% {
transform: translateY(0px) rotate(0deg);
}
35% {
transform: translateY(-195px) rotate(0deg);
}
50% {
transform:translateY(-200px) rotate(180deg);
}
85% {
transform: translateY(-5px) rotate(180deg);
}
100% {
transform: translateY(0px) rotate(0deg);
}
}
Related
I'm trying to get this circle loader working properly but having difficulty. I can do some basic animations, but this code which I found on CodePen is a bit above my pay-grade. I'm trying to use it to understand what's happening.
My objective is that the loader doesn't go all the way around the circumference of the circle. Say, only 68% of the way and stops. Or 98%. But I'm thus far unable to locate the property/value which determines how far the loader goes around the circle.
I've tried manipulating the keyframes on the right loader class to no avail as well as the transform-origin property. No dice.
Code:
#circle-loader-wrap {
overflow: hidden;
position: relative;
margin-top: -10px;
width: 200px;
height: 200px;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1) inset;
background-color: blue;
border-radius: 200px;
-ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
#circle-loader-wrap:after {
content: '';
position: absolute;
left: 15px;
top: 15px;
width: 170px;
height: 170px;
border-radius: 50%;
background-color: green;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
#circle-loader-wrap div {
overflow: hidden;
position: absolute;
width: 50%;
height: 100%;
}
#circle-loader-wrap .loader {
position: absolute;
left: 100%;
top: 0;
width: 100%;
height: 100%;
border-radius: 1000px;
background-color: pink;
}
#circle-loader-wrap .left-wrap {
left: 0;
}
#circle-loader-wrap .left-wrap .loader {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
transform-origin: 0 50% 0;
-webkit-transform-origin: 0 50% 0;
animation: loading-left 20s infinite linear;
-webkit-animation: loading-left 20s infinite linear;
}
#circle-loader-wrap .right-wrap {
left: 50%;
}
#circle-loader-wrap .right-wrap .loader {
left: -100%;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
transform-origin: 100% 50% 0;
-webkit-transform-origin: 100% 50% 0;
animation: loading-right 20s infinite linear;
-webkit-animation: loading-right 20s infinite linear;
}
#keyframes loading-left {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(180deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes loading-left {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(180deg);
}
50% {
-webkit-transform: rotate(180deg);
}
75% {
-webkit-transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
#keyframes loading-right {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(180deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes loading-right {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
}
75% {
-webkit-transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
<div class="container mt-5">
<div class="row">
<div class="col-3">
<div id="circle-loader-wrap">
<div class="left-wrap">
<div class="loader"></div>
</div>
<div class="right-wrap">
<div class="loader"></div>
</div>
</div>
</div>
</div>
</div>
I am pasting a snippet below which does what you want.
I have written my explanation of what's going on directly into the code comments next to the css rules that are doing the corresponding animation.
In case anything is still unclear, post a comment.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
#circle-loader-wrap {
overflow: hidden;
position: relative;
margin-top: -10px;
width: 200px;
height: 200px;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1) inset;
background-color: blue;
border-radius: 200px;
transform: rotate(180deg);
}
#circle-loader-wrap:after {
content: '';
position: absolute;
left: 15px;
top: 15px;
width: 170px;
height: 170px;
border-radius: 50%;
background-color: green;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
#circle-loader-wrap div {
overflow: hidden;
position: absolute;
width: 50%;
height: 100%;
}
#circle-loader-wrap .loader {
position: absolute;
left: 100%;
top: 0;
width: 100%;
height: 100%;
border-radius: 1000px;
background-color: pink;
}
#circle-loader-wrap .left-wrap {
left: 0;
}
#circle-loader-wrap .left-wrap .loader {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
transform-origin: 0 50% 0;
animation: loading-left 5s infinite linear;
}
#circle-loader-wrap .right-wrap {
left: 50%;
}
#circle-loader-wrap .right-wrap .loader {
left: -100%;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
transform-origin: 100% 50% 0;
animation: loading-right 5s infinite linear;
}
#keyframes loading-left {
0% {
transform: rotate(0deg);
}
25%, 100% {
transform: rotate(180deg);
}
}
#keyframes loading-right {
0%, 25% {
transform: rotate(0deg);
}
50%, 100% {
/* the following is for the second half of the cicrle */
/* 180deg means one half of the cicle or 50% of the cicle */
/* So, 1% is gonna be 180/50 = 3.6deg */
/* If you want 68%, then you have 18% left for the second half of the circle */
/* To get 18%: 18x3.6 = 64.8deg */
transform: rotate(64.8deg);
/* Note: The transformation will happen between 25% and 50% of the total time which is 5 seconds in this case; So, it's gonna take 1.25 seconds. */
/* In other words, it will take the same amount of time as for the first half of the circle which will make the transformation in the second half appear to be slower because it has the same time to cover a much shorter distance */
/* Between 50% and 100% nothing happens. */
/* That's your "pause" in this animation although technically it's not a pause. */
}
}
</style>
<div class="container mt-1">
<div class="row">
<div class="col">
<p>68% in this case:</p>
<div id="circle-loader-wrap">
<div class="left-wrap">
<div class="loader"></div>
</div>
<div class="right-wrap">
<div class="loader"></div>
</div>
</div>
<p>The comments next to the corresponding css rules show how to adjust.</p>
</div>
</div>
</div>
Also note: I ripped out the vendor prefixes because you don't really need those nowadays for those css rules.
I am running into an issue in my mobile media query - anything under a 640px viewport. I have a circle that comes together and forms a full circle (see snippet), but for some reason in my media query, the circle doesn't quite line up, and I am unsure why as I am using the same math that makes it work in a desktop version.
Here is what it looks like within the 640 media query:
So how this works is I give .circle the same height and width. So let's say 200px for both height and width.
Then the class of .spinner, I divide the height and width of the .circle by two. So I would have 125px for height and width.
Then I set the border size, so lets use 5px. What I do is add that border size to the height and width numbers of .spinner and use that figure, which would be 130px to everything else ranging from .top, .bottom, q2, mask, etc.
That is how I get this to work and my math in my media query is not wrong. Does anyone see why this isn't lining up?
.blue {
background-color: blue;
width: 100%;
height: 600px;
}
.circle {
z-index: 99;
width: 500px;
height: 500px;
position: absolute;
background: inherit;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%) rotate(0deg);
transform: translate(-50%, -50%) rotate(0deg);
}
.spinner {
width: 250px;
height: 250px;
position: absolute;
border: 5px solid #b5f2ff;
z-index: 10;
}
.top {
top: 255px;
left: 255px;
border-radius: 0 0 255px 0;
border-left: none;
border-top: none;
-webkit-transform-origin: top left;
transform-origin: top left;
}
.bottom {
border-radius: 255px 0 0 0;
border-bottom: none;
border-right: none;
-webkit-transform-origin: bottom right;
transform-origin: bottom right;
}
.topright,
.bottomleft {
-webkit-animation: rotate90 4s linear forwards;
animation: rotate90 4s linear forwards;
}
.topleft,
.bottomright {
-webkit-animation: rotate180 4s linear forwards;
animation: rotate180 4s linear forwards;
}
.mask {
width: 255px;
height: 255px;
position: absolute;
opacity: 1;
background: inherit;
z-index: 15;
-webkit-animation: mask 4s linear forwards;
animation: mask 4s linear forwards;
}
.q2 {
top: 0;
left: 0;
}
.q4 {
top: 255px;
left: 255px;
}
#-webkit-keyframes rotate90 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
20%,
80% {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
#keyframes rotate90 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
20%,
80% {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
#-webkit-keyframes rotate180 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
40%,
60% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
#keyframes rotate180 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
40%,
60% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
#-webkit-keyframes mask {
0% {
z-index: 15
}
40%,
60% {
z-index: 4
}
100% {
z-index: 15
}
}
#keyframes mask {
0% {
z-index: 15
}
40%,
60% {
z-index: 4
}
100% {
z-index: 15
}
}
#circle-text {
display: none;
position: absolute;
color: #FFF;
font-size: 2.3em;
text-align: center;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
z-index: 100;
}
#media screen and (max-width:640px) {
.circle {
z-index: 100;
width: 250px;
height: 250px;
-webkit-transform: translate(-50%, -50%) rotate(0deg);
transform: translate(-50%, -50%) rotate(0deg);
}
.spinner {
width: 125px;
height: 125px;
z-index: 10;
}
.top {
top: 130px;
left: 130px;
border-radius: 0 0 130px 0;
}
.bottom {
border-radius: 130px 0 0 0;
}
.mask {
width: 130px;
height: 130px;
}
.q4 {
top: 130px;
left: 130px;
}
}
<div class="blue">
<div class="circle">
<div class="spinner top topright"></div>
<div class="spinner top topleft"></div>
<div class="spinner bottom bottomleft"></div>
<div class="spinner bottom bottomright"></div>
<div class="mask q2"></div>
<div class="mask q4"></div>
</div>
</div>
You have an inconsistent use of box-sizing:border-box in your CSS. It's being used in media queries, so that it doesn't apply to all screen sizes. And it would mess up your calculations.
I`m working on an animated heart only with CSS.
I want it to pulse 2 times, take a small break, and then repeat it again.
What I have now:
small ==> big ==> small ==> repeat animation
What I'm going for:
small ==> big ==> small ==> big ==> small ==> pause ==> repeat animation
How can I do it?
My code :
#button{
width:450px;
height:450px;
position:relative;
top:48px;
margin:0 auto;
text-align:center;
}
#heart img{
position:absolute;
left:0;
right:0;
margin:0 auto;
-webkit-transition: opacity 7s ease-in-out;
-moz-transition: opacity 7s ease-in-out;
-o-transition: opacity 7s ease-in-out;
transition: opacity 7s ease-in-out;}
#keyframes heartFadeInOut {
0% {
opacity:1;
}
14% {
opacity:1;
}
28% {
opacity:0;
}
42% {
opacity:0;
}
70% {
opacity:0;
}
}
#heart img.top {
animation-name: heartFadeInOut;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 1s;
animation-direction: alternate;
}
<div id="heart" >
<img class="bottom" src="https://goo.gl/nN8Haf" width="100px">
<img class="top" src="https://goo.gl/IIW1KE" width="100px">
</div>
See also this Fiddle.
You can incorporate the pause into the animation. Like so:
#keyframes heartbeat
{
0%
{
transform: scale( .75 );
}
20%
{
transform: scale( 1 );
}
40%
{
transform: scale( .75 );
}
60%
{
transform: scale( 1 );
}
80%
{
transform: scale( .75 );
}
100%
{
transform: scale( .75 );
}
}
Working example:
https://jsfiddle.net/t7f97kf4/
#keyframes heartbeat
{
0%
{
transform: scale( .75 );
}
20%
{
transform: scale( 1 );
}
40%
{
transform: scale( .75 );
}
60%
{
transform: scale( 1 );
}
80%
{
transform: scale( .75 );
}
100%
{
transform: scale( .75 );
}
}
div
{
background-color: red;
width: 50px;
height: 50px;
animation: heartbeat 1s infinite;
}
<div>
Heart
</div>
Edit:
Working example with pure CSS heart shape:
https://jsfiddle.net/qLfg2mrd/
#keyframes heartbeat
{
0%
{
transform: scale( .75);
}
20%
{
transform: scale( 1);
}
40%
{
transform: scale( .75);
}
60%
{
transform: scale( 1);
}
80% {
transform: scale( .75);
}
100%
{
transform: scale( .75);
}
}
#heart
{
position: relative;
width: 100px;
height: 90px;
animation: heartbeat 1s infinite;
}
#heart:before,
#heart:after
{
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
#heart:after
{
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
<div id="heart"></div>
Pulse 2 times, take a small break, and then repeat it again
Try this. Going with animation opacity is a bad choice. transform: scale() will do the job.
.heart:before {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
font-family: 'icons';
font-size: 21px;
text-indent: 0;
font-variant: normal;
line-height: 21px;
}
.heart {
position: relative;
width: 500px;
overflow: inherit;
margin: 50px auto;
list-style: none;
-webkit-animation: animateHeart 2.5s infinite;
animation: animateHeart 2.5s infinite;
}
.heart:before,
.heart:after {
position: absolute;
content: '';
top: 0;
left: 50%;
width: 120px;
height: 200px;
background: red;
border-radius: 100px 100px 0 0;
-webkit-transform: rotate(-45deg) translateZ(0);
transform: rotate(-45deg) translateZ(0);
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.heart:after {
left: 26%;
-webkit-transform: rotate(45deg) translateZ(0);
transform: rotate(45deg) translateZ(0);
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
#-webkit-keyframes animateHeart {
0% {
-webkit-transform: scale(0.8);
}
5% {
-webkit-transform: scale(0.9);
}
10% {
-webkit-transform: scale(0.8);
}
15% {
-webkit-transform: scale(1);
}
50% {
-webkit-transform: scale(0.8);
}
100% {
-webkit-transform: scale(0.8);
}
}
#keyframes animateHeart {
0% {
transform: scale(0.8);
}
5% {
transform: scale(0.9);
}
10% {
transform: scale(0.8);
}
15% {
transform: scale(1);
}
50% {
transform: scale(0.8);
}
100% {
transform: scale(0.8);
}
}
span {
font-family: 'Cantora One', sans-serif;
font-size: 64px;
position: absolute;
top: 165px;
}
<div class="heart">
</div>
I like ketan's answer, but I wanted to improve the heart animation to make it more realistic.
A heart does not double in size when it beats. 10% change in size looks better to me.
I like it getting both larger and smaller
When it stops moving altogether it looks dead to me. Even when it isn't beating, it needs to expand or contract a little
I removed the "alternate directions" code so that it runs the same way through every time
I explicitly have the heart start end and at normal scale (1) and have the animation in the middle of the sequence. It seems clearer that way to me.
#heart img{
position:absolute;
left:0;
right:0;
margin:0 auto;
}
#keyframes heartFadeInOut {
0% {transform: scale(1);}
25% {transform: scale(.97);}
35% {transform: scale(.9);}
45% {transform: scale(1.1);}
55% {transform: scale(.9);}
65% {transform: scale(1.1);}
75% {transform: scale(1.03);}
100% {transform: scale(1);}
}
#heart img.bottom {
animation-name: heartFadeInOut;
animation-iteration-count: infinite;
animation-duration: 2s;
}
<div id="heart" >
<img class="bottom" src="https://i.stack.imgur.com/iBCpb.png" width="100px">
</div>
Based on various comments and making use of the ♥ we'll get this:
body {
font-size: 40pt;
color: red;
}
#keyframes heartbeat {
0% {
font-size: .75em;
}
20% {
font-size: 1em;
}
40% {
font-size: .75em;
}
60% {
font-size: 1em;
}
80% {
font-size: .75em;
}
100% {
font-size: .75em;
}
}
div {
animation: heartbeat 1s infinite;
}
<div>
♥
</div>
body{
margin: 0;
padding: 0;
background: #1f1f1f;
}
body:before
{
position: absolute;
content: '';
left: 50%;
width: 50%;
height: 100%;
background: rgba(0,0,0,.2);
}
.center
{
position: absolute;
top:50%;
left: 50%;
background: #1f1f1f;
transform: translate(-50%,-50%);
padding: 100px;
border: 5px solid white;
border-radius: 100%;
box-shadow:20px 20px 45px rgba(0,0,0,.4);
z-index: 1;
overflow: hidden;
}
.heart
{
position: relative;
width: 100px;
height: 100px;
background:#ff0036;
transform: rotate(45deg) translate(10px,10px);
animation: ani 1s linear infinite;
}
.heart:before
{
content: '';
width: 100%;
height: 100%;
background: #ff0036;
position: absolute;
top:-50%;
left:0;
border-radius: 50%;
}
.heart:after
{
content:'';
width: 100%;
height: 100%;
background: #ff0036;
position: absolute;
bottom:0;
right:50%;
border-radius: 50%;
}
.center:before
{
content: '';
position: absolute;
top:0;
left:-50%;
width: 100%;
height: 100%;
background: rgba(0,0,0,.3);
}
#keyframes ani{
0%{
transform: rotate(45deg) translate(10px,10px) scale(1);
}
25%{
transform: rotate(45deg) translate(10px,10px) scale(1);
}
30%{
transform: rotate(45deg) translate(10px,10px) scale(1.4);
}
50%{
transform: rotate(45deg) translate(10px,10px) scale(1.2);
}
70%{
transform: rotate(45deg) translate(10px,10px) scale(1.4);
}
90%{
transform: rotate(45deg) translate(10px,10px) scale(1);
}
100%{
transform: rotate(45deg) translate(10px,10px) scale(1);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HeartBeat Animation</title>
<link rel="stylesheet" href="Style.css" type="text/css">
</head>
<body>
<div class="center">
<div class="heart">
</div>
</div>
</body>
</html>
Output
for more: Heart Beating Animation
I think this is what you want for your image animation. There is no need of top image. Just use bottom.
#button{
width:450px;
height:450px;
position:relative;
top:48px;
margin:0 auto;
text-align:center;
}
#heart img{
position:absolute;
left:0;
right:0;
margin:0 auto;
}
#keyframes heartFadeInOut {
0%
{ transform: scale( .5 ); }
20%
{ transform: scale( 1 ); }
40%
{ transform: scale( .5 ); }
60%
{ transform: scale( 1 ); }
80%
{ transform: scale( .5 ); }
100%
{ transform: scale( .5 ); }
}
#heart img.bottom {
animation-name: heartFadeInOut;
animation-iteration-count: infinite;
animation-duration: 1.5s;
animation-direction: alternate;
}
<div id="heart" >
<img class="bottom" src="https://goo.gl/nN8Haf" width="100px">
</div>
I needed this for a project I was working on. I was trying to make it look as realistic as possible, and this is what I came up with.
#keyframes heartbeat {
0% {
transform: scale( .95 );
}
20% {
transform: scale( .97 );
}
30% {
transform: scale( .95 );
}
40% {
transform: scale( 1 );
}
100% {
transform: scale( .95 );
}
}
animation: heartbeat 1s infinite;
I have this CSS3 animation working on codepen.
HTML
<div class="heart heart1"></div>
<div class="heart heart2"></div>
CSS3
html, body{
width: 100%;
height: 100%;
min-width: 500px;
min-height: 500px;
overflow: hidden;
}
.heart {
position: absolute;
width: 100px;
height: 90px;
top: 50%;
left: 50%;
margin-top: -45px;
margin-left: -50px;
}
.heart:before,
.heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: #fc2e5a;
border-radius: 50px 50px 0 0;
transform: rotate(-45deg);
transform-origin: 0 100%;
}
.heart:after {
left: 0;
transform: rotate(45deg);
transform-origin :100% 100%;
}
.heart1{
animation: heart-anim 1s linear .4s infinite;
}
.heart2{
animation: pounding .5s linear infinite alternate;
}
.heart1:after, .heart1:before{
background-color: #ff7693;
}
#keyframes pounding{
0%{ transform: scale(1.5); }
100%{ transform: scale(1); }
}
#keyframes heart-anim {
46% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
52% {
transform: scale(1.5);
}
55% {
transform: scale(3);
}
100% {
opacity: 0;
transform: scale(50);
}
}
Check it here: http://codepen.io/RadValentin/pen/sfnCE
As you can see is working ok, BUT, if I post the exact code to my local server OR to jsfiddle it does not work any more: http://jsfiddle.net/40aydbfr/
I believe the animation is not made according to the best practices since it breaks very easily.
So, Why it does not work outside of codepen and how can I make it more cross browser compatible.
PS: Im using Chrome.
It doesn't work because you are missing vendor prefixes for -webkit- browsers.
The reason why it works on codepen is because, if you click on the settings button above the CSS window, you'll see that -prefix-free is enabled, which means it adds the prefixes automatically.
Always check browser support, if something doesn't work.
Updated Codepen
Updated Fiddle
html,
body {
width: 100%;
height: 100%;
min-width: 500px;
min-height: 500px;
overflow: hidden;
}
.heart {
position: absolute;
width: 100px;
height: 90px;
top: 50%;
left: 50%;
margin-top: -45px;
margin-left: -50px;
}
.heart:before,
.heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: #fc2e5a;
border-radius: 50px 50px 0 0;
transform: rotate(-45deg);
transform-origin: 0 100%;
}
.heart:after {
left: 0;
transform: rotate(45deg);
transform-origin: 100% 100%;
}
.heart1 {
-webkit-animation: heart-anim 1s linear .4s infinite;
animation: heart-anim 1s linear .4s infinite;
}
.heart2 {
-webkit-animation: pounding .5s linear infinite alternate;
animation: pounding .5s linear infinite alternate;
}
.heart1:after,
.heart1:before {
background-color: #ff7693;
}
#-webkit-keyframes pounding {
0% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
#keyframes pounding {
0% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
#-webkit-keyframes heart-anim {
46% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
52% {
transform: scale(1.5);
}
55% {
transform: scale(3);
}
100% {
opacity: 0;
transform: scale(50);
}
}
#keyframes heart-anim {
46% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
52% {
transform: scale(1.5);
}
55% {
transform: scale(3);
}
100% {
opacity: 0;
transform: scale(50);
}
}
<div class="heart heart1"></div>
<div class="heart heart2"></div>
I've been struggling with this for the past few days, so help would be greatly appreciated. I have a Title with a line (hr element) right below it. I'm trying to have a div centered in the hr that grows and shrinks. However, when the css3 animation is applied it causes the div to be displaced down and to the right, as if the div's top-left point (which I think is (0,0)) is set to be where the middle was.
I've created a jsfiddle to illustrate what I mean.
Here's my html:
<div id="header">
<h1>Center</h1>
<div id="action-bar">
<hr class="center-line" />
<div class="circle animation"></div>
</div>
</div>
and my css:
div#header {
color: #000;
width: 90%;
text-align: center;
position:absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
}
div#header h1 {
font-size: 50px;
font-weight: 300;
margin-top: 0px;
margin-bottom: 0px;
}
/* the line beneath h1 */
div #action-bar {
margin: 25px 0;
position: relative;
}
div.circle {
width: 1em;
height: 1em;
background: #000;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
div.circle:hover {
width: 2em;
height: 2em;
background: #000;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
hr.center-line {
border: 0;
height: .25em;
background: #000;
}
/* animation */
#keyframes pulse {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(90deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes pulse {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(90deg);
}
100% {
transform: rotate(180deg);
}
}
.animation {
animation: pulse 2s ease-in-out 0s infinite normal none;
-webkit-animation: pulse 2s ease-in-out 0s infinite normal none;
-webkit-backface-visibility: hidden;
}
Can anybody point be in the right direction? I'm looking for a pure-css solution if possible. Thanks!
Add negative margin to your circle element, half of it's width and height:
div.circle {
width: 1em;
height: 1em;
background: #000;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
margin-left: -0.5em;
margin-top: -0.5em;
}
div.circle:hover {
width: 2em;
height: 2em;
margin-left: -1em;
margin-top: -1em;
}
jsFiddle Demo.
Here is a smooth pulsing option.
http://jsfiddle.net/aLjsut5r/4/
/* animation */
#keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
#-webkit-keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
.animation {
animation: pulse 2s ease-in-out 0s infinite normal none;
-webkit-animation: pulse 2s ease-in-out 0s infinite normal none;
-webkit-backface-visibility: hidden;
}
.pulsing {
border: 3px solid #999;
-webkit-border-radius: 30px;
height: 18px;
width: 18px;
position: absolute;
left:20px;
top:214px;
-webkit-animation: pulsate 1s ease-out;
-webkit-animation-iteration-count: infinite;
opacity: 0.0;
}
#-webkit-keyframes pulsate {
0% {-webkit-transform: scale(0.5, 0.5); opacity: 0.5;}
50% {opacity: 1.0;}
100% {-webkit-transform: scale(1.2, 1.2); opacity: 0.5;}
}