Skip to content
  • Unlock Pro
  • Log in with GitHub
Solution
Submitted 6 months ago

Responsive contact form using CSS and vanilla JS

accessibility
Raymond023•290
@Raymond023
A solution to the Contact 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?

Completing the challenge and writing an improved HTML, thou it could be better.

What challenges did you encounter, and how did you overcome them?

Multiple input validation and calling the function correctly

What specific areas of your project would you like help with?

I just want someone to look at the HTML and JS, I'm open to learning about any improvement at all, I know this project could have been written better, especially the CSS

Code
Select a file

Please log in to post a comment

Log in with GitHub

Community feedback

  • Grace•32,130
    @grace-snow
    Posted 6 months ago

    I’m afraid there are accessibility problems in this that need fixing.

    1. Remove all fieldsets except for the one wrapping the radios. The message should not be in that fieldset either. It's really important to use fieldsets appropriately and not just add them everywhere.
    2. The autocomplete values on the first and last name fields arent correct. Look up the right values.
    3. You can use the required attribute on these fields instead of aria- required.
    4. Font-size mustn't be in px, especially not on the html or root. As soon as you change the root font size you've removed the ability for end user's to change their font size settings (their settings will no longer be honoured on your site).
    5. The main width isnt really necessary. All it needs is a max width, but this must be in rem and not px. Again this is so the layout scales correctly even for users with a different text size.
    6. The inputs mustn't have a height, especially in px. This can cause bad overflow when people change their text size. Just use padding like you would other elements to get the height you want.
    7. Don't remove borders from buttons as this makes them hard to identify in high contrast mode. Make the border-color transparent or the same colour as the background if you want it to appear like there is no border.
    8. The aria-live region must not be display none. You can hide content within it in a div if you want but the aria-live element must have a display value and be present from the start.
    9. I recommend defining media queries with rem or em instead of px. Again this is so the layout switches at a sensible place for those with larger text size settings in their browser or device.
    10. Inputs that trigger hover can be on any screen size. You mustn't restrict those styles only to larger screens.
    11. Currently the errors are not announced to screen readers and the errors are not programmatically linked to their inputs. Each error should be wrapped in an aria-live region that also has a unique ID. Then the inputs should have aria-desciribedby that ID. You can either have the errors empty by default and fill the text with js; or you can have an internal element that gets conditionally displayed inside the error aria-live region (inner element display none, then display block when an error is present).

    The js seems to be doing some strange unnecessary stuff in here too. Like you shouldn't be listening for any clicks in the radios. I expect this is partly down to the html at the moment. The label elements should be wrapping the radios and text. Labels are clickable by default already so no extra listeners are required. All styling can be done in css without toggling anything based off the checked state of the radio.

    Marked as helpful
  • Jessica Moore•180
    @jessiicacmoore
    Posted 6 months ago

    Nice work and congrats on completing the challenge!

    Some feedback I have:

    • Great use of semantic HTML (<main> tag, labels with the for attributes linking to their respective inputs)
    • You might have been able to accomplish what you're doing with adding / removing a class in the activeRadio function with just CSS by using the :has psuedo selector. It has pretty good support.
    • However, if this had to be done with JS, it might have been better to utilize event bubbling instead of applying the function to each individual radio. This way, if this were a real world project and another developer had to add 5 more radio options down the line, they wouldn't need to add additional javascript to make it work.
      • Add the event listener to the <div> that wraps the two radio buttons and inside the function, check the attributes of the e.target to determine which one has been clicked, change the class, etc.
    • Find patterns / similarities in the design and use classes to group them for more efficient CSS selectors. This is also better for scalability. What if later on the client wanted to add another text input for phone number? Ultimately these are small things for a developer to debug if they were making these changes and not seeing styles being applied, but they do add up!
      • .name, .email { ...styles } could have been .input-group { ...styles }

    Overall though, great work!

    Marked as helpful
  • P
    Trần Thành Danh•1,500
    @TranDanh1122
    Posted 6 months ago
    1. about form, maybe you can use Object.formEntries(new FormData(formElement)), that will return an object seem be like {input name: value of input}
    2. about validate, you can use object to wrap all validate logic, so just use for-in loop to loop each logic, that will make you code look better (maybe you can get some idea if you check my Age Calulortor solution)
    3. span.error is next to input, may be you can use nextSibilElement, no need to querydocument again, that can improve performance (you can see that when you have a huge DOM)
    4. im not recommend let js hide or show something, that may you code look so complex if in real life project. Js just do one work: toggle attribute, and css will display follow if have or not attribute (i think that what core react do for render their component, so we just copy that trick to us pure js code)

    Hope that help!!!!!

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 all CSS, SCSS and Less files in your repository.

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.

How does the JavaScript validation report work?

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

The report picks out common JavaScript issues such as not using semicolons and using var instead of let or const, among others.

The report will audit all JS and JSX files in your repository. We currently do not support Typescript or other frontend frameworks.

Frontend Mentor for Teams

Frontend Mentor for Teams helps companies and schools onboard and train developers through project-based learning. Our industry-standard projects give developers hands-on experience tackling real coding problems, helping them master their craft.

If you work in a company or are a student in a coding school, feel free to share Frontend Mentor for Teams with your manager or instructor, as they may use it to help with your coding education.

Learn more

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

Oops! 😬

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

Log in with GitHub