Styling Form Elements
Form elements (<input>, <textarea>, <select>, <button>) require special styling. Many have default browser styles that are hard to override. Use appearance: none to reset, then style with custom CSS. Focus states, validation styles, and cross-browser compatibility are essential. Accessible forms maintain visible focus indicators.
Resetting form element styles
CSS
/* Remove default appearance */
input,
textarea,
select,
button {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
/* Removes browser default styling */
}
/* Apply custom box model */
input,
textarea,
select {
font-family: inherit;
font-size: 16px;
/* 16px prevents auto-zoom on iOS */
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
/* Default state */
input,
textarea,
select {
background: white;
color: #333;
transition: all 0.2s ease;
}
/* Focus state (essential for accessibility) */
input:focus,
textarea:focus,
select:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}
/* Placeholder styling */
input::placeholder,
textarea::placeholder {
color: #999;
opacity: 1;
/* opacity: 1 ensures visible in all browsers */
}
/* Disabled state */
input:disabled,
textarea:disabled,
select:disabled {
background: #f5f5f5;
color: #999;
cursor: not-allowed;
border-color: #ddd;
}Text input styling
CSS
/* Basic text input */
input[type="text"] {
width: 100%;
padding: 10px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
/* Password input */
input[type="password"] {
letter-spacing: 0.25em;
/* Makes typed characters less obvious */
}
/* Email input with validation */
input[type="email"] {
padding: 10px;
border: 1px solid #ddd;
}
input[type="email"]:invalid {
border-color: #e74c3c;
background: rgba(231, 76, 60, 0.05);
}
input[type="email"]:valid {
border-color: #2ecc71;
background: rgba(46, 204, 113, 0.05);
}
/* Search input with clear button */
input[type="search"]::-webkit-search-cancel-button {
appearance: none;
width: 20px;
height: 20px;
background: url('clear-icon.svg');
cursor: pointer;
}
/* Number input (hide spinner buttons) */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
/* Date input */
input[type="date"] {
padding: 10px;
border: 1px solid #ddd;
}
input[type="date"]::-webkit-calendar-picker-indicator {
cursor: pointer;
}Textarea and select styling
CSS
/* Textarea */
textarea {
width: 100%;
font-family: monospace;
font-size: 14px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
/* Allow vertical resize only */
min-height: 120px;
}
textarea:focus {
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}
/* Select/dropdown */
select {
width: 100%;
padding: 10px 12px;
padding-right: 30px;
/* Space for dropdown arrow */
border: 1px solid #ddd;
border-radius: 4px;
background-color: white;
background-image: url('data:image/svg+xml;...');
/* Custom dropdown arrow */
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 16px;
}
select:focus {
border-color: #3498db;
outline: none;
}
/* Option styling (limited) */
option {
padding: 10px;
background: white;
color: #333;
}
option:checked {
background: #3498db;
color: white;
}
/* Multiple select */
select[multiple] {
height: auto;
padding: 5px;
}
select[multiple] option {
padding: 5px 10px;
}Button styling
CSS
/* Reset button default styles */
button,
input[type="button"],
input[type="submit"],
input[type="reset"] {
appearance: none;
cursor: pointer;
font-family: inherit;
font-size: 16px;
}
/* Primary button */
.button-primary {
padding: 10px 20px;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
font-weight: 600;
transition: all 0.2s ease;
}
.button-primary:hover {
background: #2980b9;
box-shadow: 0 2px 8px rgba(52, 152, 219, 0.3);
}
.button-primary:active {
transform: scale(0.98);
/* Pressed effect */
}
.button-primary:focus-visible {
outline: 3px solid #3498db;
outline-offset: 2px;
}
.button-primary:disabled {
background: #bdc3c7;
cursor: not-allowed;
opacity: 0.6;
}
/* Secondary button */
.button-secondary {
padding: 10px 20px;
background: white;
color: #333;
border: 2px solid #ddd;
border-radius: 4px;
transition: all 0.2s ease;
}
.button-secondary:hover {
border-color: #3498db;
background: #f5f9ff;
}
/* Link button */
.button-link {
background: none;
border: none;
color: #3498db;
cursor: pointer;
text-decoration: underline;
font-size: inherit;
padding: 0;
}
.button-link:hover {
color: #2980b9;
}
/* Icon button */
.button-icon {
width: 40px;
height: 40px;
padding: 0;
background: #f0f0f0;
border: none;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
}
.button-icon:hover {
background: #e0e0e0;
}Form validation styling
CSS
/* Required field indicator */
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 5px;
font-weight: 600;
}
.form-label.required::after {
content: ' *';
color: #e74c3c;
}
/* Valid input */
input:valid {
border-color: #2ecc71;
}
input:valid + .form-feedback {
color: #2ecc71;
display: block;
}
/* Invalid input */
input:invalid {
border-color: #e74c3c;
}
input:invalid + .form-feedback {
color: #e74c3c;
display: block;
}
/* Form feedback message */
.form-feedback {
display: none;
font-size: 12px;
margin-top: 4px;
}
/* Required validation */
input:required:invalid {
border-color: #e74c3c;
background: rgba(231, 76, 60, 0.05);
}
/* Pristine vs touched state */
input.pristine {
border-color: #ddd;
}
input.touched:invalid {
border-color: #e74c3c;
background: rgba(231, 76, 60, 0.05);
}
/* Success state */
input.success {
border-color: #2ecc71;
background: rgba(46, 204, 113, 0.05);
}
input.success + .form-feedback {
color: #2ecc71;
display: block;
}Accessible form styling
CSS
/* Always maintain visible focus indicator */
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
button:focus-visible {
outline: 3px solid #3498db;
outline-offset: 2px;
}
/* Sufficient color contrast */
.form-label {
color: #333;
/* Contrast ratio ≥ 4.5:1 */
}
/* Error messages clearly visible */
.form-error {
color: #e74c3c;
font-weight: 600;
margin-top: 4px;
}
/* Large touch targets */
input,
button,
select {
min-height: 44px;
/* Minimum 44px for touchable elements */
}
/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
input,
textarea,
select,
button {
transition: none;
}
}
/* High contrast mode */
@media (prefers-contrast: more) {
input:focus,
button:focus {
outline-width: 4px;
}
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
input,
textarea,
select {
background: #2d2d2d;
color: #fff;
border-color: #444;
}
input:focus,
textarea:focus,
select:focus {
border-color: #5a9fd4;
}
}Common form patterns
CSS
/* Inline form */
.form-inline {
display: flex;
gap: 10px;
align-items: center;
}
.form-inline input {
flex: 1;
}
/* Stacked form (mobile-first) */
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 5px;
}
input {
width: 100%;
}
@media (min-width: 768px) {
.form-group-horizontal {
display: flex;
gap: 20px;
align-items: center;
}
.form-group-horizontal .form-label {
min-width: 100px;
margin-bottom: 0;
}
.form-group-horizontal input {
flex: 1;
}
}
/* Floating label pattern */
.form-group {
position: relative;
margin-bottom: 20px;
}
.form-label {
position: absolute;
top: 50%;
left: 12px;
transform: translateY(-50%);
transition: all 0.2s ease;
color: #999;
}
input:focus ~ .form-label,
input:not(:placeholder-shown) ~ .form-label {
top: -10px;
left: 0;
font-size: 12px;
color: #3498db;
}Note
Form styling: use `appearance: none` to reset defaults. Style with padding, border, border-radius, transition. Always show focus states for accessibility (outline or box-shadow). Use ::placeholder for placeholder color. Validation: use :valid, :invalid, :required. Buttons: manage hover, active, disabled, focus states. Mobile: ensure 44px minimum touch target. Dark mode: provide color-scheme support. Respect prefers-reduced-motion.
Next
Input, Textarea & Select Styling: [Input, Textarea & Select Styling](/css/input-styling).