<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();
});
*/

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap-reboot.css

External JavaScript

This Pen doesn't use any external JavaScript resources.