readonly

Makes form controls non-editable while keeping them focusable and included in form submission. The polite alternative to disabled.

Overview

The readonly attribute makes a form control non-editable while keeping it focusable, tabbable, and included in form submission. The user can see the value, select and copy the text, and tab through it — but cannot change it.

Use readonly when a value must be submitted with the form but should not be modified by the user. Common examples: order IDs, calculated totals, server-assigned values, and confirmation screens.

Applies to: <input> (text-like types only), <textarea>

Values

AttributeFocusableEditableSubmittedWorks On
readonlyYesNoYesText inputs, textarea
disabledNoNoNoAll form controls

The key difference: readonly keeps the value in the form payload. disabled removes it entirely.

Readonly vs Disabled

These two attributes look similar but behave very differently. Choosing the wrong one is a common source of bugs.

Behaviorreadonlydisabled
User can editNoNo
User can focus/tabYesNo
User can select/copy textYesVaries by browser
Value submitted with formYesNo
Constraint validation runsNoNo
Visual appearanceSubtle (your CSS)Grayed out

Form Submission

This is the primary reason to choose readonly over disabled. Readonly fields are included in FormData and submitted to the server.

Elements That Ignore readonly

The readonly attribute only works on text-like inputs and <textarea>. It has no effect on:

  • <select> — the user can still change the selection
  • <input type="checkbox"> — the user can still toggle it
  • <input type="radio"> — the user can still change the selection
  • <input type="range"> — the slider is still draggable
  • <input type="color"> — the picker still opens

For these elements, use disabled paired with a <input type="hidden"> to carry the value, or use JavaScript to prevent changes.

Styling

Use the :read-only and :read-write pseudo-classes to style readonly fields distinctly from editable ones.

Note: The :read-only pseudo-class also matches elements that are not editable by nature (like <p> or <div>). For precise targeting, combine it with an element selector: input:read-only.

JavaScript API

The readOnly property (camelCase) reflects the attribute.