Read Only

Master the HTML readonly attribute, CSS :read-only pseudo-class, and JavaScript techniques for creating read-only form controls that balance user experience with data integrity.

What is Read Only?

In modern web development, controlling user input is fundamental to building interactive and secure forms. The readonly attribute and :read-only CSS pseudo-class provide developers with powerful tools to create read-only form fields that display information without allowing modification.

Understanding these mechanisms is essential for creating professional web applications that balance user experience with data integrity. This guide explores the HTML readonly attribute, the CSS :read-only pseudo-class, and the JavaScript techniques for manipulating read-only state.

The read-only state represents a form control that displays a value but prevents user modification. Unlike disabled controls, read-only fields remain focusable and participate in form submission, making them ideal for displaying information that users should see but not edit.

HTML Readonly Attribute

The readonly attribute is a boolean attribute that can only be applied to specific HTML elements. According to the WHATWG HTML specification, the readonly attribute is only permitted on text-based form controls.

Supported Input Types

The readonly attribute works with the following <input> types:

  • text - Standard single-line text input
  • search - Search input with search-specific behavior
  • tel - Telephone number input
  • url - URL input
  • email - Email address input
  • password - Password input (masked characters)
  • date - Date picker input
  • month - Month picker input
  • week - Week picker input
  • time - Time input
  • datetime-local - Date and time input
  • number - Numeric input with spinner controls

The <textarea> element also supports the readonly attribute.

Elements That Cannot Be Readonly

Certain form elements do not support the readonly attribute:

  • <select> elements
  • Checkbox and radio inputs
  • File upload controls
  • Range and color pickers
  • Button elements

Syntax Examples

The readonly attribute is a boolean attribute, meaning it requires no value. Simply including the attribute in the HTML tag applies the read-only state. The attribute can also be written with an explicit value for XHTML compatibility.

<!-- Basic readonly input -->
<input type="text" id="username" value="johndoe" readonly>

<!-- Readonly email input -->
<input type="email" id="email" value="[email protected]" readonly>

<!-- Readonly date input -->
<input type="date" id="appointment" value="2025-01-15" readonly>

<!-- Readonly textarea -->
<textarea id="bio" readonly>
 This is read-only content.
</textarea>

<!-- XHTML-compatible syntax -->
<input type="text" readonly="readonly">
Basic Readonly Syntax
1<!-- Basic readonly input -->2<input type="text" id="username" value="johndoe" readonly>3 4<!-- Readonly email input -->5<input type="email" id="email" value="[email protected]" readonly>6 7<!-- Readonly date input -->8<input type="date" id="appointment" value="2025-01-15" readonly>9 10<!-- Readonly textarea -->11<textarea id="bio" readonly>12 This is read-only content.13</textarea>14 15<!-- XHTML-compatible syntax -->16<input type="text" readonly="readonly">

Constraint Validation and Form Submission

When the readonly attribute is present on an input element, the element does not participate in constraint validation. This means that validation constraints such as required, minlength, maxlength, and pattern matching are effectively ignored for readonly fields according to MDN's documentation on the readonly attribute.

The rationale is straightforward: if users cannot modify the field, requiring them to provide valid input is impossible. Therefore, combining readonly with required has no practical effect and should be avoided.

Read-only form controls behave identically to editable controls during form submission. Their values are included in the submitted data, allowing server-side processing to access the readonly field's contents. This behavior distinguishes readonly from disabled controls, which are explicitly excluded from form submission.

For robust form validation strategies, always implement server-side checks regardless of client-side readonly states.

CSS :read-only Pseudo-class

The :read-only CSS pseudo-class selects elements that are not editable by the user. This includes elements with the HTML readonly attribute AND elements that are inherently non-editable.

The :read-only pseudo-class is essentially equivalent to :not(:read-write), meaning it matches any element that the :read-write pseudo-class does not match.

Elements Matched

The CSS :read-only pseudo-class has broader scope than the HTML readonly attribute. It matches:

  • <input> and <textarea> elements with the readonly attribute
  • <input type="checkbox"> and <input type="radio"> - Always read-only by nature
  • <input type="file"> - File upload controls
  • <input type="hidden"> - Hidden inputs
  • <select> elements - Dropdown selects
  • <button> elements - Button elements
  • All non-form elements (div, p, span, etc.) - Unless they have contenteditable="true"

Styling Read-only Elements

Since browsers do not apply default styling to read-only form controls, developers must implement their own visual indicators. The CSS :read-only pseudo-class provides a standardized way to target these elements with consistent styling approaches that communicate the readonly state clearly to users.

Implementing proper CSS styling for readonly states helps users understand which fields are interactive and which are for display only.

Styling Read-only Elements
1/* Style all read-only inputs */2input:read-only,3textarea:read-only {4 background-color: #f5f5f5;5 border: 1px solid #ddd;6 color: #666;7 cursor: not-allowed;8}9 10/* Remove default focus styles */11input:read-only:focus,12textarea:read-only:focus {13 outline: none;14 box-shadow: none;15}16 17/* Alternative styling approach */18.form-field:read-only {19 background-color: transparent;20 border: none;21 border-bottom: 1px dashed #ccc;22 padding: 4px 0;23}24 25/* Visual indicator with icon support */26.readonly-indicator:read-only {27 background-color: #f8f9fa;28 border-left: 3px solid #6c757d;29 padding-left: 12px;30 color: #495057;31}

JavaScript and Readonly State

JavaScript provides two primary methods for manipulating readonly state: setting the DOM property and setting the HTML attribute.

Setting Readonly State

The distinction between setting the property and setting the attribute is important. Setting the property (element.readOnly = true) is generally more efficient and immediate. The attribute approach is useful when you need to serialize the state or work with frameworks that track attribute changes.

Checking Readonly State

// Check via property (recommended)
if (input.readOnly) {
 console.log('Field is read-only');
}

// Check via attribute
if (input.hasAttribute('readonly')) {
 console.log('Field has readonly attribute');
}

// Toggle readonly state
function toggleReadonly(element) {
 element.readOnly = !element.readOnly;
 updateVisualState(element);
}

Common Patterns

Dynamic Form Scenarios: Toggle readonly state based on form progression, such as locking fields after form submission or multi-step form wizards.

Profile Editor: Allow users to switch between view and edit modes with appropriate visual feedback and smooth transitions between states.

Generated Values: Display values computed or set programmatically that users should not modify, such as auto-generated coupon codes or system timestamps.

Performance Considerations

For forms with many readonly fields, batch updates to minimize layout reflows. Setting readOnly on large numbers of inputs can trigger layout recalculations, so consider using document fragments or batch processing techniques for optimal performance.

These JavaScript techniques are essential for building dynamic web applications with responsive form interactions.

Setting and Checking Readonly
1// Method 1: Set the property directly2const input = document.getElementById('myInput');3input.readOnly = true;4 5// Method 2: Set the attribute6input.setAttribute('readonly', '');7 8// Check via property (recommended)9if (input.readOnly) {10 console.log('Field is read-only');11}12 13// Remove readonly14input.readOnly = false;15input.removeAttribute('readonly');16 17// Toggle readonly state18function toggleReadonly(element) {19 element.readOnly = !element.readOnly;20 updateVisualState(element);21}
Form Controller Pattern
1class FormController {2 constructor(formId) {3 this.form = document.getElementById(formId);4 this.setupFieldListeners();5 }6 7 setupFieldListeners() {8 const inputs = this.form.querySelectorAll('input, textarea');9 inputs.forEach(input => {10 input.addEventListener('focus', () => {11 if (input.readOnly) {12 input.blur();13 }14 });15 });16 }17 18 lockSubmittedFields() {19 const inputs = this.form.querySelectorAll('input, textarea');20 inputs.forEach(input => {21 input.readOnly = true;22 });23 }24 25 // Batch update for performance26 setFieldsReadonly(selector, readonly) {27 const inputs = document.querySelectorAll(selector);28 const fragment = document.createDocumentFragment();29 inputs.forEach(input => {30 fragment.appendChild(input);31 input.readOnly = readonly;32 });33 document.body.appendChild(fragment);34 }35}

Readonly vs Disabled: Key Differences

Understanding the distinction between readonly and disabled is crucial for proper form implementation:

Behaviorreadonlydisabled
User can editNoNo
Form submissionYesNo
Focusable via keyboardYesNo
Can be re-enabledYesYes
Default stylingNoneGrayed out

When to Use Each

Use readonly when:

  • Displaying information for review without modification
  • The value is essential for form submission
  • Users need to copy content from the field
  • The field should remain focusable for accessibility

Use disabled when:

  • The field is temporarily unavailable
  • The value should not be submitted
  • Visual indication of unavailability is needed
  • The field will be enabled based on other interactions

Security Considerations

Neither readonly nor disabled provides security. Users can modify these attributes using browser developer tools, potentially bypassing intended restrictions. Any security-critical validation must occur on the server-side, not relying on client-side readonly or disabled states as documented in research by Adrian Roselli.

When building secure web applications, always implement server-side validation regardless of client-side state.

Readonly vs Disabled Comparison
Behaviorreadonlydisabled
User can editNoNo
Participates in form submissionYesNo
Focusable via keyboardYesNo
Can be re-enabled via JSYesYes
Default browser stylingNoneGrayed out
Screen reader announcementVariesVaries
Constraint validationExcludedExcluded

Accessibility Considerations

Screen Reader Behavior

Screen reader support for readonly states varies significantly across combinations of browsers and screen readers. Research shows inconsistent announcements:

  • JAWS with Chrome: Announces readonly for text, email, number, password, search, telephone, and URL inputs
  • NVDA with Firefox: Announces readonly for text, email, month, password, search, telephone, URL, and week inputs
  • VoiceOver macOS: Announces as "selectable" rather than read-only
  • TalkBack with Chrome: Announces as "disabled" rather than read-only according to research by Adrian Roselli

This inconsistency means developers cannot rely on screen readers to consistently communicate readonly state to users.

Styling Challenges

The lack of default browser styling for readonly controls creates challenges:

  1. No visual indication - Users may not realize a field is readonly without trying to edit it
  2. Inconsistent browser behavior - Firefox applies gray text to date/time inputs; Chrome on Android extends this to month/week inputs as documented by Adrian Roselli
  3. Contrast requirements - WCAG guidelines mandate sufficient contrast for read-only text

Best Practices

  • Provide clear visual indicators (borders, colors, icons) to communicate readonly state
  • Consider alternative patterns for complex readonly scenarios, such as displaying values as plain text
  • Use ARIA judiciously with aria-readonly="true" can help but may not be consistently announced
  • Test with actual assistive technology combinations your users actually employ

Security Note

Neither readonly nor disabled provides security. Users can modify these attributes using browser developer tools. Server-side validation is essential regardless of client-side state.

Creating accessible web experiences requires careful attention to how readonly states are communicated to all users.

Use Cases and Examples

Confirmation Forms

Readonly fields excel in scenarios where users review and confirm information before final submission. Display shipping details, order summaries, or profile information that users can see but not modify.

Profile Display Modes

Toggle between edit and view modes, allowing users to switch between readonly display and editable fields with appropriate visual feedback and smooth transitions.

Generated Values

Display values that are computed or set programmatically, such as system-generated IDs, timestamps, calculated totals, or auto-generated coupon codes that users should not modify directly.

Order Summary Displays

Show order details, pricing breakdowns, and total calculations in readonly fields during checkout review steps to prevent accidental modifications while maintaining clear visibility of all values.

These patterns are essential for building professional web forms that guide users through complex interactions.

Best Practices Summary

Do's

  • Use readonly for values users should review but not modify
  • Apply clear visual styling to indicate readonly state
  • Test with real assistive technology combinations
  • Implement server-side validation regardless of client-side state
  • Keep readonly fields focusable for accessibility navigation

Don'ts

  • Rely on readonly for security-critical data
  • Combine readonly with required (it's meaningless)
  • Assume consistent screen reader behavior
  • Forget to test keyboard navigation
  • Use readonly as the only form of data protection

Common Patterns

  1. Review and Confirm: Display values in readonly fields during review before submission
  2. Read-Only Display: Show computed or system-generated values
  3. Toggle Edit: Allow switching between readonly view and editable mode with appropriate visual feedback

Browser Compatibility

The readonly attribute and :read-only pseudo-class have excellent browser support across all modern browsers. Minor differences exist in styling date/time inputs in readonly state, particularly between Firefox and Chrome on different platforms.

Key Takeaways

HTML Readonly Attribute

Only works on text inputs and textarea. Prevents user editing while maintaining focusability and form submission.

CSS :read-only Pseudo-class

Broader scope than HTML attribute. Matches inherently non-editable elements including checkboxes and selects.

JavaScript Control

Toggle readonly state dynamically based on form progression or user interactions using property or attribute methods.

Accessibility First

Provide visual indicators since browser defaults are minimal. Test with actual assistive technology combinations.

Frequently Asked Questions

Ready to Build Better Web Forms?

Our team specializes in creating accessible, performant web applications with modern form patterns that prioritize user experience and data integrity.