Understanding the CSS :read-only Pseudo-Class

The CSS :read-only pseudo-class represents any element that cannot be edited by the user, such as an input field with the HTML readonly attribute applied. This guide explains what the :read-only pseudo-class is, how it identifies non-editable form controls, how it differs from the :disabled state, and how to use it effectively in your stylesheets to improve user experience.

What is the :read-only Pseudo-Class?

The :read-only pseudo-class is a CSS selector that targets elements whose content cannot be modified by the user. While the browser considers any standard, non-editable HTML element (such as <p>, <div>, or <span>) as technically read-only, this pseudo-class is most frequently applied to form elements like <input> and <textarea>.

Its direct counterpart is the :read-write pseudo-class, which targets any element that the user can actively edit, including standard form inputs and elements with the contenteditable attribute set.

How :read-only Targets Non-Editable Inputs

In HTML, form inputs become non-editable when the readonly boolean attribute is added. The :read-only pseudo-class queries this condition and applies styles specifically to those locked controls.

<!-- Targets this element -->
<input type="text" value="System Generated ID" readonly>

<!-- Does not target this element -->
<input type="text" value="Editable Name">
input:read-only {
  background-color: #f3f4f6;
  border-color: #d1d5db;
  color: #6b7280;
  cursor: default;
}

By scoping the selector with input or textarea, you ensure that generic page elements like headings and paragraphs are not unintentionally styled.

:read-only vs. :disabled

Although both states prevent the user from editing an input's value, they serve distinct functional and semantic purposes:

  • :read-only inputs: The user cannot change the text, but the field can still receive focus, allow text selection, and trigger click events. Most importantly, values in a read-only field are submitted with the form data.
  • :disabled inputs: The field is completely deactivated. It cannot receive focus, text cannot be selected, and its data is excluded from form submissions.

Because of these functional differences, read-only inputs should visually communicate that the text is locked without making the element appear entirely dead or inactive.

Which Elements Match :read-only?

  1. Text controls with readonly: Form fields such as <input type="text" readonly> or <textarea readonly>.
  2. Standard non-editable elements: Elements like <div>, <section>, or <article> that do not have contenteditable="true".
  3. Form controls that do not support editing: Elements such as buttons or range sliders may not match :read-only in the same way depending on browser implementations, as the attribute does not apply to non-text inputs.

Practical Example

A common use case involves forms where specific user data is pre-populated and locked, while remaining editable fields require attention.

/* Style editable fields */
input:read-write {
  border: 2px solid #2563eb;
  background-color: #ffffff;
}

/* Style locked, read-only fields */
input:read-only {
  border: 1px solid #9ca3af;
  background-color: #f9fafb;
  color: #4b5563;
  user-select: all; /* Allows easy copying of the value */
}

This styling informs the user immediately which fields require interaction and which are provided strictly for viewing or copying data.