HTML <input> reference Jump to this section

Common attributes Jump to this section

type Jump to this section

The type attribute determines the kind of input control and what data it accepts. This is the most important attribute as it completely changes the input's behavior, validation, and appearance.

Common values: text, email, password, number, tel, url, search, date, time, datetime-local, month, week, color, file, range, checkbox, radio, hidden, submit, button, reset

Text inputs Jump to this section

<input type="text" placeholder="Enter text">
<input type="email" placeholder="email@example.com">
<input type="password" placeholder="Password">
<input type="tel" placeholder="(123) 456-7890">
<input type="url" placeholder="https://example.com">
<input type="search" placeholder="Search...">

Number inputs Jump to this section

<input type="number" min="0" max="100" step="1">
<input type="range" min="0" max="100" value="50">

Date and time inputs Jump to this section

<input type="date">
<input type="time">
<input type="datetime-local">
<input type="month">
<input type="week">

Selection inputs Jump to this section

<input type="checkbox" id="agree">
<label for="agree">I agree</label>
<input type="radio" name="choice" id="opt1">
<label for="opt1">Option 1</label>

Other inputs Jump to this section

<input type="color" value="#3b82f6">
<input type="file" accept="image/*">

name Jump to this section

Identifies the input when submitting form data. The name becomes the key in the submitted data. Required for form submission.

Use descriptive names that match your backend expectations (e.g., email, user_name, quantity).

<input type="text" name="username">
<!-- Submits as: username=enteredvalue -->

value Jump to this section

Sets the initial or current value of the input. For text inputs, this is the default text. For checkboxes/radios, this is the value sent when checked.

<input type="text" value="Default text">
<input type="checkbox" name="subscribe" value="yes">

placeholder Jump to this section

Displays hint text inside the input when it's empty. Disappears when the user starts typing. Not a replacement for a proper label.

Use for examples or formatting hints, but always provide a <label> for accessibility.

<input type="email" placeholder="you@example.com">
<input type="tel" placeholder="(555) 123-4567">

required Jump to this section

Boolean attribute that makes the field mandatory for form submission. Browsers will display an error message if the field is empty when submitting.

Use on fields that must be filled out. Combine with proper error messaging.

<input type="text" required>

disabled Jump to this section

Boolean attribute that makes the input non-interactive and excludes it from form submission. Typically displayed with reduced opacity.

Use when an input is temporarily unavailable or depends on another selection.

<input type="text" disabled>

readonly Jump to this section

Makes the input non-editable but still focusable and included in form submission. Unlike disabled, the value is still submitted.

Use when you want to display a value that shouldn't be changed but needs to be submitted (e.g., calculated totals, confirmed selections).

<input type="text" value="Total: $100" readonly>

maxlength Jump to this section

Limits the maximum number of characters the user can enter. Browsers prevent typing beyond this limit.

Use to enforce character limits (e.g., tweet length, username constraints).

<input type="text" maxlength="280" placeholder="Max 280 characters">

minlength Jump to this section

Requires a minimum number of characters for validation. Unlike maxlength, this doesn't prevent typing but triggers validation errors on submit.

<input type="password" minlength="8" placeholder="Min 8 characters">

min / max Jump to this section

Sets minimum and maximum values for number, date, and range inputs. Used for validation and UI constraints.

<input type="number" min="1" max="100">
<input type="date" min="2024-01-01" max="2024-12-31">
<input type="range" min="0" max="100" value="50">

step Jump to this section

Controls the increment for number and range inputs. Also affects date/time inputs.

<input type="number" step="0.01" placeholder="Price">
<input type="range" min="0" max="100" step="5">
<input type="time" step="60"> <!-- 1-minute increments -->

pattern Jump to this section

Defines a regular expression the input's value must match for validation. Used with text-based inputs.

Use to enforce specific formats (phone numbers, postal codes, custom IDs).

<input type="text" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" 
       placeholder="123-456-7890" title="Format: XXX-XXX-XXXX">
<input type="text" pattern="[A-Z]{2}[0-9]{4}" 
       placeholder="AB1234" title="2 letters, 4 numbers">

autocomplete Jump to this section

Controls browser autofill behavior. Can enable/disable autocomplete or specify what type of data to suggest.

Values: on, off, name, email, username, new-password, current-password, tel, street-address, postal-code, cc-number, etc.

<input type="email" autocomplete="email">
<input type="password" autocomplete="new-password">
<input type="text" autocomplete="off">

autofocus Jump to this section

Automatically focuses this input when the page loads. Only one element per page should have this attribute.

Use sparingly on search pages or single-purpose forms.

<input type="search" autofocus placeholder="Search...">

multiple Jump to this section

Allows multiple values for email and file inputs. For files, users can select multiple files at once.

<input type="email" multiple placeholder="email1@example.com, email2@example.com">
<input type="file" multiple accept="image/*">

accept Jump to this section

Specifies which file types the file input should accept. Uses MIME types or file extensions.

<input type="file" accept="image/*">
<input type="file" accept=".pdf,.doc,.docx">
<input type="file" accept="image/png,image/jpeg">

capture Jump to this section

For file inputs on mobile devices, specifies which camera to use (user-facing or environment-facing).

Values: user (front camera), environment (back camera)

<input type="file" accept="image/*" capture="user">
<input type="file" accept="image/*" capture="environment">

size Jump to this section

Sets the visible width of the input in characters. Modern CSS is usually preferred for sizing.

<input type="text" size="30">

list Jump to this section

References a <datalist> element by its id to provide autocomplete suggestions.

<input type="text" list="browsers" placeholder="Choose a browser">
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Safari">
  <option value="Edge">
</datalist>

form Jump to this section

Associates the input with a form element by its id, even when the input is outside the form in the DOM.

<form id="signup-form">
  <!-- other inputs -->
</form>

<input type="email" form="signup-form" name="email">

inputmode Jump to this section

Hints which virtual keyboard to display on mobile devices.

Values: none, text, decimal, numeric, tel, search, email, url

<input type="text" inputmode="numeric" placeholder="Enter code">
<input type="text" inputmode="email">

enterkeyhint Jump to this section

Customizes the enter key label on virtual keyboards.

Values: enter, done, go, next, previous, search, send

<input type="search" enterkeyhint="search">
<input type="email" enterkeyhint="next">

spellcheck Jump to this section

Controls whether the browser should check spelling. Can be true or false.

<input type="text" spellcheck="true">
<input type="text" spellcheck="false">

checked Jump to this section

Boolean attribute for checkboxes and radio buttons. Sets the initial checked state.

<input type="checkbox" checked>
<input type="radio" name="option" value="1" checked>

aria-label Jump to this section

Provides an accessible label when a visible <label> element isn't present or practical.

<input type="search" aria-label="Search the website">

aria-describedby Jump to this section

References additional descriptive text by its id to provide context or instructions.

<input type="password" id="pwd" aria-describedby="pwd-help">
<small id="pwd-help">Must be at least 8 characters</small>

aria-invalid Jump to this section

Indicates whether the input has a validation error. Should be updated dynamically with JavaScript.

<input type="email" aria-invalid="true" aria-describedby="email-error">
<span id="email-error">Please enter a valid email address</span>

aria-required Jump to this section

Indicates that the field is required. Use in addition to the required attribute for better accessibility.

<input type="text" required aria-required="true">

data-* attributes Jump to this section

Custom attributes for storing application-specific data on the input element.

<input type="text" data-validation-rule="email" data-field-id="user_email">

<script>
  const input = document.querySelector('input');
  const rule = input.dataset.validationRule; // "email"
  const fieldId = input.dataset.fieldId; // "user_email"
</script>

id Jump to this section

Unique identifier for the input. Essential for linking with <label> elements and JavaScript selection.

<label for="username">Username:</label>
<input type="text" id="username" name="username">

class Jump to this section

Assigns CSS class names for styling or JavaScript selection.

<input type="text" class="form-control input-lg">

title Jump to this section

Provides a tooltip on hover. Not accessible to keyboard-only users, so don't rely on it for critical information.

<input type="text" title="Enter your full legal name">

tabindex Jump to this section

Controls keyboard focus order. Inputs are focusable by default, so rarely needed.

<input type="text" tabindex="1">
<input type="text" tabindex="2">
<input type="text" tabindex="-1"> <!-- Removed from tab order -->

Styling basics Jump to this section

Inputs are inline-level elements by default. Style with padding, border, background, and font properties. Ensure sufficient contrast and clear focus indicators.

Examples Jump to this section

Basic text input Jump to this section

.input-basic {
    padding: 10px 14px;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    font-size: 15px;
    width: 100%;
}

Underline input Jump to this section

.input-underline {
    padding: 8px 0;
    background: transparent;
    border: none;
    border-bottom: 1px solid #d1d5db;
    font-size: 15px;
}

Pill input (rounded) Jump to this section

.input-pill {
    padding: 10px 20px;
    border: 1px solid #d1d5db;
    border-radius: 50px;
    font-size: 15px;
}

With icon (search) Jump to this section

🔍
<div class="wrapper-div">
<input class="input-with-icon" placeholder="Search...">
<span class="icon">🔍</span>
</div>
.input-with-icon {
    padding-left: 40px;
}
.icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: #9ca3af;
}
.wrapper-div {
    position:relative;
    width:200px;
}

Size variants Jump to this section



.input-small {
    padding: 6px 10px;
    font-size: 13px;
    border-radius: 4px;
}
.input-medium {
    padding: 10px 14px;
    font-size: 15px;
    border-radius: 6px;
}
.input-large {
    padding: 14px 18px;
    font-size: 17px;
    border-radius: 8px;
}

Disabled state Jump to this section

.input-basic:disabled {
    background: #f3f4f6;
    border-color: #e5e7eb;
    color: #9ca3af;
    cursor: not-allowed;
}

Error state Jump to this section

.input-error {
    border: 2px solid #dc2626;
    background: #fef2f2;
}

Success state Jump to this section

.input-success {
    border: 2px solid #16a34a;
    background: #f0fdf4;
}

Custom checkbox Jump to this section

input[type="checkbox"] {
    appearance: none;
    width: 20px;
    height: 20px;
    border: 2px solid #d1d5db;
    border-radius: 4px;
    cursor: pointer;
}
input[type="checkbox"]:checked {
    background: #3b82f6;
    border-color: #3b82f6;
}

Toggle switch Jump to this section

.toggle-switch {
    appearance: none;
    width: 44px;
    height: 24px;
    background: #d1d5db;
    border-radius: 12px;
    position: relative;
    cursor: pointer;
    transition: background 0.3s;
}
.toggle-switch:checked {
    background: #3b82f6;
}
.toggle-switch::after {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    width: 20px;
    height: 20px;
    background: white;
    border-radius: 50%;
    transition: transform 0.3s;
}
.toggle-switch:checked::after {
    transform: translateX(20px);
}

Focus states Jump to this section

Always provide clear focus indicators for accessibility. Use :focus or :focus-visible pseudo-classes.

Blue outline on focus Jump to this section

.input-basic {
    border: 1px solid #d1d5db;
    transition: all 0.2s;
}
.input-basic:focus {
    border-color: #3b82f6;
    outline: 2px solid #93c5fd;
    outline-offset: 2px;
}

Glow effect on focus Jump to this section

.input-glow {
    border: 1px solid #d1d5db;
    transition: all 0.2s;
}
.input-glow:focus {
    border-color: #8b5cf6;
    box-shadow: 0 0 0 8px rgba(139, 92, 246, 0.1);
    outline: none;
}

Placeholder styling Jump to this section

input::placeholder {
    color: #9ca3af;
    font-style: italic;
    opacity: 0.7;
}

JavaScript patterns Jump to this section

Inputs are central to form interactions and data collection. Use event listeners to validate, transform, and respond to user input in real-time.

Getting and setting values Jump to this section

Access the current value of an input using the value property.

const input = document.getElementById('js-value');
// Get the current value
const value = input.value;
// Set a new value
input.value = 'New text';
// Clear the input
input.value = '';

Listen for input changes Jump to this section

Use the input event to respond to every keystroke or change in real-time. Use change event for when the user finishes editing (on blur).

Character count: 0
const input = document.getElementById('js-input-event');
const output = document.getElementById('js-input-output');
// Fires on every keystroke
input.addEventListener('input', (e) => {
    output.textContent = `Character count: ${e.target.value.length}`;
});
// Fires when input loses focus (if value changed)
input.addEventListener('change', (e) => {
    console.log('Final value:', e.target.value);
});

Real-time validation Jump to this section

Validate input as the user types and provide immediate feedback.

const emailInput = document.getElementById('js-validate');
const message = document.getElementById('js-validate-msg');
emailInput.addEventListener('input', (e) => {
    const value = e.target.value;
    if (value === '') {
        message.textContent = '';
        emailInput.style.borderColor = '#d1d5db';
    } else if (value.includes('@') && value.includes('.')) {
        message.textContent = '✓ Valid email';
        message.style.color = '#16a34a';
        emailInput.style.borderColor = '#16a34a';
    } else {
        message.textContent = '✗ Invalid email format';
        message.style.color = '#dc2626';
        emailInput.style.borderColor = '#dc2626';
    }
});

Format input (phone number) Jump to this section

Automatically format user input into a specific pattern as they type.

const phoneInput = document.getElementById('js-phone');
phoneInput.addEventListener('input', (e) => {
    let value = e.target.value.replace(/\D/g, ''); // Remove non-digits
    if (value.length > 10) {
        value = value.slice(0, 10);
    }
    // Format as (XXX) XXX-XXXX
    if (value.length >= 6) {
        value = `(${value.slice(0,3)}) ${value.slice(3,6)}-${value.slice(6)}`;
    } else if (value.length >= 3) {
        value = `(${value.slice(0,3)}) ${value.slice(3)}`;
    } else if (value.length > 0) {
        value = `(${value}`;
    }
    e.target.value = value;
});

Show/hide password toggle Jump to this section

Allow users to toggle password visibility for easier verification.

const passwordInput = document.getElementById('js-password');
const toggleBtn = document.getElementById('js-password-toggle');
toggleBtn.addEventListener('click', () => {
    if (passwordInput.type === 'password') {
        passwordInput.type = 'text';
        toggleBtn.textContent = '🔒'; // Hide
    } else {
        passwordInput.type = 'password';
        toggleBtn.textContent = '🔓'; // Show
    }
});

Character counter with limit Jump to this section

Display remaining characters for inputs with a maximum length.

0 / 100
const textarea = document.getElementById('js-counter');
const counter = document.getElementById('js-counter-display');
const maxLength = 100;
textarea.addEventListener('input', (e) => {
    const length = e.target.value.length;
    counter.textContent = `${length} / ${maxLength}`;
    // Change color when near limit
    if (length > maxLength * 0.9) {
        counter.style.color = '#dc2626';
    } else if (length > maxLength * 0.7) {
        counter.style.color = '#f59e0b';
    } else {
        counter.style.color = '#6b7280';
    }
});

Auto-resize textarea Jump to this section

Automatically expand a textarea as the user types more content.

const textarea = document.getElementById('js-autoresize');
textarea.addEventListener('input', (e) => {
    // Reset height to auto to get proper scrollHeight
    e.target.style.height = 'auto';
    // Set height to scrollHeight
    e.target.style.height = e.target.scrollHeight + 'px';
});

File input preview Jump to this section

Display a preview of selected images before upload.

const fileInput = document.getElementById('js-file');
const preview = document.getElementById('js-file-preview');
fileInput.addEventListener('change', (e) => {
    const file = e.target.files[0];
    if (file && file.type.startsWith('image/')) {
        const reader = new FileReader();
        reader.onload = (event) => {

preview.innerHTML = <img src="${event.target.result}" style="max-width:200px;border-radius:6px;">; }; reader.readAsDataURL(file); } else { preview.innerHTML = '

Please select an image file

'; } });

Checkbox select all Jump to this section

Implement "select all" functionality for multiple checkboxes.




const selectAll = document.getElementById('js-select-all');
const checkboxes = document.querySelectorAll('.js-item-checkbox');
selectAll.addEventListener('change', (e) => {
    checkboxes.forEach(checkbox => {
        checkbox.checked = e.target.checked;
    });
});
// Update select-all state when individual boxes change
checkboxes.forEach(checkbox => {
    checkbox.addEventListener('change', () => {
        const allChecked = Array.from(checkboxes).every(cb => cb.checked);
        const someChecked = Array.from(checkboxes).some(cb => cb.checked);
        selectAll.checked = allChecked;
        selectAll.indeterminate = someChecked && !allChecked;
    });
});

Number input with custom controls Jump to this section

Create custom increment/decrement buttons for better UX.

const numberInput = document.getElementById('js-number');
const decrementBtn = document.getElementById('decrement');
const incrementBtn = document.getElementById('increment');
decrementBtn.addEventListener('click', () => {
    const current = parseInt(numberInput.value) || 0;
    const min = parseInt(numberInput.min) || -Infinity;
    numberInput.value = Math.max(min, current - 1);
});
incrementBtn.addEventListener('click', () => {
    const current = parseInt(numberInput.value) || 0;
    const max = parseInt(numberInput.max) || Infinity;
    numberInput.value = Math.min(max, current + 1);
});

Search with debounce Jump to this section

Delay search execution until user stops typing to reduce API calls.

const searchInput = document.getElementById('js-search');
const status = document.getElementById('js-search-status');
let timeout;
searchInput.addEventListener('input', (e) => {
    const query = e.target.value;
    // Clear previous timeout
    clearTimeout(timeout);
    if (query.length < 2) {
        status.textContent = '';
        return;
    }
    status.textContent = 'Typing...';
    // Wait 500ms after user stops typing
    timeout = setTimeout(() => {
        status.textContent = `Searching for "${query}"...`;
        // Perform search API call here
        setTimeout(() => {
            status.textContent = `Found results for "${query}"`;
        }, 500);
    }, 500);
});

Range slider with value display Jump to this section

Show the current value of a range input dynamically.

50
const rangeInput = document.getElementById('js-range');
const valueDisplay = document.getElementById('js-range-value');
rangeInput.addEventListener('input', (e) => {
    valueDisplay.textContent = e.target.value;
});

Custom validation message Jump to this section

Provide custom validation messages instead of browser defaults.

const form = document.getElementById('js-custom-validation');
const usernameInput = document.getElementById('js-username');
const errorMsg = document.getElementById('js-username-error');
usernameInput.addEventListener('input', () => {
    // Clear error on input
    errorMsg.textContent = '';
    usernameInput.style.borderColor = '#d1d5db';
});
form.addEventListener('submit', (e) => {
    e.preventDefault();
    const username = usernameInput.value.trim();
    if (username === '') {
        errorMsg.textContent = 'Username is required';
        usernameInput.style.borderColor = '#dc2626';
        usernameInput.focus();
    } else if (username.length < 3) {
        errorMsg.textContent = 'Username must be at least 3 characters';
        usernameInput.style.borderColor = '#dc2626';
        usernameInput.focus();
    } else {
        errorMsg.textContent = '';
        alert('Form submitted!');
    }
});

Copy to clipboard Jump to this section

Copy input value to clipboard when clicking a button.

const copyInput = document.getElementById('js-copy');
const copyBtn = document.getElementById('copy-btn');
copyBtn.addEventListener('click', async () => {
    try {
        await navigator.clipboard.writeText(copyInput.value);
        copyBtn.textContent = '✓ Copied';
        setTimeout(() => {
            copyBtn.textContent = 'Copy';
        }, 1500);
    } catch (err) {
        console.error('Failed to copy:', err);
    }
});