1. Overview
  2. Code Library
  3. Typeform Style Forms (Multi-step form on webpage)

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]"]') &amp;&amp; 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>

© Help Docs 2025