HTML Guides for boolean attribute
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The hidden attribute indicates that an element is not yet, or is no longer, relevant to the current state of the page. Browsers will not render elements that have this attribute. It’s available on all HTML elements as a global attribute.
In HTML, boolean attributes like hidden, disabled, readonly, and checked follow special rules. Unlike attributes in programming languages where you might set a value to true or false, boolean attributes in HTML work by presence or absence:
- Present = the feature is on (e.g., hidden, hidden="", or hidden="hidden")
- Absent = the feature is off (the attribute is simply not in the markup)
This is a common source of confusion. Writing hidden="false" does not make the element visible. Because the attribute is still present in the markup, the browser interprets it as “this element is hidden.” The actual string value "false" is ignored for the purpose of determining the boolean state. This can lead to frustrating bugs where elements remain invisible despite what looks like correct code.
According to the HTML specification, the only valid values for a boolean attribute are the empty string ("") or the attribute’s own name (e.g., hidden="hidden"). Any other value, including "true" or "false", is invalid and will trigger a W3C validator error.
How the hidden attribute works with newer values
Starting with more recent updates to the HTML specification, the hidden attribute also accepts the value "until-found". When set to hidden="until-found", the element remains hidden but can be revealed by the browser’s find-in-page feature or by fragment navigation. This is the only keyword value (besides the empty string and the attribute’s canonical name) that changes the attribute’s behavior. It does not change the fact that "false" is an invalid value.
How to fix it
- To hide an element, add the hidden attribute with no value.
- To show an element, remove the hidden attribute entirely from the markup.
- If you’re toggling visibility with JavaScript, use element.hidden = false (the JavaScript property, not the HTML attribute) or element.removeAttribute('hidden').
Examples
❌ Invalid: setting hidden to "false"
<!-- The element is STILL hidden and the markup is invalid -->
<div hidden="false">You won't see this text.</div>
❌ Invalid: setting hidden to "true"
<!-- "true" is also not a valid value for a boolean attribute -->
<p hidden="true">This paragraph is hidden, but the markup is invalid.</p>
✅ Valid: using hidden without a value
<div hidden>This element is hidden from the page.</div>
✅ Valid: using hidden with an empty string or its own name
<!-- Both of these are valid ways to write boolean attributes -->
<div hidden="">Hidden element</div>
<div hidden="hidden">Also a hidden element</div>
✅ Valid: showing the element by omitting hidden
<div>This element is visible because it has no hidden attribute.</div>
✅ Valid: using hidden="until-found"
<div hidden="until-found">
This content is hidden but can be found via browser search.
</div>
Toggling visibility with JavaScript
When dynamically showing or hiding elements, use the hidden property on the DOM element rather than setting the attribute to "false":
<button type="button" id="toggle">Toggle message</button>
<p id="message" hidden>Hello! Now you can see me.</p>
<script>
document.getElementById("toggle").addEventListener("click", function () {
const msg = document.getElementById("message");
msg.hidden = !msg.hidden; // Correctly toggles the boolean property
});
</script>
Using msg.hidden = false in JavaScript correctly removes the hidden attribute from the element. This is different from writing hidden="false" directly in HTML, which keeps the attribute present and triggers the validation error.
In HTML, boolean attributes like allowfullscreen, disabled, readonly, and hidden work differently from what many developers expect. Their presence alone on an element means “true,” and their absence means “false.” The only valid values for a boolean attribute are the empty string ("") or the attribute’s own name (e.g., allowfullscreen="allowfullscreen"). Setting a boolean attribute to "true" is not valid HTML according to the WHATWG HTML living standard, even though browsers will typically still interpret it as enabled.
This matters for several reasons. First, it violates the HTML specification and will produce a W3C validation error. Second, it can create confusion for other developers who may assume that setting the attribute to "false" would disable it — but that’s not how boolean attributes work. Setting allowfullscreen="false" would still enable fullscreen because the attribute is present. Keeping your markup valid and semantically correct avoids these misunderstandings and ensures forward compatibility with browsers and tooling.
It’s also worth noting that allowfullscreen is now considered a legacy attribute. The modern approach is to use the allow attribute with the "fullscreen" permission token, which is part of the broader Permissions Policy mechanism. The allow attribute gives you fine-grained control over multiple features in a single attribute.
Examples
Incorrect: boolean attribute set to “true”
This triggers the validation error because "true" is not a valid value for a boolean attribute.
<iframe src="https://example.com" allowfullscreen="true"></iframe>
Correct: boolean attribute with no value
Simply include the attribute name without any value assignment.
<iframe src="https://example.com" allowfullscreen></iframe>
Also correct: boolean attribute with an empty string
The empty string is a valid value for any boolean attribute.
<iframe src="https://example.com" allowfullscreen=""></iframe>
Also correct: boolean attribute set to its own name
Per the spec, a boolean attribute can be set to a case-insensitive match of its own name.
<iframe src="https://example.com" allowfullscreen="allowfullscreen"></iframe>
Recommended: using the modern allow attribute
The allow attribute is the preferred approach going forward. It replaces allowfullscreen and can also control other permissions like camera, microphone, and more.
<iframe src="https://example.com" allow="fullscreen"></iframe>
You can combine multiple permissions in a single allow attribute:
<iframe src="https://example.com" allow="fullscreen; camera; microphone"></iframe>
Common mistake: trying to disable with “false”
Be aware that the following does not disable fullscreen — the attribute is still present, so fullscreen is still allowed. This would also produce a validation error.
<!-- This does NOT disable fullscreen — and is invalid HTML -->
<iframe src="https://example.com" allowfullscreen="false"></iframe>
To disable fullscreen, simply omit the attribute entirely:
<iframe src="https://example.com"></iframe>
In HTML, boolean attributes work differently than you might expect from programming languages. They don’t accept "true" or "false" as values. Instead, the presence of the attribute means it’s active, and its absence means it’s inactive. This is defined in the WHATWG HTML Living Standard, which states that a boolean attribute’s value must either be the empty string or a case-insensitive match for the attribute’s name.
This means there are exactly three valid ways to write the disabled attribute:
- disabled (no value)
- disabled="" (empty string)
- disabled="disabled" (attribute name as value)
Any other value — including "true", "false", "yes", "no", or "1" — is invalid and will trigger a W3C validation error.
A common and dangerous misunderstanding is that disabled="false" will make an element not disabled. It won’t. Because boolean attributes are activated by their presence alone, disabled="false" still disables the element. The browser sees the disabled attribute is present and treats the element as disabled, completely ignoring the "false" value. This can lead to confusing bugs where elements appear permanently disabled.
This issue affects all elements that support the disabled attribute, including <input>, <button>, <select>, <textarea>, <fieldset>, <optgroup>, and <option>. The same rules apply to other boolean attributes like checked, readonly, required, autofocus, and hidden.
Why this matters
- Standards compliance: Using invalid attribute values violates the HTML specification and produces W3C validation errors.
- Maintainability: Developers reading disabled="true" or disabled="false" may misunderstand the intent, especially if they assume "false" removes the disabled state.
- Framework pitfalls: Some JavaScript frameworks dynamically set disabled="true" or disabled="false" as string values. When the rendered HTML reaches the browser, both values result in a disabled element, which is rarely the intended behavior.
How to fix it
- To disable an element, add the disabled attribute with no value, or use disabled="" or disabled="disabled".
- To enable an element, remove the disabled attribute entirely. Don’t set it to "false".
- In JavaScript, use the DOM property element.disabled = true or element.disabled = false, or use element.removeAttribute('disabled') to enable it. Avoid element.setAttribute('disabled', 'false').
Examples
❌ Invalid: using "true" and "false" as values
<form>
<input type="text" disabled="true">
<select disabled="false">
<option>Option A</option>
</select>
<button type="submit" disabled="true">Submit</button>
</form>
Both the "true" and "false" values are invalid. Additionally, disabled="false" still disables the <select> element, which is almost certainly not what was intended.
✅ Valid: correct boolean attribute usage
<form>
<input type="text" disabled>
<select>
<option>Option A</option>
</select>
<button type="submit" disabled="disabled">Submit</button>
</form>
Here, the <input> and <button> are disabled using valid syntax. The <select> is enabled because the disabled attribute has been removed entirely.
✅ Valid: toggling disabled state with JavaScript
<form>
<input type="text" id="username" disabled>
<button type="button" id="toggle">Enable field</button>
<script>
document.getElementById('toggle').addEventListener('click', function () {
var field = document.getElementById('username');
field.disabled = !field.disabled;
});
</script>
</form>
Using the disabled DOM property (a real boolean) is the correct way to toggle the disabled state dynamically. This avoids the pitfall of setting string values like "true" or "false" on the attribute.
In HTML, boolean attributes work differently than you might expect from programming languages. A boolean attribute’s presence on an element represents the true value, and its absence represents false. You don’t set them to "true" or "false" like you would in JavaScript or other languages. According to the WHATWG HTML specification, a boolean attribute has exactly three valid forms:
- The attribute name alone (e.g., multiple)
- The attribute with an empty value (e.g., multiple="")
- The attribute with a value matching its own name, case-insensitively (e.g., multiple="multiple")
Setting multiple="true" is invalid because "true" is not one of the permitted values. While browsers are forgiving and will typically still treat the attribute as present (effectively enabling it), this produces a W3C validation error and does not conform to the HTML standard. Relying on browser leniency leads to inconsistent behavior, makes your code harder to maintain, and can cause problems with HTML processing tools or strict parsers.
This same rule applies to all boolean attributes in HTML, including disabled, readonly, checked, required, hidden, autoplay, and many others.
It’s also important to note that multiple="false" does not disable the attribute. Because the attribute is still present on the element, the browser treats it as enabled. To disable a boolean attribute, you must remove it from the element entirely.
Examples
❌ Invalid: using "true" as the value
<label for="colors">Select your favorite colors:</label>
<select id="colors" name="colors" multiple="true">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
This triggers the validation error: Bad value “true” for attribute “multiple” on element “select”.
✅ Fixed: attribute name only (preferred)
<label for="colors">Select your favorite colors:</label>
<select id="colors" name="colors" multiple>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
✅ Fixed: empty string value
<label for="colors">Select your favorite colors:</label>
<select id="colors" name="colors" multiple="">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
✅ Fixed: value matching the attribute name
<label for="colors">Select your favorite colors:</label>
<select id="colors" name="colors" multiple="multiple">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
❌ Common mistake: using "false" to disable
<!-- This does NOT disable multiple selection — the attribute is still present -->
<select name="colors" multiple="false">
<option value="red">Red</option>
<option value="green">Green</option>
</select>
✅ Correct way to disable: remove the attribute entirely
<label for="color">Select a color:</label>
<select id="color" name="color">
<option value="red">Red</option>
<option value="green">Green</option>
</select>
In HTML, boolean attributes like selected work differently than you might expect if you’re coming from a programming language. A boolean attribute’s presence alone means “true,” and its absence means “false.” Setting selected="true" is invalid because the only permitted values for a boolean attribute are the empty string ("") or the attribute’s own name (e.g., selected="selected"). The value "true" is not recognized by the HTML specification, which is why the W3C validator flags it.
This matters for several reasons. First, it violates the WHATWG HTML specification, which explicitly defines how boolean attributes must be written. Second, while most browsers are forgiving and will still treat selected="true" as if the option is selected, relying on this lenient behavior is risky — it can lead to inconsistencies across browsers or tools that parse HTML strictly. Third, invalid markup can cause problems for assistive technologies, automated testing tools, and server-side HTML processors that follow the spec closely.
The same rule applies to other boolean attributes like disabled, checked, readonly, multiple, required, and hidden. None of them should be set to "true" or "false".
It’s also worth noting that setting a boolean attribute to "false" (e.g., selected="false") does not turn it off — the attribute’s mere presence activates it. To deactivate a boolean attribute, you must remove it entirely from the element.
Examples
❌ Invalid: using selected="true"
<select name="color">
<option selected="true">Red</option>
<option>Green</option>
<option>Blue</option>
</select>
This triggers the validation error because "true" is not a valid value for the boolean selected attribute.
✅ Valid: bare attribute (preferred)
<select name="color">
<option selected>Red</option>
<option>Green</option>
<option>Blue</option>
</select>
The simplest and most common way to write a boolean attribute — just include the attribute name with no value.
✅ Valid: empty string value
<select name="color">
<option selected="">Red</option>
<option>Green</option>
<option>Blue</option>
</select>
An empty string is a valid value for any boolean attribute per the HTML spec.
✅ Valid: attribute name as value
<select name="color">
<option selected="selected">Red</option>
<option>Green</option>
<option>Blue</option>
</select>
Using the attribute’s own name as its value is also valid. This form is sometimes seen in XHTML-style markup and in templating systems.
❌ Invalid: using selected="false" to deselect
<select name="color">
<option selected="false">Red</option>
<option>Green</option>
<option>Blue</option>
</select>
This is both invalid and misleading. The option will still be selected because the selected attribute is present. To not select an option, simply omit the attribute:
<select name="color">
<option>Red</option>
<option>Green</option>
<option>Blue</option>
</select>
In HTML, boolean attributes work differently from regular attributes. They don’t take true or false as values. Instead, the mere presence of the attribute represents the “true” state, and its complete absence represents “false.” According to the WHATWG HTML specification, a boolean attribute has exactly three valid representations: the attribute name alone (checked), an empty string value (checked=""), or the attribute name as its own value (checked="checked"). Any other value — including seemingly intuitive ones like "true", "false", "yes", or "no" — is invalid.
This is particularly important to understand because checked="false" does not uncheck the input. Since the attribute is still present, the browser interprets it as checked. This can lead to confusing behavior where a developer writes checked="false" expecting the checkbox to be unchecked, but it renders as checked. To leave an input unchecked, you must omit the checked attribute entirely.
The checked attribute applies to <input> elements of type checkbox and radio. It sets the initial checked state when the page loads. Note that JavaScript uses a different convention — the checked DOM property accepts true or false as JavaScript boolean values — but this does not apply to HTML markup.
Fixing this issue ensures standards compliance, avoids unexpected behavior, and improves code clarity. While browsers are lenient and will typically treat any value as “checked,” relying on this behavior is non-standard and can cause confusion for developers reading the code.
Examples
Invalid: using a string value
<input type="checkbox" checked="true">
<input type="radio" name="color" value="red" checked="yes">
These produce validation errors because "true" and "yes" are not valid boolean attribute values.
Invalid: attempting to set false
<!-- This does NOT uncheck the input — it's still checked! -->
<input type="checkbox" checked="false">
Despite the value "false", the checkbox will still render as checked because the attribute is present.
Valid: attribute name only (recommended)
<input type="checkbox" checked>
<input type="radio" name="color" value="red" checked>
This is the most common and cleanest form.
Valid: empty string value
<input type="checkbox" checked="">
Valid: attribute name as its own value
<input type="checkbox" checked="checked">
This form is sometimes seen in XHTML-compatible markup.
Valid: omitting the attribute to leave unchecked
<input type="checkbox">
To represent an unchecked state, simply leave the attribute off.
Full example in context
<!DOCTYPE html>
<html lang="en">
<head>
<title>Newsletter Preferences</title>
</head>
<body>
<form>
<fieldset>
<legend>Email preferences</legend>
<label>
<input type="checkbox" name="newsletter" checked>
Subscribe to newsletter
</label>
<label>
<input type="checkbox" name="promotions">
Receive promotional emails
</label>
</fieldset>
<fieldset>
<legend>Frequency</legend>
<label>
<input type="radio" name="frequency" value="daily" checked>
Daily
</label>
<label>
<input type="radio" name="frequency" value="weekly">
Weekly
</label>
</fieldset>
</form>
</body>
</html>
In this example, the newsletter checkbox and the “Daily” radio button are pre-selected using the valid checked attribute without any value. The promotions checkbox and “Weekly” radio button are unchecked because the attribute is absent.
Ready to validate your sites?
Start your free trial today.