Frontend Mentor | Multi-step form

Solution retrospective
I'm most proud of how the form dynamically adapts to user selections—particularly the toggle between monthly and yearly plans, the automatic price recalculations, and the way selected add-ons update both visually and in the summary section. The real-time form validation with accessibility considerations (like aria-invalid
) also adds to a more inclusive user experience.
Next time, I would refactor parts of the JavaScript for better modularity and maintainability—especially the logic around plan toggling and summary updates, which could be broken into smaller, reusable functions. I’d also consider separating concerns more clearly (e.g., using separate files for validation logic, UI updates, and pricing calculations) and possibly integrating a frontend framework like React or Svelte for more scalable state management and reactivity.
What challenges did you encounter, and how did you overcome them?One of the main challenges was managing the state of multiple interdependent components—such as syncing the selected plan with its price, toggling between billing cycles, and updating add-on selections in both UI and summary. It was easy for small logic issues to cause inconsistencies, especially when toggling between monthly and yearly pricing.
To overcome this, I carefully structured event listeners and used consistent class toggling (selected-plan
, shift-l
, shift-r
) to track the UI state. I also centralized logic for recalculating prices and updating summaries through dedicated functions like summaryHeadUpdate()
and calculateTotal()
to avoid redundancy. Testing and refining each step interaction helped ensure a smooth user experience across different screen sizes and inputs.
-
Form Validation Enhancements
I'd like feedback on improving the validation logic. Right now, it's handled on blur and before progressing to the next step, but I’m unsure if the current method is scalable or the most accessible for screen readers. -
Responsive Layout Optimization
The layout changes for smaller screens, but I feel the transition between desktop and mobile could be more fluid. I'd appreciate suggestions on better ways to handle this, especially regarding flex/grid layout restructuring. -
Code Readability and Refactoring
I used a lot offorEach
loops and manual DOM manipulation. I'd love tips on how to refactor this JavaScript to make it more modular, maintainable, or even more performant—perhaps using component-based structures or utility functions. -
Accessibility
I added basic ARIA attributes, but I’m not sure if the form is fully accessible. I'd like detailed feedback on improving keyboard navigation, focus management between steps, and screen reader compatibility. -
Scalable Pricing Logic
The pricing and toggle logic are currently hardcoded and a bit repetitive. I’d appreciate suggestions on how to structure pricing data (e.g., using objects or JSON) to make the logic more dynamic and easier to extend.
Please log in to post a comment
Log in with GitHubCommunity feedback
- P@dar-ju
Hi Maxessien!
I find your work quite detailed and thorough, you are great!
I found a few things that could be improved or fixed.
First of all, HTML, you have a few errors:
<div class="steps" aria-label="Form steps navigation"><span class="steps-num active">1</span><span class="steps-indicator">Step 1<p>Your info</p></span></div>
why are you putting p in span? you can't do that. Change p to span- same as putting div in label, it is an error
- same as h3 in span, change span to div
- you have a form on all pages, but you moved the button outside of it, it is not advisable to do this, the button should be in the form and be responsible for processing the form
- on the add-ons page you use ul and li and this is good, and on the plan page there is also a list of plans
About the logic of the fields:
- shows an error for the phone number if there are not enough digits, but does not show how many there should be
- when you click the Confirm button, reset all fields in case you need to fill out the form again
About the visual part:
- add .toggle-display
cursor: pointer;
to the entire field so that you can understand that the entire element can be clicked. And fix the block from span to div - on the section number fields, on the contrary,
cursor: pointer;
is set, but nothing happens when clicked, either remove this line or add logic
To summarize briefly: you need to figure out when to use span (text element) and when div (block element), you need to include all form controls in the form, including the button.
Otherwise, great, good luck with your development!
Join our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord