
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 use it:
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 {
}
});
});






