📝 Form Elements Design Guide
Form elements є critical touchpoints між користувачами та системою. Whether collecting email для newsletter signup, dosage calculator inputs, або trip report submissions, well-designed forms reduce friction, prevent errors, та improve completion rates. Для mushroom education site, forms handle: cultivation log entries, safety checklists, species identification submissions, та user feedback. Effective form design balances visual clarity (labels, placeholders), validation feedback (error/success states), accessibility (keyboard navigation, screen readers), та mobile usability. Цей guide охоплює complete form element library з CSS, validation patterns, та best practices від WCAG 2.1 accessibility standards.
🎨 Form Elements Showcase
Contact Form Example
💻 CSS Implementation
Base Input Styles:
/* Label */
.form-label {
display: block;
font-weight: 600;
margin-bottom: 8px;
color: #2c3e50;
font-size: 0.95em;
}
/* Required indicator */
.form-label::after {
content: " *";
color: #dc3545;
}
/* Text Input */
.form-input {
width: 100%;
padding: 12px 16px;
font-size: 1em;
line-height: 1.5;
color: #2c3e50;
background: white;
border: 2px solid #e9ecef;
border-radius: 8px;
transition: all 0.3s ease;
font-family: inherit;
}
/* Focus State */
.form-input:focus {
outline: none;
border-color: #f857a6;
box-shadow: 0 0 0 3px rgba(248, 87, 166, 0.1);
}
/* Hover State */
.form-input:hover {
border-color: #dee2e6;
}
/* Disabled State */
.form-input:disabled {
background: #f8f9fa;
cursor: not-allowed;
opacity: 0.6;
}
/* Placeholder */
.form-input::placeholder {
color: #adb5bd;
opacity: 1;
}
Validation States:
/* Error State */
.form-input.error {
border-color: #dc3545;
background: #fff5f5;
}
.form-input.error:focus {
box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.1);
}
/* Success State */
.form-input.success {
border-color: #28a745;
background: #f0fff4;
}
.form-input.success:focus {
box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.1);
}
/* Validation Messages */
.form-message {
margin-top: 6px;
font-size: 0.875em;
display: flex;
align-items: center;
gap: 6px;
}
.form-message.error {
color: #dc3545;
}
.form-message.error::before {
content: "⚠️";
}
.form-message.success {
color: #28a745;
}
.form-message.success::before {
content: "✓";
}
Select Dropdown:
.form-select {
width: 100%;
padding: 12px 16px;
padding-right: 40px; /* Space для arrow */
font-size: 1em;
border: 2px solid #e9ecef;
border-radius: 8px;
background: white;
cursor: pointer;
font-family: inherit;
/* Remove default arrow */
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
/* Custom arrow */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='%232c3e50' d='M6 8L0 0h12z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 16px center;
}
.form-select:focus {
outline: none;
border-color: #f857a6;
box-shadow: 0 0 0 3px rgba(248, 87, 166, 0.1);
}
Checkboxes та Radio Buttons:
/* Modern approach: use accent-color */
.form-checkbox,
.form-radio {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: #f857a6; /* Modern browsers */
}
/* Wrapper для label clickability */
.checkbox-wrapper,
.radio-wrapper {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
}
.checkbox-wrapper:hover,
.radio-wrapper:hover {
opacity: 0.8;
}
/* Custom checkbox (advanced) */
.custom-checkbox {
position: relative;
width: 20px;
height: 20px;
}
.custom-checkbox input {
opacity: 0;
position: absolute;
}
.custom-checkbox-box {
width: 20px;
height: 20px;
border: 2px solid #e9ecef;
border-radius: 4px;
background: white;
transition: all 0.3s;
}
.custom-checkbox input:checked + .custom-checkbox-box {
background: #f857a6;
border-color: #f857a6;
}
.custom-checkbox input:checked + .custom-checkbox-box::after {
content: "✓";
color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
File Upload:
<!-- HTML -->
<label class="file-upload">
<input type="file" accept="image/*" />
<div>📁 Click to upload або drag and drop</div>
<div class="file-hint">PNG, JPG up to 10MB</div>
</label>
/* CSS */
.file-upload {
border: 2px dashed #e9ecef;
border-radius: 8px;
padding: 30px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
}
.file-upload:hover {
border-color: #f857a6;
background: #fff7fa;
}
.file-upload input[type="file"] {
display: none; /* Hide default input */
}
.file-hint {
font-size: 0.875em;
color: #6c757d;
margin-top: 8px;
}
♿ Accessibility
Proper Label Association:
<!-- Method 1: for/id association -->
<label for="email" class="form-label">Email</label>
<input type="email" id="email" class="form-input" />
<!-- Method 2: wrap input -->
<label class="form-label">
Email
<input type="email" class="form-input" />
</label>
ARIA Attributes:
<!-- Required field -->
<input type="text" aria-required="true" required />
<!-- Error state -->
<input type="email"
class="form-input error"
aria-invalid="true"
aria-describedby="email-error" />
<div id="email-error" class="form-message error">
Invalid email format
</div>
<!-- Helper text -->
<input type="password"
aria-describedby="password-hint" />
<div id="password-hint" class="form-hint">
Must be at least 8 characters
</div>
✅ Form Elements Checklist
Implementation Checklist:
- ☐ All inputs have associated labels (for/id або wrapper)
- ☐ Focus states clearly visible (outline або box-shadow)
- ☐ Placeholder text не замінює labels
- ☐ Validation states: error та success styled
- ☐ Error messages descriptive та specific
- ☐ Required fields marked (*)
- ☐ Touch targets ≥ 44x44px на mobile
- ☐ ARIA attributes: aria-required, aria-invalid, aria-describedby
- ☐ Keyboard navigation works (Tab, Shift+Tab)
- ☐ Color contrast meets WCAG AA (4.5:1)
- ☐ Disabled states clearly indicated
- ☐ File upload shows selected filename