Skip to content
  • Unlock Pro
  • Log in with GitHub
Solution
Submitted 11 days ago

Frontend Mentor | Multi-step form

sass/scss
Maxessien•80
@Maxessien
A solution to the Multi-step form challenge
View live sitePreview (opens in new tab)View codeCode (opens in new tab)

Solution retrospective


What are you most proud of, and what would you do differently next time?

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.

What specific areas of your project would you like help with?
  1. 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.

  2. 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.

  3. Code Readability and Refactoring
    I used a lot of forEach 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.

  4. 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.

  5. 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.

Code
Select a file

Please log in to post a comment

Log in with GitHub

Community feedback

  • P
    Andrey•4,240
    @dar-ju
    Posted 11 days ago

    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
Frontend Mentor logo

Stay up to datewith new challenges, featured solutions, selected articles, and our latest news

Frontend Mentor

  • Unlock Pro
  • Contact us
  • FAQs
  • Become a partner

Explore

  • Learning paths
  • Challenges
  • Solutions
  • Articles

Community

  • Discord
  • Guidelines

For companies

  • Hire developers
  • Train developers
© Frontend Mentor 2019 - 2025
  • Terms
  • Cookie Policy
  • Privacy Policy
  • License

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

How does the accessibility report work?

When a solution is submitted, we use axe-core to run an automated audit of your code.

This picks out common accessibility issues like not using semantic HTML and not having proper heading hierarchies, among others.

This automated audit is fairly surface level, so we encourage to you review the project and code in more detail with accessibility best practices in mind.

How does the CSS report work?

When a solution is submitted, we use stylelint to run an automated check on the CSS code.

We've added some of our own linting rules based on recommended best practices. These rules are prefixed with frontend-mentor/ which you'll see at the top of each issue in the report.

The report will audit 1st-party linked stylesheets, and styles within <style> tags.

How does the HTML validation report work?

When a solution is submitted, we use html-validate to run an automated check on the HTML code.

The report picks out common HTML issues such as not using headings within section elements and incorrect nesting of elements, among others.

Note that the report can pick up “invalid” attributes, which some frameworks automatically add to the HTML. These attributes are crucial for how the frameworks function, although they’re technically not valid HTML. As such, some projects can show up with many HTML validation errors, which are benign and are a necessary part of the framework.

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub