What You'll Learn
Style all HTML input types: text, email, password, number, search, and more
Customize checkboxes and radio buttons with accent-color
Create custom select dropdowns by removing default browser styling
Control textarea resizing with the resize property
Style file inputs and their browser-specific pseudo-elements
Customize range sliders and color pickers across different browsers
Work with date and time inputs and their platform-specific interfaces
Use fieldset and legend to group related form controls
Introduction to Form Elements
HTML provides a rich set of form input types, each designed for specific data entry needs. Modern browsers render these inputs with native controls that provide appropriate keyboards on mobile devices and built-in validation. Understanding how to style these elements consistently across browsers is essential for creating professional forms.
Different input types require different styling approaches. Text-based inputs are straightforward, but elements like checkboxes, select dropdowns, and range sliders need browser-specific pseudo-elements and vendor prefixes. The accent-color property provides a modern way to theme certain form controls without complex custom styling.
Progressive Enhancement:
Not all browsers support all input types equally. Older browsers may fall back to text inputs, so always include appropriate pattern and validation attributes as a safety net.
Text Input Types
HTML provides specialized text input types that trigger appropriate mobile keyboards and enable browser validation. These include email, tel, url, number, search, and password.
<input type="text" placeholder="Enter text">
<input type="email" placeholder="user@example.com">
<input type="password" placeholder="Enter password">
<input type="tel" placeholder="(555) 123-4567">
<input type="url" placeholder="https://example.com">
<input type="number" min="0" max="100">
<input type="search" placeholder="Search...">
Removing Number Input Spinners
Number inputs display spinner arrows by default. Remove them for cleaner styling using browser-specific pseudo-elements:
/* Chrome, Safari, Edge */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type="number"] {
-moz-appearance: textfield;
}
Mobile Keyboards:
Using the correct input type shows optimized keyboards on mobile: email adds @ key, tel shows number pad, url adds .com shortcut.
Checkboxes and Radio Buttons
Checkboxes allow multiple selections while radio buttons allow only one selection within a group. The modern accent-color property lets you quickly theme these inputs without custom styling.
<div class="checkbox-item">
<input type="checkbox" id="option1" checked>
<label for="option1">Subscribe to newsletter</label>
</div>
<div class="radio-item">
<input type="radio" id="small" name="size" checked>
<label for="small">Small</label>
</div>
input[type="checkbox"],
input[type="radio"] {
width: 20px;
height: 20px;
margin-right: 10px;
cursor: pointer;
accent-color: #3b82f6;
}
label {
cursor: pointer;
}
accent-color Browser Support:
accent-color is supported in Chrome 93+, Firefox 92+, and Safari 15.4+. It provides a simple way to theme form controls to match your brand colors.
Select Dropdowns
Select elements are notoriously difficult to style consistently. Remove the default arrow and add a custom one using background images and appearance: none.
select {
width: 100%;
padding: 10px 35px 10px 12px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
background: white;
/* Remove default arrow */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/* Add custom arrow */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23333' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
}
/* IE 11 */
select::-ms-expand {
display: none;
}
Option Groups
Use <optgroup> to organize options into categories within a select dropdown:
<select>
<optgroup label="Citrus">
<option value="orange">Orange</option>
<option value="lemon">Lemon</option>
</optgroup>
<optgroup label="Berries">
<option value="strawberry">Strawberry</option>
<option value="blueberry">Blueberry</option>
</optgroup>
</select>
Textareas
Textareas are multi-line text inputs. Control their resizing behavior with the resize property to prevent layout issues.
textarea {
width: 100%;
padding: 10px 12px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 16px;
font-family: inherit;
line-height: 1.5;
min-height: 100px;
/* Allow vertical resize only */
resize: vertical;
}
/* Disable resizing completely */
textarea.no-resize {
resize: none;
}
/* Allow horizontal resize */
textarea.horizontal-resize {
resize: horizontal;
}
/* Allow both directions */
textarea.both-resize {
resize: both;
}
Best Practice:
Use resize: vertical as the default. It allows users to expand the textarea for longer content without breaking your layout horizontally.
File Inputs
File inputs consist of a button and text showing the selected filename. Style the button using browser-specific pseudo-elements.
input[type="file"] {
width: 100%;
padding: 10px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
background: white;
}
/* Chrome, Safari, Edge */
input[type="file"]::-webkit-file-upload-button {
padding: 8px 16px;
border: none;
border-radius: 4px;
background: #3b82f6;
color: white;
cursor: pointer;
font-weight: 600;
margin-right: 12px;
}
input[type="file"]::-webkit-file-upload-button:hover {
background: #2563eb;
}
/* Firefox */
input[type="file"]::file-selector-button {
padding: 8px 16px;
border: none;
border-radius: 4px;
background: #3b82f6;
color: white;
cursor: pointer;
font-weight: 600;
margin-right: 12px;
}
input[type="file"]::file-selector-button:hover {
background: #2563eb;
}
Restricting File Types
<!-- Accept only images -->
<input type="file" accept="image/*">
<!-- Accept multiple files -->
<input type="file" multiple>
<!-- Accept specific file types -->
<input type="file" accept=".pdf,.doc,.docx">
Range Sliders
Range inputs create draggable sliders. Style the track and thumb separately using browser-specific pseudo-elements.
input[type="range"] {
width: 100%;
height: 8px;
-webkit-appearance: none;
appearance: none;
background: #ddd;
border-radius: 4px;
outline: none;
}
/* Chrome, Safari, Edge */
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 24px;
height: 24px;
border-radius: 50%;
background: #3b82f6;
cursor: pointer;
transition: all 0.2s;
}
input[type="range"]::-webkit-slider-thumb:hover {
background: #2563eb;
transform: scale(1.1);
}
/* Firefox */
input[type="range"]::-moz-range-thumb {
width: 24px;
height: 24px;
border: none;
border-radius: 50%;
background: #3b82f6;
cursor: pointer;
transition: all 0.2s;
}
input[type="range"]::-moz-range-track {
background: #ddd;
border-radius: 4px;
height: 8px;
}
Color Pickers
Color inputs open native color picker interfaces. Style the color swatch displayed in the input using pseudo-elements.
input[type="color"] {
width: 100px;
height: 50px;
border: 2px solid #ddd;
border-radius: 4px;
cursor: pointer;
padding: 2px;
}
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: none;
border-radius: 2px;
}
input[type="color"]::-moz-color-swatch {
border: none;
border-radius: 2px;
}
Date and Time Inputs
Date and time inputs provide native picker interfaces that vary by browser and platform. They're difficult to style consistently, but you can control basic appearance.
<input type="date">
<input type="time">
<input type="datetime-local">
<input type="month">
<input type="week">
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"] {
width: 100%;
padding: 10px 12px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 16px;
font-family: inherit;
}
Cross-Browser Differences:
Date and time inputs render very differently across browsers and platforms. For consistent UX, consider using a JavaScript date picker library. However, native inputs provide better accessibility and mobile experiences.
Fieldsets and Legends
Group related form controls using <fieldset> and provide a caption with <legend>. This improves both visual organization and accessibility.
<fieldset>
<legend>Personal Information</legend>
<label for="fname">First Name</label>
<input type="text" id="fname">
<label for="lname">Last Name</label>
<input type="text" id="lname">
</fieldset>
fieldset {
border: 2px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
legend {
padding: 0 10px;
font-weight: 600;
color: #3b82f6;
}
Accessibility Benefits:
Screen readers announce the legend when users interact with form controls inside the fieldset, providing important context. Use fieldsets especially for groups of checkboxes or radio buttons.
Key Takeaways
Input Types: Use appropriate input types (email, tel, url) for better mobile keyboards and validation
accent-color: Quickly theme checkboxes and radio buttons with modern accent-color property
appearance: none: Remove default browser styling for selects and range inputs before applying custom styles
Vendor Prefixes: Use ::-webkit- and ::-moz- pseudo-elements for cross-browser file and range input styling
Textarea Resize: Use resize: vertical to allow content expansion without breaking horizontal layout
File Input Buttons: Style with ::file-selector-button (Firefox) and ::-webkit-file-upload-button (Chrome/Safari)
Range Sliders: Style track and thumb separately using browser-specific pseudo-elements
Date Inputs: Accept platform-specific rendering for better accessibility and mobile UX
Fieldsets: Group related controls with <fieldset> and <legend> for better structure and accessibility
accept Attribute: Use accept on file inputs to filter selectable file types