<form>
<label for="name">Full Name <span aria-hidden="true">*</span></label>
<input type="text" id="name" name="name" autocomplete="name" required>
<label for="email">Email <span aria-hidden="true">*</span></label>
<input type="email" id="email" name="email" autocomplete="email" required>
<label for="subject">Subject</label>
<select id="subject" name="subject">
<option value="">Choose a subject…</option>
<option value="support">Support</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<button type="submit" class="primary">Send</button>
<button type="reset" class="secondary">Clear</button>
</form>
Forms
Native HTML form elements styled automatically — no extra classes on inputs, labels, or textareas. The framework handles spacing, focus states, validation, and dark mode.
Complete Contact Form
Validation States
Axiom01 uses native HTML5 validation states (`:invalid:not(:placeholder-shown)`) to automatically highlight errors when a user leaves an invalid field, without requiring custom JS or extra classes.
<!-- Just use native HTML5 validation attributes (type="email", required) -->
<label for="email">Email Address</label>
<input type="email" id="email" value="invalid-email@" required>
Modifiers
- `form.centered` - Limits the form's maximum width and centers it using margins.
All Input Types
<!-- All types are styled automatically — no classes needed -->
<label for="date">Date</label>
<input type="date" id="date">
<label for="time">Time</label>
<input type="time" id="time">
<label for="vol">Volume</label>
<input type="range" id="vol" min="0" max="100" value="50">
<label for="file">File Upload</label>
<input type="file" id="file" accept=".pdf,.doc">
Textarea
Set rows for initial height. The browser allows vertical resize via resize: vertical (applied by default). Use maxlength + <output> for character counts:
<label for="bio">Bio</label>
<textarea id="bio" rows="4" maxlength="280"></textarea>
Select & Option Groups
<label for="plan">Plan</label>
<select id="plan">
<option value="">Choose…</option>
<option value="free">Free</option>
<option value="pro">Pro</option>
</select>
<!-- Grouped options -->
<select id="stack">
<optgroup label="Frontend">
<option>React</option>
</optgroup>
<optgroup label="Backend">
<option>Node.js</option>
</optgroup>
</select>
Checkboxes & Radio Buttons
<!-- Always wrap in fieldset + legend -->
<fieldset>
<legend>Notifications</legend>
<label>
<input type="checkbox" name="notify" value="email" checked>
Email notifications
</label>
<label>
<input type="checkbox" name="notify" value="sms">
SMS notifications
</label>
</fieldset>
<fieldset>
<legend>Account type</legend>
<label>
<input type="radio" name="type" value="personal" checked>
Personal
</label>
<label>
<input type="radio" name="type" value="team">
Team
</label>
</fieldset>
Validation States
Use aria-invalid + aria-describedby for accessible error states. A helper <small> element provides context text:
<!-- Error state -->
<label for="email">Email</label>
<input type="email" id="email" value="bad-email"
aria-invalid="true"
aria-describedby="email-error">
<small id="email-error">
<span class="axicon render" data-name="Alert-Circle"></span>
Please enter a valid email address.
</small>
<!-- With helper text -->
<label for="pw">Password</label>
<input type="password" id="pw" aria-describedby="pw-hint">
<span id="pw-hint">Minimum 8 characters.</span>
Required Fields Pattern
<p><small>Fields marked * are required.</small></p>
<label for="name">Name <span aria-hidden="true">*</span></label>
<input type="text" id="name" required>
<!-- The * is aria-hidden — required attr does the accessible work -->
Inline Search Form
For single-line inline forms, wrap input + button in a <div class="actions">:
<label for="search">Search documentation</label>
<div class="actions">
<input type="search" id="search" placeholder="Search…">
<button type="submit" class="primary">
<span class="axicon render" data-name="Search"></span> Search
</button>
</div>
Native Validation with JavaScript
const form = document.querySelector('form');
form.addEventListener('submit', e => {
e.preventDefault();
// Validate all fields
const fields = form.querySelectorAll('input, select, textarea');
let firstInvalid = null;
fields.forEach(field => {
const valid = field.checkValidity();
field.setAttribute('aria-invalid', !valid);
// Show/hide associated error message
const errorId = field.getAttribute('aria-describedby');
if (errorId) {
const errorEl = document.getElementById(errorId);
if (errorEl) errorEl.hidden = valid;
}
if (!valid && !firstInvalid) firstInvalid = field;
});
if (firstInvalid) {
firstInvalid.focus(); // Move focus to first error
return;
}
// All valid — submit
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
Design Philosophy
- No extra classes on inputs — all types styled via
input[type="..."]element selectors - Label always paired — use
for/idor wrap the input inside the label - fieldset + legend — always group related checkboxes and radios
- Native validation first —
required,type,min,max,pattern - aria-describedby — connect error/helper text to the input by
id - autocomplete — always set for common fields (name, email, address)
- No .form-control, .form-group, .input-wrapper — these are anti-patterns in Axiom01
Accessibility
- Every input must have a visible
<label>— placeholder text disappears and is not a label - Required fields: use
requiredattribute (not CSS-only asterisks) - Error messages: use
aria-invalid="true"on the input +aria-describedbypointing to the error text - Error text container should have
role="alert"for immediate announcement - Disabled fields use the
disabledattribute — never CSSpointer-events: noneonly - Group related controls in
<fieldset>with a<legend> - Touch targets minimum 44×44px — the framework ensures this for all inputs
- Focus styles are always visible — never suppress
:focus-visible
Features
- Semantic Structure - Built with native HTML5 elements for maximum reliability.
- Theme Aware - Automatically adapts to all 22 Axiom01 themes via OKLCH tokens.
- Fully Responsive - Scales perfectly from mobile to desktop screens.
- No JS Dependency - Core functionality relies on pure CSS for maximum performance.
- Customizable - Easily extendable via Axiom01's design tokens and modifiers.
Use Cases
The Forms component is designed for versatile implementation across modern web applications. Ideal scenarios include:
- Dashboards & Admin Panels - Structured data presentation and interface control.
- Content Management Systems - Organizing complex information hierarchies and media.
- E-Commerce Platforms - Enhancing product discovery and user workflows.
- Marketing Sites - Highlighting key product offerings cleanly and effectively.
- SaaS Applications - Delivering native-feeling, responsive app experiences.