Last active
April 25, 2021 00:46
-
-
Save tks18/3c3e332527851d0d0b46230a5cc81bd8 to your computer and use it in GitHub Desktop.
Pure CSS Heart Animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title> Pure CSS Heart Animation </title> | |
<style> | |
body { | |
display: flex; | |
justify-content: center; | |
margin: 0; | |
height: 100vh; | |
background: linear-gradient(135deg, #121721, #000); | |
font: 1em verdana, sans-serif; | |
} | |
.animation-head { | |
position: absolute; | |
left: -100vw; | |
} | |
.animation-head:checked + label { | |
color: #e2264d; | |
filter: none; | |
will-change: font-size; | |
-webkit-animation: heart 1s cubic-bezier(0.17, 0.89, 0.32, 1.49); | |
animation: heart 1s cubic-bezier(0.17, 0.89, 0.32, 1.49); | |
} | |
.animation-head:checked + label:before, .animation-head:checked + label:after { | |
-webkit-animation: inherit; | |
animation: inherit; | |
-webkit-animation-timing-function: ease-out; | |
animation-timing-function: ease-out; | |
} | |
.animation-head:checked + label:before { | |
will-change: transform, border-width, border-color; | |
-webkit-animation-name: bubble; | |
animation-name: bubble; | |
} | |
.animation-head:checked + label:after { | |
will-change: opacity, box-shadow; | |
-webkit-animation-name: sparkles; | |
animation-name: sparkles; | |
} | |
.animation-head:focus + label { | |
text-shadow: 0 0 3px white, 0 1px 1px white, 0 -1px 1px white, 1px 0 1px white, -1px 0 1px white; | |
} | |
.toggle-animation { | |
align-self: center; | |
position: relative; | |
color: #888; | |
font-size: 2em; | |
filter: grayscale(1); | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
cursor: pointer; | |
} | |
.toggle-animation:before, .toggle-animation:after { | |
position: absolute; | |
z-index: -1; | |
top: 50%; | |
left: 50%; | |
border-radius: 50%; | |
content: ''; | |
} | |
.toggle-animation:before { | |
box-sizing: border-box; | |
margin: -2.25rem; | |
border: solid 2.25rem #e2264d; | |
width: 4.5rem; | |
height: 4.5rem; | |
transform: scale(0); | |
} | |
.toggle-animation:after { | |
margin: -0.1875rem; | |
width: 0.375rem; | |
height: 0.375rem; | |
box-shadow: 0.32476rem -3rem 0 -0.1875rem #ff8080, -0.32476rem -2.625rem 0 -0.1875rem #ffed80, 2.54798rem -1.61656rem 0 -0.1875rem #ffed80, 1.84982rem -1.89057rem 0 -0.1875rem #a4ff80, 2.85252rem 0.98418rem 0 -0.1875rem #a4ff80, 2.63145rem 0.2675rem 0 -0.1875rem #80ffc8, 1.00905rem 2.84381rem 0 -0.1875rem #80ffc8, 1.43154rem 2.22414rem 0 -0.1875rem #80c8ff, -1.59425rem 2.562rem 0 -0.1875rem #80c8ff, -0.84635rem 2.50595rem 0 -0.1875rem #a480ff, -2.99705rem 0.35095rem 0 -0.1875rem #a480ff, -2.48692rem 0.90073rem 0 -0.1875rem #ff80ed, -2.14301rem -2.12438rem 0 -0.1875rem #ff80ed, -2.25479rem -1.38275rem 0 -0.1875rem #ff8080; | |
} | |
@-webkit-keyframes heart { | |
0%, 17.5% { | |
font-size: 0; | |
} | |
} | |
@keyframes heart { | |
0%, 17.5% { | |
font-size: 0; | |
} | |
} | |
@-webkit-keyframes bubble { | |
15% { | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 2.25rem; | |
} | |
30%, 100% { | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 0; | |
} | |
} | |
@keyframes bubble { | |
15% { | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 2.25rem; | |
} | |
30%, 100% { | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 0; | |
} | |
} | |
@-webkit-keyframes sparkles { | |
0%, 20% { | |
opacity: 0; | |
} | |
25% { | |
opacity: 1; | |
box-shadow: 0.32476rem -2.4375rem 0 0rem #ff8080, -0.32476rem -2.0625rem 0 0rem #ffed80, 2.1082rem -1.26585rem 0 0rem #ffed80, 1.41004rem -1.53985rem 0 0rem #a4ff80, 2.30412rem 0.85901rem 0 0rem #a4ff80, 2.08305rem 0.14233rem 0 0rem #80ffc8, 0.76499rem 2.33702rem 0 0rem #80ffc8, 1.18748rem 1.71734rem 0 0rem #80c8ff, -1.35019rem 2.0552rem 0 0rem #80c8ff, -0.60229rem 1.99916rem 0 0rem #a480ff, -2.44865rem 0.22578rem 0 0rem #a480ff, -1.93852rem 0.77557rem 0 0rem #ff80ed, -1.70323rem -1.77366rem 0 0rem #ff80ed, -1.81501rem -1.03204rem 0 0rem #ff8080; | |
} | |
} | |
@keyframes sparkles { | |
0%, 20% { | |
opacity: 0; | |
} | |
25% { | |
opacity: 1; | |
box-shadow: 0.32476rem -2.4375rem 0 0rem #ff8080, -0.32476rem -2.0625rem 0 0rem #ffed80, 2.1082rem -1.26585rem 0 0rem #ffed80, 1.41004rem -1.53985rem 0 0rem #a4ff80, 2.30412rem 0.85901rem 0 0rem #a4ff80, 2.08305rem 0.14233rem 0 0rem #80ffc8, 0.76499rem 2.33702rem 0 0rem #80ffc8, 1.18748rem 1.71734rem 0 0rem #80c8ff, -1.35019rem 2.0552rem 0 0rem #80c8ff, -0.60229rem 1.99916rem 0 0rem #a480ff, -2.44865rem 0.22578rem 0 0rem #a480ff, -1.93852rem 0.77557rem 0 0rem #ff80ed, -1.70323rem -1.77366rem 0 0rem #ff80ed, -1.81501rem -1.03204rem 0 0rem #ff8080; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<input class="animation-head" id="toggle-heart" type="checkbox"/> | |
<label class="toggle-animation" for="toggle-heart" aria-label="like">😍</label> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @import compass; | |
$bubble-d: 4.5rem; // bubble diameter | |
$bubble-r: .5*$bubble-d; // bubble-radius | |
$sparkle-d: .375rem; | |
$sparkle-r: .5*$sparkle-d; | |
@mixin sparkles($k) { | |
$shadow-list: (); | |
$n-groups: 7; | |
$group-base-angle: 360deg/$n-groups; | |
$group-distr-r: (1 + $k*.25)*$bubble-r; | |
$n-sparkles: 2; | |
$sparkle-base-angle: 360deg/$n-sparkles; | |
$sparkle-off-angle: 60deg; // offset angle from radius | |
$spread-r: -$k*$sparkle-r; | |
@for $i from 0 to $n-groups { | |
$group-curr-angle: $i*$group-base-angle - 90deg; | |
$xg: $group-distr-r*cos($group-curr-angle); | |
$yg: $group-distr-r*sin($group-curr-angle); | |
@for $j from 0 to $n-sparkles { | |
$sparkle-curr-angle: $group-curr-angle + | |
$sparkle-off-angle + $j*$sparkle-base-angle; | |
$xs: $xg + $sparkle-d*cos($sparkle-curr-angle); | |
$ys: $yg + $sparkle-d*sin($sparkle-curr-angle); | |
$shadow-list: $shadow-list, $xs $ys 0 $spread-r | |
hsl(($i + $j)*$group-base-angle, 100%, 75%); | |
} | |
} | |
box-shadow: $shadow-list; | |
} | |
@mixin bubble($ext) { | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: $ext; | |
} | |
body { | |
display: flex; | |
justify-content: center; | |
margin: 0; | |
height: 100vh; | |
background: linear-gradient(135deg, | |
#121721, #000); | |
font: 1em verdana, sans-serif; | |
} | |
.animation-head { | |
position: absolute; | |
left: -100vw; | |
&:checked + label { | |
color: #e2264d; | |
filter: none; | |
will-change: font-size; | |
animation: heart 1s cubic-bezier(.17, .89, .32, 1.49); | |
&:before, &:after { | |
animation: inherit; | |
animation-timing-function: ease-out; | |
} | |
&:before { | |
will-change: transform, border-width, border-color; | |
animation-name: bubble; | |
} | |
&:after { | |
will-change: opacity, box-shadow; | |
animation-name: sparkles; | |
} | |
} | |
&:focus + label { | |
text-shadow: 0 0 3px white, | |
0 1px 1px white, 0 -1px 1px white, | |
1px 0 1px white, -1px 0 1px white; | |
} | |
} | |
.toggle-animation { | |
align-self: center; | |
position: relative; | |
color: #888; | |
font-size: 2em; | |
filter: grayscale(1); | |
user-select: none; | |
cursor: pointer; | |
&:before, &:after { | |
position: absolute; | |
z-index: -1; | |
top: 50%; left: 50%; | |
border-radius: 50%; | |
content: ''; | |
} | |
&:before { | |
box-sizing: border-box; | |
margin: -$bubble-r; | |
border: solid $bubble-r #e2264d; | |
width: $bubble-d; height: $bubble-d; | |
transform: scale(0); | |
} | |
&:after { | |
margin: -$sparkle-r; | |
width: $sparkle-d; height: $sparkle-d; | |
@include sparkles(1); | |
} | |
} | |
@keyframes heart { | |
0%, 17.5% { font-size: 0; } | |
} | |
@keyframes bubble { | |
15% { @include bubble($bubble-r); } | |
30%, 100% { @include bubble(0); } | |
} | |
@keyframes sparkles { | |
0%, 20% { opacity: 0; } | |
25% { | |
opacity: 1; | |
@include sparkles(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment