<main>
<h1 class="heading">Click to turn
<span class="on">
<span>
on
</span>
</span>
<span class="off">
<span>
off
</span>
</span>
</h1>
<button type="button" class="btn">
<span>
<b></b>
<svg viewBox="-5.5 -5.5 71 71" id="circle">
<circle cx="30" cy="30" r="30" stroke="white" stroke-width="11" fill="transparent"></circle>
</svg>
</span>
</button>
</main>
<aside>
<a href="https://dribbble.com/shots/4762832-Microinteraction-Exploration-003" target="_blank" rel="noopener">
<svg class="dribbble-logo" xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0 0 256 256" preserveAspectRatio="xMidYMid"><path d="M128 8.5c66 0 119.4 53.4 119.4 119.3S194 247.2 128 247.2 8.6 193.8 8.6 127.9 62 8.5 128 8.5z" fill="#E74D89"/><path d="M128 255.7c-70.6 0-128-57.3-128-127.8C0 57.3 57.4 0 128 0s128 57.3 128 127.8-57.4 127.9-128 127.9zm107.9-110.4c-3.7-1.2-33.8-10.1-68.1-4.7 14.3 39.2 20.1 71.2 21.2 77.8 24.6-16.5 42.1-42.7 46.9-73.1zm-65.2 83.2c-1.6-9.6-8-43-23.3-82.8-.2.1-.5.2-.7.2-61.7 21.5-83.8 64.2-85.8 68.2 18.5 14.4 41.8 23 67.1 23 15.1.1 29.6-3 42.7-8.6zM46.8 201c2.5-4.2 32.5-53.8 88.9-72.1 1.4-.5 2.9-.9 4.3-1.3-2.7-6.2-5.7-12.4-8.9-18.5-54.6 16.3-107.6 15.6-112.4 15.5 0 1.1-.1 2.2-.1 3.3.1 28.1 10.7 53.7 28.2 73.1zM21 105.6c4.9.1 49.9.3 101.1-13.3C104 60.1 84.4 33.1 81.6 29.2 50.9 43.6 28.1 71.8 21 105.6zm81.4-83.8c3 4 22.9 31 40.8 63.9 38.9-14.6 55.3-36.6 57.3-39.4-19.3-17.1-44.7-27.5-72.5-27.5-8.8 0-17.4 1.1-25.6 3zm110.2 37.1c-2.3 3.1-20.6 26.6-61 43.1 2.5 5.2 5 10.5 7.3 15.8.8 1.9 1.6 3.8 2.4 5.6 36.4-4.6 72.5 2.8 76.1 3.5-.3-25.7-9.5-49.4-24.8-68z" fill="#B2215A"/></svg>
Dribbble inspiration
</a>
</aside>
@import url('https://fonts.googleapis.com/css?family=Pacifico|Roboto:300,700');
:root {
--timing: cubic-bezier(.645,.045,.355,1);
--primary: #f4f7f5;
}
html,
body {
height: 100%;
background-color: var(--primary);
}
body {
display: grid;
place-items: center;
background:
radial-gradient(#fff 30%, rgba(255,255,255,0) 70%),
radial-gradient(var(--primary) 10%, rgba(244, 247, 245,0) 20%);
background-size: 100% 100%, 10px 10px;
background-position: 0 0;
}
/*@media (max-width: 420px) {
body {
background: var(--primary);
}
}*/
main {
display: grid;
place-items: center;
gap: 1em 0;
}
/* Heading effect */
.heading {
font-family: 'Roboto', sans-serif;
font-weight: 300;
display: grid;
grid: auto / auto auto;
}
.heading > span {
margin-left: 0.25em;
font-weight: 700;
}
.heading span {
overflow: hidden;
display: inline-flex;
transition: .6s;
}
.heading > span,
.heading > span.on span {
transform: translateY(100%);
grid-area: 1 / 2;
}
.heading > span span,
.heading > span.on {
transform: translateY(-100%);
}
.heading.active span.off,
.heading.active span.off span,
.heading:not(.active) span.on,
.heading:not(.active) span.on span {
transform: none;
}
button {
--w: 6em;
--bg: rgb(var(--rgb));
--bga: rgba(var(--rgb), .4); /* Safari fix */
-webkit-appearance: none;
border: none;
font-size: 100%;
width: var(--w);
height: var(--w);
background: var(--bg);
box-shadow: 0 3px 12px 2px var(--bga);
border-radius: 50%;
position: relative;
overflow: hidden;
cursor: pointer;
transition: .1s transform, .3s box-shadow;
will-change: transform, box-shadow;
backface-visibility: hidden;
}
button > * {
pointer-events: none;
}
button:focus {
outline: none;
}
button:active {
transform: scale(.97);
}
button:after {
--bg: rgb(var(--rgb));
content: '';
position: absolute;
top: -15%;
left: -15%;
width: 200%;
height: 200%;
background: var(--bg);
border-radius: inherit;
transform: translate(5%, 5%) scale(.03);
pointer-events: none;
}
button.animating:after {
animation: c .5s cubic-bezier(.5, 0, .5, 1) backwards;
}
button.active,
button:not(.active):after {
--rgb: 64, 227, 120;
}
button:not(.active),
button.active:after {
--rgb: 229, 55, 94;
}
@keyframes c {
to {
transform: none;
}
}
button span {
display: inline-block;
position: relative;
margin-top: 5px;
}
button b {
--w: 7px;
overflow: hidden;
border-radius: var(--w);
display: grid;
width: var(--w);
height: 35px;
top: 0;
left: 50%;
position: absolute;
transform: translateX(-50%);
z-index: 3;
will-change: transform;
}
button b:before {
content: '';
background: #fff;
width: 100%;
height: 100%;
border-radius: var(--w);
transform: translateY(-15px);
transition-timing-function: var(--timing);
transition: .5s;
}
button.active b:before {
transform: translateY(12px);
transition-delay: .27s;
transition-timing-function: cubic-bezier(.25, .25, .25, 1.25);
}
button svg {
--dash: 190;
stroke-linecap: round;
stroke-dasharray: var(--dash);
stroke-dashoffset: var(--dash);
width: 46px;
height: 46px;
transform: scaleX(-1) rotate(-89deg);
transition: .4s;
transition-timing-function: var(--timing);
margin: auto;
position: relative;
z-index: 1;
will-change: transform, stroke-dashoffset;
}
button:not(.active) svg {
stroke-dashoffset: 40;
transform: scaleX(-1) rotate(-52deg);
transition: .5s .25s;
}
aside {
position: absolute;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
text-align: center;
width: 100%;
padding: 0 2em 2em;
font-family: 'Pacifico', cursive;
}
aside a {
text-decoration: underline;
color: #E65289;
display: flex;
align-items: center;
}
aside a:hover,
aside a:focus {
color: #000;
text-decoration: none;
}
.dribbble-logo {
width: 18px;
height: 18px;
margin-right: 5px;
}
const btn = document.querySelector('.btn');
const heading = document.querySelector('.heading');
let active = false;
const turnOn = () => {
btn.classList.add('active');
heading.classList.add('active');
}
const turnOff = () => {
btn.classList.remove('active');
heading.classList.remove('active');
}
const toggleAnimation = () => {
btn.classList.remove('animating');
active ? turnOn() : turnOff();
};
function clickHandler() {
active = !active;
btn.classList.add('animating');
btn.addEventListener('animationend', toggleAnimation);
}
btn.addEventListener('click', clickHandler);
/*btn.addEventListener('animationend', () => {
btn.classList.remove('animating');
if (active === true) {
btn.classList.add('active');
heading.classList.add('active');
} else {
btn.classList.remove('active');
heading.classList.remove('active');
}
});
btn.addEventListener('animationend', () => {
btn.classList.remove('animating');
active ? turnOn() : turnOff();
});
*/
This Pen doesn't use any external JavaScript resources.