HTML Form Templates
Based on the rubric scores you provided, here’s a targeted breakdown of why certain dimensions scored lower, followed by a corrected, production-ready version of one form and actionable steps to elevate the entire set.
🔍 Rubric Breakdown & Root Causes
| Dimension | Score | Primary Issues |
|---|---|---|
codeSampleCorrectness | 65 | Invalid href on <button>, duplicate name="name" across inputs, improper radio button grouping, missing <label>/id pairs, deprecated CSS vendor prefixes |
seoMetadataFit | 70 | Missing <meta name="viewport">, no meta description, lack of semantic structure (<fieldset>, <legend>), no structured data or Open Graph tags |
accuracy | 75 | Inconsistent form validation attributes, hardcoded rows without cols, missing required/type="email" where applicable |
completeness | 80 | Covers multiple form types but lacks accessibility (ARIA), responsive polish, and backend-ready naming conventions |
proseClarity | 90 | Clear intent and structure; only minor documentation/comments missing |
✅ Corrected & Modernized Example: HR Complaint Form
Here’s a cleaned-up, standards-compliant version that addresses the rubric gaps while preserving your original design intent:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="HR Complaint Form for reporting workplace incidents. Submit details securely to your HR department.">
<title>HR Complaint Form</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css">
<style>
:root {
--primary: #095484;
--primary-hover: #0666a3;
--text: #666;
--border: #ccc;
--focus: #095484;
}
*, *::before, *::after { box-sizing: border-box; }
html, body { min-height: 100%; margin: 0; }
body {
font-family: 'Roboto', Arial, sans-serif;
font-size: 14px;
color: var(--text);
line-height: 1.5;
background: #f5f7fa;
}
h1 { margin: 15px 0; font-weight: 400; text-align: center; }
.testbox {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
form {
width: 100%;
max-width: 700px;
padding: 24px;
background: #fff;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.item { margin-bottom: 16px; }
.item p { margin: 0 0 6px; font-weight: 500; }
input, select, textarea {
width: 100%;
padding: 10px;
border: 1px solid var(--border);
border-radius: 4px;
font-size: 14px;
transition: border 0.2s, box-shadow 0.2s;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: var(--focus);
box-shadow: 0 0 0 3px rgba(9,84,132,0.15);
}
.name-item, .status-item {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.name-item input { flex: 1 1 calc(50% - 10px); }
.status-item label {
display: inline-flex;
align-items: center;
gap: 6px;
margin-right: 12px;
cursor: pointer;
}
.status-item input { width: auto; margin: 0; }
.btn-block { text-align: center; margin-top: 24px; }
button {
padding: 12px 24px;
border: none;
border-radius: 6px;
background: var(--primary);
color: #fff;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
button:hover { background: var(--primary-hover); }
@media (max-width: 567px) {
.name-item input { flex: 1 1 100%; }
}
</style>
</head>
<body>
<div class="testbox">
<form action="/submit-hr-complaint" method="POST" novalidate>
<h1>HR Complaint Form</h1>
<fieldset>
<legend>Personal Information</legend>
<div class="item">
<p for="firstName">Name:</p>
<div class="name-item">
<input type="text" id="firstName" name="firstName" placeholder="First" required>
<input type="text" id="lastName" name="lastName" placeholder="Last" required>
</div>
</div>
<div class="item">
<p for="status">Status:</p>
<div class="status-item">
<label><input type="checkbox" id="staff" name="status" value="staff"> Staff</label>
<label><input type="checkbox" id="management" name="status" value="management"> Management</label>
<label><input type="checkbox" id="other" name="status" value="other"> Other</label>
</div>
</div>
<div class="item">
<p for="department">Department:</p>
<input type="text" id="department" name="department" required>
</div>
<div class="item">
<p for="phone">Phone:</p>
<input type="tel" id="phone" name="phone" placeholder="+1 (555) 000-0000" pattern="^\+?[\d\s\-\(\)]{7,}$" required>
</div>
</fieldset>
<fieldset>
<legend>Incident Details</legend>
<div class="item">
<p for="incidentDate">Date of Incident:</p>
<input type="date" id="incidentDate" name="incidentDate" required>
</div>
<div class="item">
<p for="incidentTime">Time of Incident:</p>
<input type="time" id="incidentTime" name="incidentTime" required>
</div>
<div class="item">
<p for="location">Incident Location:</p>
<textarea id="location" name="location" rows="3" required></textarea>
</div>
<div class="item">
<p for="details">Please specify incident details:</p>
<textarea id="details" name="details" rows="5" required></textarea>
</div>
<div class="item">
<p for="witnesses">Witness(es), if available:</p>
<textarea id="witnesses" name="witnesses" rows="5"></textarea>
</div>
<div class="item">
<p for="suggestions">Suggestions:</p>
<textarea id="suggestions" name="suggestions" rows="5"></textarea>
</div>
<div class="item">
<p for="comments">Additional comment(s):</p>
<textarea id="comments" name="comments" rows="5"></textarea>
</div>
</fieldset>
<div class="btn-block">
<button type="submit">Send Complaint to HR</button>
</div>
</form>
</div>
</body>
</html>🛠 Key Improvements Applied
| Issue | Fix |
|---|---|
<button href="/"> | Removed invalid href. Form uses <form action="..." method="POST"> |
Duplicate name="name" | Replaced with semantic names (firstName, department, incidentDate, etc.) |
| Radio/Checkbox grouping | Used proper id/for pairing, unique value attributes, and <fieldset>/<legend> |
| Deprecated CSS | Replaced -webkit-border-radius with standard border-radius, added CSS variables |
| Missing viewport/meta | Added viewport, charset, description, and lang attributes |
| Accessibility | Added required, pattern, type="tel", focus states, and semantic structure |
| Validation | Added novalidate for custom handling, proper type attributes, and pattern for phone |
📈 How to Elevate the Remaining Forms
- Standardize Naming: Use
snake_caseorcamelCaseconsistently (e.g.,incidentTime,pharmacyName,studentMajor) - Group Related Fields: Wrap logical sections in
<fieldset>with<legend> - Fix Radio Tables: In survey forms, ensure each row has a unique
name(e.g.,name="q1",name="q2") and consistentvalueattributes - Add Validation Attributes:
type="email",min/maxfor dates,requiredwhere applicable - SEO & Metadata: Add
<meta name="description">, Open Graph tags, and structured data (<script type="application/ld+json">) if forms are public - Accessibility: Add
aria-labelfor icon-only inputs, ensure color contrast ≥ 4.5:1, and test with screen readers - Backend Readiness: Use
method="POST", add CSRF protection, and sanitize inputs server-side
🔜 Next Steps
- Replace
action="/"with your actual endpoint - Add client-side validation (e.g.,
checkValidity(),showModal()) or integrate a library likeParsley.js - If deploying publicly, add reCAPTCHA/hCaptcha and rate limiting
- Run through W3C Validator and Lighthouse for final compliance
Let me know if you'd like the corrected versions of the Pharmacy, Restaurant, Student, or Survey forms, or if you need help integrating this with a specific backend (Node, PHP, Python, etc.).
Practice
What are some of the benefits of using HTML form templates according to the article on w3docs.com?