CSS :read-only Pseudo-Class
The CSS :read-only pseudo-class selects elements that are not user-editable. It is commonly used to style <input> and <textarea> elements with the readonly attribute, but it also matches elements that are not editable by default.
:read-only Syntax
selector:read-only {
property: value;
}
The :read-only pseudo-class matches elements that are not user-editable.
Basic Example
input:read-only {
background-color: #f2f2f2;
}
Applies a light gray background to input elements that are read-only, including inputs that are not editable by their nature.
Textarea Example
textarea:read-only {
border-color: #999;
}
Changes the border color of a read-only textarea.
Class Selector
.form-field:read-only {
color: #555;
}
Matches a non-editable element with the form-field class. The class itself does not determine whether the element is editable.
No Parentheses
The :read-only pseudo-class does not accept arguments and is written without parentheses.
How :read-only Works
The browser determines whether an element is user-editable. The :read-only pseudo-class matches elements that cannot be edited through normal user interaction.
HTML Example
<label for="reference-code">Reference Code:</label>
<input type="text" id="reference-code" value="CSS-104" readonly>
CSS Example
input:read-only {
background-color: #f2f2f2;
border: 1px solid #999;
}
The input receives the read-only styling because the user cannot directly edit its value.
Editable Elements
<input type="text" value="Editable text">
A normal editable text input does not match :read-only. It matches :read-write instead.
Automatic State Changes
When a supported control becomes read-only or editable, the browser updates pseudo-class matching automatically.
Broader Than Form Controls
Unlike the HTML readonly attribute, the CSS pseudo-class is not restricted to text-entry form controls. Ordinary non-editable elements can also match.
The readonly Attribute
The HTML readonly boolean attribute prevents users from directly changing the value of supported text-entry form controls.
HTML Example
<input type="text" value="HTML Reference" readonly>
The input displays its value but does not allow the user to edit it.
Boolean Attribute
<input type="text" value="CSS Reference" readonly>
The presence of the readonly attribute activates the read-only state for supported controls. Writing readonly="false" does not disable it.
Attribute Selector
input[readonly] {
background-color: #f2f2f2;
}
The attribute selector matches inputs with the readonly attribute present.
Pseudo-Class Selector
input:read-only {
background-color: #f2f2f2;
}
The pseudo-class matches based on the element's editability rather than simply checking for an attribute.
Important Difference
An input type that does not support readonly, such as a checkbox, can still match :read-only because it is not a text-editable control.
Read-Only Input Elements
The readonly attribute is supported by several text-entry input types, including text, search, URL, telephone, email, password, date, time, number, and related date/time types.
Text Input
<input type="text" value="Page Title" readonly>
Displays a text value that the user cannot edit.
Email Input
<input type="email" value="info@example.com" readonly>
Displays a read-only email address.
Number Input
<input type="number" value="25" readonly>
Displays a numeric value that cannot be directly changed by the user.
Date Input
<input type="date" value="2026-11-04" readonly>
Displays a date value without allowing the user to change it through the control.
CSS Example
input:read-only {
background-color: #f2f2f2;
color: #555;
}
Styles read-only inputs and other input types that are not user-editable.
Targeting Only readonly Inputs
input[readonly]:read-only {
background-color: #f2f2f2;
}
Use the attribute selector together with the pseudo-class when the intended target is specifically an input with the readonly attribute.
Read-Only <textarea> Elements
The <textarea> element supports the readonly attribute and matches :read-only when editing is prevented.
HTML Example
<label for="terms">Terms:</label>
<textarea id="terms" rows="4" readonly>These terms are provided for reference.</textarea>
CSS Example
textarea:read-only {
background-color: #f2f2f2;
border: 1px solid #999;
color: #555;
}
Applies a gray background, border, and text color to the read-only textarea.
Text Selection
Users can generally select and copy text from a read-only textarea even though they cannot edit its contents.
Scrolling
A read-only textarea can still be scrolled when its content exceeds the visible area.
Read-Only vs. Disabled
A read-only textarea can normally receive focus and participate in form submission, unlike a disabled textarea.
Contenteditable Elements
The :read-only pseudo-class also relates to the editability of ordinary HTML elements.
Editable Content
<div contenteditable="true">
Edit this text.
</div>
The editable div matches :read-write because the user can modify its content.
Non-Editable Content
<div contenteditable="false">
This text is not editable.
</div>
The div matches :read-only when it is not user-editable.
CSS Example
div:read-only {
background-color: #f2f2f2;
}
div:read-write {
background-color: #eaf6fc;
}
Applies different backgrounds to non-editable and editable div elements.
Inherited Editability
The contenteditable attribute is enumerated, and editability can be inherited from an ancestor. An element without its own contenteditable attribute may still be editable.
Ordinary Page Content
Most ordinary page elements are not editable by default and can match :read-only. Use a more specific selector when styling form controls.
Read-Only vs. Disabled
The readonly and disabled attributes serve different purposes and affect form behavior differently.
Comparison
| Behavior | Read-Only | Disabled |
|---|---|---|
| User can edit the value | No | No |
| Can normally receive focus | Yes | No |
| Included in form submission | Yes, if otherwise successful | No |
| Participates in constraint validation | No | No |
| Text can generally be selected | Yes | Depends on the control |
| HTML attribute | readonly | disabled |
HTML Example
<input type="text" value="Read-only value" readonly>
<input type="text" value="Disabled value" disabled>
CSS Example
input[readonly] {
background-color: #f2f2f2;
}
input:disabled {
background-color: #ddd;
opacity: 0.6;
}
Uses separate styles to distinguish read-only inputs from disabled inputs.
Important Selector Difference
A disabled text input also matches :read-only because it is not user-editable. Use [readonly] when you specifically need to identify controls with the HTML attribute.
Form Submission and Validation
Read-only controls behave differently from editable controls during form submission and constraint validation.
Form Submission
<form action="/process.php" method="post">
<label for="order-code">Order Code:</label>
<input type="text" id="order-code" name="order_code" value="ORD-104" readonly>
<button type="submit">Submit</button>
</form>
The read-only input's value is included in the submitted form data because it has a name and is not disabled.
Constraint Validation
Read-only form controls do not participate in constraint validation. The required attribute should not be used with readonly on the same supported input or textarea.
Read-Only Does Not Mean Secure
Read-only values can still be modified using developer tools or scripts. Server-side code must validate submitted values rather than assuming the readonly attribute prevents changes.
Disabled Controls
Disabled controls are excluded from form submission. Use disabled when the value should not be submitted as a successful form control.
Styling Submitted Values
form input[readonly]:read-only {
background-color: #f2f2f2;
color: #555;
}
Provides a distinct appearance for read-only values displayed within a form.
JavaScript and Read-Only Fields
JavaScript can inspect or change the read-only state of supported form controls.
Check the Read-Only Property
const input = document.getElementById("reference-code");
console.log(input.readOnly);
The readOnly property reports whether the input has its read-only state enabled.
Make an Input Read-Only
input.readOnly = true;
Prevents the user from directly editing the input's value.
Make an Input Editable
input.readOnly = false;
Removes the read-only restriction from a supported input.
Check the CSS State
console.log(input.matches(":read-only"));
The matches() method determines whether the element currently matches the CSS pseudo-class.
Automatic CSS Updates
When JavaScript changes the read-only state, the browser updates :read-only and :read-write matching automatically.
Related Pseudo-Classes
The :read-only pseudo-class describes editability. Other pseudo-classes describe different form-control states.
Comparison
| Pseudo-Class | Matching Behavior |
|---|---|
:read-only | Matches elements that are not user-editable. |
:read-write | Matches elements that are user-editable. |
:disabled | Matches disabled form controls. |
:enabled | Matches enabled form controls. |
:required | Matches eligible form controls that require a value. |
:optional | Matches eligible form controls that are not required. |
:focus | Matches an element that currently has focus. |
Read-Only vs. Read-Write
input:read-only {
background-color: #f2f2f2;
}
input:read-write {
background-color: #fff;
}
These selectors distinguish non-editable and editable inputs.
Read-Only vs. Disabled
A disabled control can also match :read-only. The pseudo-classes describe different characteristics and are not mutually exclusive.
Read-Only vs. Focus
Read-only text inputs can normally receive focus. An input can match both :read-only and :focus.
:read-only Specificity
The :read-only pseudo-class contributes a specificity of 0-1-0, like other standard pseudo-classes.
Specificity Examples
| Selector | Specificity |
|---|---|
:read-only | 0-1-0 |
input:read-only | 0-1-1 |
.form-field:read-only | 0-2-0 |
form input:read-only | 0-1-2 |
input[readonly]:read-only | 0-2-1 |
input:focus:read-only | 0-2-1 |
#reference-code:read-only | 1-1-0 |
Specificity Example
input {
background-color: #fff;
}
input:read-only {
background-color: #f2f2f2;
}
When both rules match and other cascade factors are equal, the :read-only rule takes precedence because it has greater specificity.
Combined Selectors
input[readonly]:read-only {
border-color: #999;
}
The attribute selector and pseudo-class each contribute 0-1-0 to the selector's specificity.
Practical Uses
The :read-only pseudo-class can help distinguish non-editable content from editable form controls.
Read-Only Background
input:read-only {
background-color: #f2f2f2;
}
Applies a gray background to non-editable inputs.
Read-Only Border
textarea:read-only {
border-color: #999;
}
Uses a different border for a read-only textarea.
Read-Only Text Color
input[readonly] {
color: #555;
}
Changes the text color of inputs with the readonly attribute.
Editable vs. Read-Only
input:read-write {
background-color: #fff;
}
input:read-only {
background-color: #f2f2f2;
}
Uses different backgrounds to distinguish editable and non-editable inputs.
Contenteditable Areas
.content-area:read-write {
border: 2px solid #006699;
}
.content-area:read-only {
border: 1px solid #999;
}
Styles an editable content area differently from a non-editable one.
Limitations
The :read-only pseudo-class has a broader meaning than the HTML readonly attribute.
Matches Many Elements
Most ordinary HTML elements are not editable by default and can match :read-only. Avoid using the pseudo-class without an appropriate element or class selector when styling forms.
Not Limited to readonly Attributes
An element can match :read-only even when it does not have a readonly attribute.
Disabled Elements
Disabled controls can match :read-only. Use :disabled when specifically targeting disabled controls.
Does Not Prevent Editing
The pseudo-class does not make an element read-only. HTML attributes and element behavior determine editability.
Not a Security Feature
Read-only values can be modified through scripts or developer tools. Validate submitted data on the server.
Attribute Support Varies by Input Type
Not every input type supports the HTML readonly attribute. The CSS pseudo-class can still match non-editable input types.
Form Submission
Read-only and disabled controls behave differently during submission. Choose the appropriate HTML attribute based on the intended form behavior.
Best Practices
- Use
:read-onlyto style elements that are not user-editable. - Combine the pseudo-class with an element or class selector to avoid unintentionally styling ordinary page content.
- Use
[readonly]when specifically targeting controls with the HTMLreadonlyattribute. - Use
:read-writeto style editable controls. - Use
:disabledwhen the intended target is a disabled form control. - Remember that read-only text controls can normally receive focus and be included in form submission.
- Do not use read-only fields as a security mechanism for protecting submitted values.
- Provide clear labels and readable text for read-only fields.
- Maintain sufficient contrast between text, borders, and backgrounds.
- Test form controls with both editable and read-only states.
:read-only Example
This example includes an editable input, a read-only input, and a read-only textarea. Read-only controls receive a gray background and border. Use the button to switch the second input between read-only and editable states.
HTML
<div class="readonly-demo">
<label for="demo-name">Page Name</label>
<input type="text" id="demo-name" value="CSS Basics">
<label for="demo-code">Reference Code</label>
<input type="text" id="demo-code" value="CSS-104" readonly>
<button type="button" id="toggle-readonly">Make Editable</button>
<label for="demo-notes">Reference Notes</label>
<textarea id="demo-notes" rows="3" readonly>These notes are provided for reference.</textarea>
</div>
CSS
.readonly-demo label {
display: block;
margin: 10px 0 5px;
font-weight: bold;
}
.readonly-demo input,
.readonly-demo textarea {
display: block;
width: 100%;
box-sizing: border-box;
padding: 8px;
border: 2px solid #ccc;
background-color: #fff;
}
.readonly-demo input:read-only,
.readonly-demo textarea:read-only {
background-color: #f2f2f2;
border-color: #999;
color: #555;
}
.readonly-demo button {
margin-top: 10px;
padding: 8px 12px;
cursor: pointer;
}
JavaScript
const input = document.getElementById("demo-code");
const button = document.getElementById("toggle-readonly");
button.addEventListener("click", () => {
input.readOnly = !input.readOnly;
button.textContent = input.readOnly ? "Make Editable" : "Make Read-Only";
});
Browser Result
Note: The Reference Code input starts in a read-only state. Click Make Editable to allow changes and remove its gray styling. Click Make Read-Only to restore the original state. The textarea remains read-only.
Browser Support
Baseline: Widely available. The :read-only pseudo-class is supported in modern versions of Chrome, Edge, Firefox, Safari, and other major browsers. Older browsers may have differences in how editability is determined.
For current compatibility information, visit Can I Use? and search for :read-only.
Specifications
The :read-only pseudo-class is defined in CSS Selectors Level 4 as a mutability pseudo-class. It matches elements that are not user-editable.
