Form Elements

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.

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; }

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; }

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; }

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; }

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; }

Key Takeaways