# Attribute “readonly” is only allowed when the input type is “date”, “datetime-local”, “email”, “month”, “number”, “password”, “search”, “tel”, “text”, “time”, “url”, or “week”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/attribute-readonly-is-only-allowed-when-the-input-type-is-date-datetime-local-email-month-number-password-search-tel-text-time-url-or-week
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The HTML specification restricts the `readonly` attribute to input types where the user would normally type or select a textual/numeric/date value. The idea is straightforward: `readonly` means "you can see and select this value, but you can't edit it." That concept only makes sense for fields that contain editable text or structured data like dates and numbers. For controls like checkboxes, radio buttons, color pickers, file selectors, and range sliders, the interaction model is fundamentally different — there's no text to make "read-only."

The full list of input types that support `readonly` is:

- `text`
- `search`
- `url`
- `tel`
- `email`
- `password`
- `date`
- `month`
- `week`
- `time`
- `datetime-local`
- `number`

The `readonly` attribute is **not** valid on these types: `checkbox`, `radio`, `range`, `color`, `file`, `hidden`, `button`, `submit`, `reset`, and `image`.

## Why this matters

**Standards compliance:** Browsers are not required to honor `readonly` on unsupported input types. Even if a browser appears to respect it today, that behavior is not guaranteed and could change.

**Form submission behavior:** There's a critical difference between `readonly` and `disabled`. A `readonly` field's value **is included** in form submission data, while a `disabled` field's value **is not**. If you swap `readonly` for `disabled` to fix this error, be aware that the field's value won't be sent with the form unless you take additional steps (such as adding a hidden input).

**Accessibility:** Screen readers and assistive technologies rely on valid HTML to convey the correct state of form controls. Using `readonly` on an unsupported type can send confusing signals about the control's interactivity.

## How to fix it

You have several options depending on your goal:

1. **Remove `readonly`** if it was added by mistake or isn't necessary.
2. **Change the input type** to one that supports `readonly`, if that fits your use case.
3. **Use `disabled` instead** to prevent interaction on non-textual inputs. Remember that disabled fields are excluded from form submission.
4. **Pair `disabled` with a hidden input** if you need the value submitted with the form but want the visible control to be non-interactive.

## Examples

### Invalid: `readonly` on a checkbox

```html
<input type="checkbox" name="agree" readonly>
```

### Invalid: `readonly` on a range input

```html
<input type="range" name="volume" min="0" max="100" value="50" readonly>
```

### Invalid: `readonly` on a color input

```html
<input type="color" name="theme" value="#ff0000" readonly>
```

### Fixed: using `readonly` on a supported input type

```html
<input type="text" name="code" value="ABC-123" readonly>
<input type="email" name="contact" value="user@example.com" readonly>
<input type="date" name="start" value="2024-01-15" readonly>
```

### Fixed: using `disabled` for a non-textual input

```html
<input type="checkbox" name="agree" checked disabled>
```

### Fixed: using `disabled` with a hidden input to preserve form submission

If you need the value to be submitted with the form while keeping the visible control non-interactive, pair a `disabled` control with a `hidden` input:

```html
<!-- The hidden input ensures the value is submitted -->
<input type="hidden" name="agree" value="on">
<!-- The disabled checkbox is visible but non-interactive -->
<input type="checkbox" name="agree_display" checked disabled>
<label for="agree_display">I agree to the terms</label>
```

### Fixed: using JavaScript to prevent changes (advanced)

If you truly need a checkbox that looks interactive but can't be changed, you can use JavaScript while keeping the HTML valid:

```html
<input type="checkbox" name="agree" checked onclick="return false;">
```

Note that this approach relies on JavaScript and won't work if scripting is disabled. For most cases, using `disabled` (with or without a companion hidden input) is the simpler and more robust solution.
