Tutorial: Fancy Submit Button Interactions

Tutorial: Fancy Submit Button Interactions

Description

Fancy Submit Button Interactions that displays a loading spinner (w/ or w/o progress bar) in the submit button when submitting and shows a success message when a specific process is completely finished.

How To

Create submit buttons.


<div class="submit-buttons">
  <div class="submit-buttons__block">
    <h4 class="submit-buttons__title">Submit 1</h4>
      <div class="submit-buttons__content">
        <button class="submit-button submit-button--1" type="submit" title="Submit">
          <span class="submit-button__pending submit-button__pending--1"></span>
          <span class="submit-button__text submit-button__text--1">Submit</span>
          <span class="submit-button__loaded submit-button__loaded--1"> <span>Success!</span></span>
        </button>
      </div>
  </div>

  <div class="submit-buttons__block">
    <h4 class="submit-buttons__title">Submit 2</h4>
    <div class="submit-buttons__content">
      <button class="submit-button submit-button--2" type="submit" title="Submit">
        <span class="submit-button__pending submit-button__pending--2"><span class="submit-button__pending-loader--2"></span></span>
        <span class="submit-button__text submit-button__text--2">Submit</span>
        <span class="submit-button__loaded submit-button__loaded--2"></span>
      </button>
    </div>
  </div>
</div>

The primary CSS/CSS3 rules.

.submit-buttons {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

.submit-buttons__block {
  margin-bottom: 40px;
}

.submit-buttons__title {
  margin-bottom: 20px;
  text-align: center;
}

.submit-button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 200px;
  height: 54px;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 1.44px;
  box-shadow: 0px 16px 35px 0 rgba(0, 0, 0, 0.25);
  outline: none;
  border: none;
  overflow: hidden;
  cursor: pointer;
}

.submit-button__pending,
.submit-button__loaded {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: inherit;
  opacity: 0;
  visibility: hidden;
}

.submit-button--3 {
  background-image: linear-gradient(to right bottom, #ff18ab 1%, #6e03ff);
}

.submit-button--1 {
  background-image: linear-gradient(to right bottom, #1affec 1%, #9f4ff9);
}

@keyframes pending-circle {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

.submit-button__pending--1 {
  display: block;
}

.submit-button__pending--1:before {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: "Font Awesome 5 Free";
  font-size: 1.6rem;
  content: '\f110';
}

.submit-button__pending--1:after {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: 4px;
  content: '';
  transform: scaleX(0);
  transform-origin: left center;
  background-image: linear-gradient(to right bottom, #ffce3a 1%, #ff0e69);
  background-size: 100%;
}

.submit-button__pending--1.js-active {
  transition-property: all;
  transition-duration: 0.1s;
  transition-timing-function: linear;
  transition-delay: 0.3s;
  opacity: 1;
  visibility: visible;
}

.submit-button__pending--1.js-active:before {
  animation: pending-circle 1s infinite;
}

.submit-button__pending--1.js-active:after {
  transition-property: all;
  transition-duration: 1.7s;
  transition-timing-function: cubic-bezier(0, 0, 0.97, 0.13);
  transition-delay: 0.1s;
  transform: scaleX(1);
}

.submit-button__text--1.js-active {
  transition-property: all;
  transition-duration: 0.3s;
  transition-timing-function: linear;
  transition-delay: 0s;
  opacity: 0;
  visibility: hidden;
}

.submit-button__loaded--1 {
  display: flex;
  align-items: center;
  justify-content: center;
}

.submit-button__loaded--1:before {
  margin-right: 10px;
  font-family: "Font Awesome 5 Free";
  font-size: 1.4rem;
  content: '\f00c';
  transform: translate(-10px, -2px);
}

.submit-button__loaded--1 span {
  transform: translateX(10px);
}

.submit-button__loaded--1.js-active {
  transition: opacity .1s linear 2.1s;
  opacity: 1;
  visibility: visible;
}

.submit-button__loaded--1.js-active:before {
  transition-property: all;
  transition-duration: 0.2s;
  transition-timing-function: linear;
  transition-delay: 2.15s;
  transform: translate(0, -2px);
}

.submit-button__loaded--1.js-active span {
  transition-property: all;
  transition-duration: 0.2s;
  transition-timing-function: linear;
  transition-delay: 2.15s;
  transform: translateX(0);
}

.submit-button--2 {
  background-image: linear-gradient(to right bottom, #ffce3a 1%, #ff0e69);
}

@keyframes pending-loader-circles {
  0% {
    opacity: .3;
  }
  100% {
    opacity: 1;
  }
}

@keyframes pending-loader-moving {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(50px);
  }
}

.submit-button__pending--2 {
  display: flex;
  align-items: center;
  justify-content: center;
}

.submit-button__pending--2:before, .submit-button__pending--2:after,
.submit-button__pending--2 span {
  position: relative;
  display: block;
  margin-right: 5px;
  width: 10px;
  height: 10px;
  background-color: #fff;
  border-radius: 50%;
  opacity: .3;
}

.submit-button__pending--2:before, .submit-button__pending--2:after {
  content: '';
}

.submit-button__pending--2:before {
  animation-delay: 0s;
}

.submit-button__pending--2 span {
  animation-delay: .4s;
}

.submit-button__pending--2:after {
  animation-delay: .8s;
}

.submit-button__pending--2.js-active {
  transition-property: all;
  transition-duration: 0.1s;
  transition-timing-function: linear;
  transition-delay: 0.3s;
  opacity: 1;
  visibility: visible;
}

.submit-button__pending--2.js-active:before {
  animation: pending-loader-circles .8s linear infinite alternate, pending-loader-moving .2s linear 2s 1 forwards;
}

.submit-button__pending--2.js-active span {
  animation: pending-loader-circles .8s linear .4s infinite alternate, pending-loader-moving .2s linear 2.1s 1 forwards;
}

.submit-button__pending--2.js-active:after {
  animation: pending-loader-circles .8s linear .8s infinite alternate, pending-loader-moving .2s linear 2.2s 1 forwards;
}

.submit-button__text--2.js-active {
  transition-property: all;
  transition-duration: 0.3s;
  transition-timing-function: linear;
  transition-delay: 0s;
  opacity: 0;
  visibility: hidden;
}

.submit-button__loaded--2 {
  display: flex;
  align-items: center;
  justify-content: center;
}

.submit-button__loaded--2:before {
  display: block;
  width: 30px;
  height: 30px;
  content: '';
  transform: rotate(0);
  border: 2px solid transparent;
  border-radius: 50%;
}

.submit-button__loaded--2:after {
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  font-family: "Font Awesome 5 Free";
  font-size: .9rem;
  content: '\f00c';
  transform: translate(-50%, -50%);
  opacity: 0;
}

.submit-button__loaded--2.js-active {
  transition-property: all;
  transition-duration: 0.1s;
  transition-timing-function: linear;
  transition-delay: 2.2s;
  opacity: 1;
  visibility: visible;
}

.submit-button__loaded--2.js-active:before {
  transition: transform .4s linear 2.3s, border-top-color .1s linear 2.3s, border-right-color .1s linear 2.4s, border-bottom-color .1s linear 2.5s, border-left-color .1s linear 2.6s;
  transform: rotate(360deg);
  border-color: #fff;
}

.submit-button__loaded--2.js-active:after {
  transition-property: all;
  transition-duration: 0.2s;
  transition-timing-function: linear;
  transition-delay: 0.6s;
  opacity: 1;
}

The main JavaScript to enable the submit interactions.

const DOM = {
  submitBtn: '.submit-button',
  submitPending: '.submit-button__pending',
  submitText: '.submit-button__text',
  submitLoaded: '.submit-button__loaded'
};

//find exact children of the button
const findChildren = elem => {
  
  return [
    elem.querySelector(DOM.submitPending),
    elem.querySelector(DOM.submitText),
    elem.querySelector(DOM.submitLoaded)
  ];
  
};

//find node parent function
const findParent = (elem, referenceElem) => {
  
  const className = referenceElem.slice(0, referenceElem.length);
  
  let ind = true;
  
  while (ind) {
  
    if(elem.classList.contains(className)) {
      break;
    } else {
      elem = elem.parentNode;
    }
    
  }
  
  return elem;
  
};

//onclick function for buttons - active state
document.querySelectorAll(DOM.submitBtn).forEach(elem => {
  
  elem.addEventListener('click', event => {
    
    let clickedElem = findParent(event.target, 'submit-button');
    
    const innerChildren = findChildren(clickedElem);
    
    //adding active class to the clicked elem
    if(! clickedElem.classList.contains('js-active')) {
      
      clickedElem.classList.add('js-active');
      
      innerChildren.forEach(elem => {
        elem.classList.add('js-active');
      });
      
    } else {
      
    }
    
  });
  
});

Author: nat-davydova

Demo: Codepen

Fancy you stumbling on my piece of the internet. Bonjour!

My name is Anmol and I'm the Blogger-In-Chief of this joint & working as the Chief Technology Officer at Azoora, Inc. I'm putting up my views here trying to help creative solopreneurs, developers & designers build their business using the power of websites, apps & social media, this, is, my jam.

If you're looking to start your own online business with a professional high quality website or mobile app, just get in touch. I'd be more than happy to assist.

SKYPE | FACEBOOK | LINKEDIN | TWITTER | EMAIL

Leave a Comment

Your email address will not be published. Required fields are marked *