Form Fields
Forms are a core part of most web applications and require a solid, predictable HTML structure to be maintainable and scalable. Beyond visual styling, forms rely heavily on semantic markup to ensure proper validation, accessibility, and JavaScript behavior.
Every form field should:
- Be wrapped in a dedicated container (form group)
- Include a label properly associated with its input
- Expose a predictable DOM structure for styling and JS hooks
- Reserve space for validation and error messages
Keeping this structure consistent across all input types (text, select, checkbox, radio, etc.) allows us to reuse styles, validation logic, and interaction patterns across projects, reducing complexity and preventing edge cases.
Component Structure
Section titled “Component Structure”- Form Group -> only has margin bottom, and the role is to separate between fields
- Form Label -> Displays informational text for input (not mandatory)
- Form field -> can be input type text, checkbox, select,radio,etc, they have colors for sucess & error
- Form Error -> Is only visible & generated via JS, they are usefull when a form field (custom) needs to display custom error messages
[ Form Group ][ Label ] Label Name [ Label ][ Input/Select/Radio ] Label Name [ /Input/Select/Radio ][ Error ] Error Message [ /Error ][/Form Group]Layout
Section titled “Layout”The layout can be adjusted freely, as long as the column system is respected in all cases and existing inline lists are preserved where applicable.
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; border: 1px solid #ccc; border-radius: 8px;"> <iframe src="https://codepen.io/andresclua/full/yyYQjyR" style="position: absolute; top:0; left:0; width:100%; height:100%; border:0;" allowfullscreen loading="lazy"> </iframe></div>Spinner to the Rescue
Section titled “Spinner to the Rescue”The c--spinner component will now be part of all our projects. It provides a consistent way to indicate to users that an action is in progress, such as:
- A search is running
- A page transition is loading
- A form is being submitted
In the next example you are going to see spinner in action
<iframe src="https://codepen.io/andresclua/embed/MYazBOV?default-tab=result" style="width: 100%; height: 500px;" frameborder="0" loading="lazy" allowfullscreen></iframe>From now on this is the structure that we want to implement, since we can take advantage of a shared and predictable DOM structure, reusable styles, and unified JavaScript logic across all projects. This approach reduces edge cases, simplifies maintenance, and ensures a consistent user experience.
States & Feedback
Section titled “States & Feedback”All form fields must support the following states:
- Default – Neutral, ready for interaction
- Focus – Clearly visible focus state for accessibility
- Success – Used when validation passes
- Error – Used when validation fails and paired with a Form Error message
- Disabled – Non-interactive, visually distinct
State changes should be handled via classes and not inline styles.
Simple Form Validation
Best practices
Section titled “Best practices”- Validation should be triggered on submit and, when needed, on blur.
- Error messages must be specific and helpful.
- Errors should never rely on color alone — text feedback is mandatory.
- Native browser validation can be overridden if custom behavior is required.
- Every input must be associated with a label (visually hidden labels are acceptable).
- Use semantic HTML whenever possible.
- Ensure sufficient color contrast in all states.
- Error messages must be announced to screen readers when they appear.
Knowledge Check
Test your understanding of this section
Loading questions...