Typeform Style Forms (Multi-step form on webpage)
Anyone that's used forms before has heard of Typeform.
They have an incredibly simple and high end design for their forms that we've replicated using the code below.
You need to create the form, setup where you want it to redirect to in the form builder (on submission), and then add the form to a webpage.
The code adds white chevrons to the Previous & Next Buttons on a multi-step form. I suggest you hide the cancel button (form builder, gear icon on the page).
VIDEO HERE
Put this code in Page Settings:
CSS:
.formio-component-radio .form-radio .form-check { margin-top: 10px !important;} .formio-component-radio .form-radio .form-check-label { width: 100%; border: 2px solid #117aeb; border-radius: 10px; padding: 8px !important; background: white;} .formio-component-radio .form-radio .form-check-label:hover { background: #ffffff90;} .formio-component-radio .form-radio .form-check-label .form-check-input { accent-color: black !important;} /* Common styles for both buttons */.btn-wizard-nav-previous,.btn-wizard-nav-next { font-size: 0px !important; /* Hide the text */ width: 60px !important; /* Set a width (adjust as needed) */ height: 60px !important; /* Set a height (adjust as needed) */ position: relative; /* For positioning the pseudo-element */ border: none; /* Remove default button borders */ background-color: transparent; /* Or set your desired background */ padding: 0; /* Remove default padding */ cursor: pointer; /* Show a pointer cursor on hover */} /* Styles for the left arrow (previous button) */.btn-wizard-nav-previous::before { content: ''; display: block; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23FFF'%3E%3Cpath d='M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z'/%3E%3C/svg%3E"); /* Left arrow SVG */ background-repeat: no-repeat; background-position: center; background-size: contain; color: white !important;} /* Styles for the right arrow (next button) */.btn-wizard-nav-next::before { content: ''; display: block; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23FFF'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E"); /* Right arrow SVG */ background-repeat: no-repeat; background-position: center; background-size: contain; color: white !important;} .btn-wizard-nav-submit { height: 60px !important;}
Page Settings > Custom Code > Body End
<script> // Minimal solution that won't interfere with form's internal logic(function() { // Add required CSS const styleElement = document.createElement('style'); styleElement.textContent = ` body { overflow-y: hidden !important;} @keyframes formFlyOut { from { transform: translateY(0); opacity: 1; } to { transform: translateY(-100vh); opacity: 0; } } @keyframes formFlyIn { from { transform: translateY(100vh); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .crmco-form-animate-out { animation: formFlyOut 0.4s ease-out forwards; } .crmco-form-animate-in { animation: formFlyIn 0.4s ease-out forwards; } `; document.head.appendChild(styleElement); // Variables to track state let isAnimating = false; let lastAnimationTime = 0; // Function to safely animate without disrupting form behavior function animateFormTransition() { // Prevent multiple animations from running simultaneously if (isAnimating) return; // Prevent animations from running too frequently const now = Date.now(); if (now - lastAnimationTime < 1000) return; lastAnimationTime = now; isAnimating = true; const form = document.querySelector('.crmco-form'); if (!form) { isAnimating = false; return; } // Add animation class form.classList.add('crmco-form-animate-out'); // When animation ends, add the fly-in animation setTimeout(() => { form.classList.remove('crmco-form-animate-out'); form.classList.add('crmco-form-animate-in'); // Reset after animation completes setTimeout(() => { form.classList.remove('crmco-form-animate-in'); isAnimating = false; }, 500); }, 400); // Match duration of animation } // Function to set up auto-advance for radio buttons function setupRadioAutoAdvance() { document.addEventListener('change', function(e) { // Check if it's a radio button if (e.target.matches('input[type="radio"]')) { animateFormTransition(); // Small delay before clicking to let animation start setTimeout(() => { const nextButton = document.querySelector('.btn-wizard-nav-next'); if (nextButton) nextButton.click(); }, 50); } // Check if it's a select element if (e.target.matches('[name="data[select]"]') && e.target.value) { animateFormTransition(); // Small delay before clicking to let animation start setTimeout(() => { const nextButton = document.querySelector('.btn-wizard-nav-next'); if (nextButton) nextButton.click(); }, 50); } }); } // Function to add animation to next button clicks function setupButtonAnimation() { document.addEventListener('click', function(e) { // Check if the next button was clicked directly or via a child element if (e.target.matches('.btn-wizard-nav-next') || e.target.closest('.btn-wizard-nav-next')) { // Just animate, don't interfere with the click animateFormTransition(); } }, false); // Use bubbling phase to not interfere with form's handlers } // Initialize when the DOM is ready if (document.readyState !== 'loading') { setupRadioAutoAdvance(); setupButtonAnimation(); } else { document.addEventListener('DOMContentLoaded', function() { setupRadioAutoAdvance(); setupButtonAnimation(); }); }})();</script>