<button class="heart">
<div class="heart-flip"></div>
</button>
<button class="heart-button">
<div class="heart-flip"></div>
<span>Like<span>d</span></span>
</button>
<!-- dribbble - twitter -->
<a class="dribbble" href="https://dribbble.com/ai" target="_blank"><img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg" alt=""></a>
<a class="twitter" target="_blank" href="https://twitter.com/aaroniker_me"><svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72"><path d="M67.812 16.141a26.246 26.246 0 0 1-7.519 2.06 13.134 13.134 0 0 0 5.756-7.244 26.127 26.127 0 0 1-8.313 3.176A13.075 13.075 0 0 0 48.182 10c-7.229 0-13.092 5.861-13.092 13.093 0 1.026.118 2.021.338 2.981-10.885-.548-20.528-5.757-26.987-13.679a13.048 13.048 0 0 0-1.771 6.581c0 4.542 2.312 8.551 5.824 10.898a13.048 13.048 0 0 1-5.93-1.638c-.002.055-.002.11-.002.162 0 6.345 4.513 11.638 10.504 12.84a13.177 13.177 0 0 1-3.449.457c-.846 0-1.667-.078-2.465-.231 1.667 5.2 6.499 8.986 12.23 9.09a26.276 26.276 0 0 1-16.26 5.606A26.21 26.21 0 0 1 4 55.976a37.036 37.036 0 0 0 20.067 5.882c24.083 0 37.251-19.949 37.251-37.249 0-.566-.014-1.134-.039-1.694a26.597 26.597 0 0 0 6.533-6.774z"></path></svg></a>
.heart,
.heart-button {
cursor: pointer;
outline: none;
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
.heart-flip {
--base: 32px;
--duration: .6s;
--active: #ea4673;
--inactive: #d1d6ee;
width: var(--base);
height: calc(var(--base) + var(--base) / 2);
border-radius: calc(var(--base) / 2) calc(var(--base) / 2) 0 0;
position: relative;
transform-origin: 50% 66.66%;
transform-style: preserve-3d;
transform: rotate(var(--rotate, -45deg));
transition: background var(--duration), transform var(--duration) ease;
background: var(--heart-background, var(--inactive));
&:before,
&:after {
content: '';
width: calc(var(--base) / 2);
height: var(--base);
border-radius: var(--pseudo-border-radius, calc(var(--base) / 2) 0 0 calc(var(--base) / 2));
position: absolute;
left: var(--pseudo-left, -50%);
transform-origin: var(--pseudo-origin, 100%) 50%;
bottom: 0;
background: var(--heart-background, var(--inactive));
filter: brightness(var(--pseudo-filter, 50%));
transform: translateX(1%) rotateY(var(--pseudo-rotate, 90deg)) translateZ(0);
transition: background var(--duration), transform var(--duration) ease, filter var(--duration);
}
&:after {
--pseudo-border-radius: 0 calc(var(--base) / 2) calc(var(--base) / 2) 0;
--pseudo-left: 100%;
--pseudo-origin: 0;
filter: brightness(var(--pseudo-filter-second, 100%));
transform: translateX(-1%) rotateY(var(--pseudo-rotate-second, 0deg)) translateZ(0);
}
}
&.active {
.heart-flip {
--rotate: 45deg;
--pseudo-filter: 100%;
--pseudo-filter-second: 50%;
--pseudo-rotate: 0deg;
--pseudo-rotate-second: 90deg;
--heart-background: var(--active);
}
}
}
.heart {
background: none;
border: none;
padding: 0;
transform: scale(var(--button-scale, 1)) translateZ(0);
transition: transform .2s;
&:active {
--button-scale: .95;
}
}
.heart-button {
--duration: .4s;
--color: #404660;
--color-hover: #2b3044;
--color-active: #fff;
--border: #d1d6ee;
--border-hover: #bbc1e1;
--border-active: #ea4673;
--background: #fff;
--background-active: #ea4673;
font-family: inherit;
font-size: 14px;
line-height: 1.6;
font-weight: 600;
padding: 6px 16px;
border-radius: 7px;
color: var(--button-color, var(--color));
border: 1px solid var(--button-border, var(--border));
background: var(--button-background, var(--background));
transform: scale(var(--button-scale, 1)) translateZ(0);
transition: background var(--duration), border-color var(--duration), color var(--duration), transform .2s;
.heart-flip {
--base: 8px;
--active: #fff;
--inactive: #bbc1e1;
display: inline-block;
vertical-align: top;
margin: 4px 6px 0 0;
}
span {
display: inline-block;
vertical-align: top;
}
& > span {
transform: translateX(var(--text-x, 4px));
transition: transform var(--duration);
span {
display: inline-block;
vertical-align: top;
opacity: var(--span-opacity, 0);
transform: translateX(var(--span-x, 4px));
transition: opacity var(--duration), transform var(--duration);
}
}
&:active {
--button-scale: .95;
}
&:hover {
--button-color: var(--color-hover);
--button-border: var(--border-hover);
}
&.active {
--text-x: 0;
--button-color: var(--color-active);
--button-border: var(--border-active);
--button-background: var(--background-active);
--span-opacity: 1;
--span-x: 0;
}
}
html {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: inherit;
&:before,
&:after {
box-sizing: inherit;
}
}
// Center & dribbble
body {
font-family: 'Inter', Arial;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: #F6F8FF;
.heart-button {
margin-top: 40px;
}
.dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
img {
display: block;
height: 28px;
}
}
.twitter {
position: fixed;
display: block;
right: 64px;
bottom: 14px;
svg {
width: 32px;
height: 32px;
fill: #1da1f2;
}
}
}
View Compiled
document.querySelectorAll('.heart, .heart-button').forEach(button => button.addEventListener('click', e => button.classList.toggle('active')));
This Pen doesn't use any external JavaScript resources.