HTML readonly input: why required stops checking a locked field

An input with readonly can remain focusable and contribute its named value to form data, but it is excluded from constraint validation. An empty locked field therefore cannot be made dependable by adding required. Check the source of the locked value and validate the submitted record on the server. MDN readonly attribute

An original equipment-loan form displays a reference assigned by the application. While the reference is loading, the field is empty and read-only. The author adds required expecting the browser to block submission. That expectation fails because the field is not participating in the browser's constraint checks.

Inspect participation before changing the error message

This small fixture exposes the state:

<form id="loan">
  <label for="loan-reference">Loan reference</label>
  <input id="loan-reference" name="reference" readonly>
  <button type="submit">Record loan</button>
</form>

In that page's console:

const form = document.getElementById('loan');
const reference = document.getElementById('loan-reference');

console.log(reference.willValidate); // false
console.log(reference.checkValidity()); // true
console.log(new FormData(form).get('reference')); // ''

checkValidity() returning true does not establish that the value exists or identifies a real loan. The input is barred from constraint validation. The willValidate property reports whether the control participates.

Do not add required to this read-only fixture. MDN notes that the combination is not permitted, and required would not restore validation while the input remains read-only. If users must supply a reference themselves, unlock the field and apply appropriate constraints to that editable state.

Change the Boolean property, not a false-looking string

This markup still locks the input:

<input name="reference" readonly="false">

readonly is a Boolean attribute. Its presence enables the state, even when its value is the text false. To unlock the field in JavaScript:

reference.readOnly = false;
reference.required = true;

To return it to an application-assigned state:

reference.required = false;
reference.readOnly = true;
reference.value = 'LOAN-204';

The DOM property is readOnly, with a capital O. Setting .value still works while the control is read-only. The state limits user editing through that control; it does not freeze JavaScript or make the submitted value trustworthy.

For the loan page, do not unlock an application-assigned identifier simply to make a missing value pass browser validation. Finish loading or assigning the reference before permitting the real submission, show an actionable failure if that step fails, and have the server derive or verify the reference for the loan being recorded.

Confirm that the control supports readonly

The attribute applies to text-like inputs, dates and times, number inputs, and textareas. It does not provide a read-only checkbox, radio button, range slider, file chooser, or select menu. A checkbox bearing an ignored readonly attribute can still be changed.

disabled has a different consequence: disabled controls are excluded from the submitted form data. Replacing readonly with disabled can therefore make the loan reference disappear from the payload. The fieldset guide explains group disabling and the first-legend exception.

If an immutable choice must be shown, choose an appropriate display and server data contract rather than treating an unsupported attribute as enforcement. A hidden copy can carry a value, but it is still client input that the server must verify.

Test the actual state transition

Start with the locked empty reference. Confirm willValidate is false and inspect the empty form-data value. Then switch to an editable, required field and confirm that an empty value is invalid. Set LOAN-204, return to the assigned read-only state, and inspect the payload again.

The form validation guide covers checks for editable inputs. For the loan form, finish by testing the failed-reference-loading path too: the page should explain why recording cannot continue, and the server should reject a missing or unrelated reference even if a client submits it directly.

Keep reading