HTML Guides for attributes
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.
End tags in HTML must not have any attributes.
According to the HTML specification, only start tags (also called opening tags) may contain attributes, while end tags must appear as a plain </tagname> with nothing else.
For example, this is invalid and will trigger the error:
<p>Welcome to the site.</p class="welcome">
Correct code removes the attribute from the end tag:
<p>Welcome to the site.</p>
If you need the element to have an attribute, only include it in the start tag:
<p class="welcome">Welcome to the site.</p>
The HTML specification requires that attributes on an element be separated by one or more ASCII whitespace characters. When you omit the space — typically between a closing quote of one attribute’s value and the name of the next attribute — the browser may struggle to determine where one attribute ends and the next begins. While some browsers may attempt to parse the element correctly, the behavior is not guaranteed and can lead to unexpected results.
This issue commonly occurs when editing HTML by hand, especially when copying and pasting attributes from different sources or when a template engine concatenates attribute strings without proper spacing. It can also happen when a closing quote is immediately followed by another attribute name, making the markup difficult to read and maintain.
Beyond validation, missing spaces between attributes hurt code readability. Other developers (or your future self) scanning the markup may misread attribute boundaries, leading to bugs that are hard to track down. Consistent spacing also ensures that assistive technologies and browser parsers interpret your elements exactly as intended.
How to Fix It
Go through your HTML and ensure every attribute is separated from adjacent attributes by at least one space character. Pay special attention to:
- Attributes placed immediately after a quoted value (e.g., "value"class should be "value" class).
- Attributes placed after unquoted values, which can be even more ambiguous.
- Dynamically generated markup from template engines or JavaScript, where concatenation might drop whitespace.
Examples
Incorrect: No Space Between Attributes
<a href="page.php"class="big">link</a>
Here, class is placed directly after the closing quote of the href value with no space in between. The validator will flag this as an error.
Correct: Space Between Attributes
<a href="page.php" class="big">link</a>
A single space between "page.php" and class resolves the issue.
Incorrect: Multiple Missing Spaces
<img src="photo.jpg"alt="A sunset"width="600"height="400">
All four attributes run together without any whitespace separating them.
Correct: All Attributes Properly Spaced
<img src="photo.jpg" alt="A sunset" width="600" height="400">
Correct: Using Line Breaks as Whitespace
When an element has many attributes, you can use newlines for separation, which also improves readability:
<img
src="photo.jpg"
alt="A sunset"
width="600"
height="400">
Newlines and indentation count as valid whitespace between attributes and are perfectly acceptable in HTML. This multi-line style is especially helpful for elements with numerous attributes, such as <input> fields in forms or components with data attributes.
The HTML parser reads element attributes by looking for a name, then an =, then a value. When it encounters = in a spot where it expects a name to start, it means something has gone wrong with the attribute syntax. This can happen in several ways: an attribute name is missing entirely before the =, there’s a double == instead of a single =, a space was accidentally inserted in the middle of an attribute name, or a previous attribute’s value was left unquoted causing the parser to lose track of where one attribute ends and the next begins.
This is a problem because browsers may silently discard the malformed attribute, apply it incorrectly, or even misinterpret surrounding attributes. This leads to unpredictable behavior across different browsers. Screen readers and other assistive technologies may also fail to interpret the element correctly, creating accessibility issues.
How to Fix It
- Check for missing attribute names — Make sure every = sign is preceded by a valid attribute name like class, id, src, etc.
- Check for double equals signs — Replace any == with a single =.
- Check for spaces in attribute names — Attribute names cannot contain spaces. Remove accidental spaces within names.
- Check for unquoted attribute values — Always quote attribute values with double quotes. An unquoted value containing special characters can cause the parser to misread subsequent attributes.
- Check for stray = characters — Look for leftover = signs from copy-paste errors or incomplete edits.
Examples
Missing attribute name before =
An = appears with no attribute name before it:
<!-- ❌ Bad: no attribute name before = -->
<img ="photo.jpg" alt="A photo">
<!-- ✅ Fixed: added the src attribute name -->
<img src="photo.jpg" alt="A photo">
Double equals sign
A typo creates == instead of =:
<!-- ❌ Bad: double equals sign -->
<a href=="https://example.com">Link</a>
<!-- ✅ Fixed: single equals sign -->
<a href="https://example.com">Link</a>
Space inside an attribute name
A space splits what should be one attribute name into two tokens, leaving an orphaned =:
<!-- ❌ Bad: space in "data-value" splits the attribute -->
<div data- value="10">Content</div>
<!-- ✅ Fixed: no space in the attribute name -->
<div data-value="10">Content</div>
Unquoted attribute value causing a cascade
When a value isn’t quoted, the parser can misinterpret where it ends, causing the next attribute’s = to appear in an unexpected position:
<!-- ❌ Bad: unquoted class value with space causes parsing issues -->
<p class=my class id="intro">Text</p>
<!-- ✅ Fixed: properly quoted attribute value -->
<p class="my-class" id="intro">Text</p>
Stray = from an incomplete edit
A leftover = from a deleted or partially edited attribute:
<!-- ❌ Bad: stray = left over after removing an attribute -->
<div class="container" = >Content</div>
<!-- ✅ Fixed: removed the stray = -->
<div class="container">Content</div>
When the HTML parser reads a tag, it expects a specific sequence: the tag name, then optional attributes (each with a name, optionally followed by = and a value), and finally a closing >. If the parser encounters a < character in a position where it’s looking for an attribute name, it means something has gone structurally wrong. The parser interprets the < as the beginning of a new tag, but since it’s still inside the current tag’s definition, it raises this error.
This issue commonly arises from three scenarios:
- A stray < character inside a tag — perhaps from a typo or a copy-paste error.
- A missing > on a previous tag — causing the parser to treat the next tag’s < as though it’s still part of the previous tag’s attributes.
- Incorrectly nested or overlapping tags — where one element is accidentally placed inside another element’s opening tag.
This matters because browsers handle malformed HTML unpredictably. One browser might silently ignore the stray character, while another might drop the entire element or render content incorrectly. Fixing these structural errors ensures consistent rendering across all browsers and improves accessibility, since screen readers and other assistive technologies rely on well-formed markup to interpret page structure.
Examples
Stray < character inside a tag
A common typo where an extra < appears before the closing of a self-closing tag or between attributes:
<!-- ❌ Stray "<" inside the img tag -->
<img src="photo.jpg" alt="smiling cat" < />
Remove the stray < character:
<!-- ✅ Fixed: no extra "<" -->
<img src="photo.jpg" alt="smiling cat" />
Missing > on a preceding tag
When a tag is missing its closing >, the parser continues reading the next tag as though it were part of the first tag’s attributes:
<!-- ❌ The opening <div> is missing its closing ">" -->
<div class="wrapper"
<p>Hello, world!</p>
</div>
The parser sees <p> while still inside the <div> tag, triggering the error. Add the missing >:
<!-- ✅ Fixed: <div> is properly closed -->
<div class="wrapper">
<p>Hello, world!</p>
</div>
Missing > on a tag with multiple attributes
This often happens with tags that have many attributes, making it easy to miss the closing >:
<!-- ❌ The <a> tag is missing its closing ">" -->
<a href="/about" class="nav-link" id="about-link"
<span>About Us</span>
</a>
<!-- ✅ Fixed: closing ">" added to the <a> tag -->
<a href="/about" class="nav-link" id="about-link">
<span>About Us</span>
</a>
Accidental angle bracket in an attribute value
If an attribute value contains a < that isn’t properly quoted, the parser may misinterpret it:
<!-- ❌ Unquoted or broken attribute value with "<" -->
<div title=5<10>
<p>Content</p>
</div>
Ensure attribute values containing special characters are properly quoted and use HTML entities where needed:
<!-- ✅ Fixed: value is quoted and uses an entity for "<" -->
<div title="5<10">
<p>Content</p>
</div>
How to debug this error
When you see this error, follow these steps:
- Go to the line number reported by the validator.
- Look at the tag on that line — check if it has a stray < character.
- If the tag looks fine, check the tag immediately before it — a missing > on the previous tag is often the real culprit.
- Verify all attribute values are properly quoted — unquoted values containing < can trigger this error.
- Use a code editor with syntax highlighting — mismatched or broken tags are usually easy to spot when the syntax colors look wrong.
The HTML parser reads element tags by looking for attribute names, an = sign, and then a quoted value. When the parser finds a " character in a position where it expects an attribute name to start, it means something has gone wrong with the syntax. The validator flags this as a parse error because the browser has to guess what you intended, which can lead to attributes being silently dropped, values being misassigned, or unexpected rendering behavior.
This error most commonly occurs due to one of these causes:
- Missing = sign between an attribute name and its value (e.g., class"main" instead of class="main").
- Extra closing quote that creates a stray " after a valid attribute (e.g., class="main"" with a doubled quote).
- Stray quote from copy-paste errors or typos that leave orphan " characters floating in the tag.
- Accidentally deleted = during editing, breaking an otherwise valid attribute.
Beyond being invalid HTML, this problem can cause real functional issues. A missing = sign may cause the browser to interpret the attribute value as a separate (unknown) attribute, effectively losing the intended value. An extra quote can cause the parser to misread subsequent attributes, potentially breaking event handlers, links, or styling. These issues can also harm accessibility, as assistive technologies rely on properly parsed attributes to convey meaning.
Examples
Missing equals sign
The = between the attribute name and value is absent, so the parser sees "container" where it expects a new attribute name.
<!-- ❌ Bad: missing = before the value -->
<div class"container">Content</div>
<!-- ✅ Fixed: = added between name and value -->
<div class="container">Content</div>
Extra closing quotation mark
A doubled " at the end of an attribute value leaves a stray quote that the parser doesn’t expect.
<!-- ❌ Bad: extra " after the attribute value -->
<a href="https://example.com"">Visit</a>
<!-- ✅ Fixed: single closing quote -->
<a href="https://example.com">Visit</a>
Multiple attributes with a stray quote
When multiple attributes are present, a stray quote can also corrupt the parsing of subsequent attributes.
<!-- ❌ Bad: extra " after id value bleeds into the next attribute -->
<input id="email"" type="text" name="email">
<!-- ✅ Fixed: clean quotes on every attribute -->
<input id="email" type="text" name="email">
Missing equals sign on a later attribute
The error doesn’t always occur on the first attribute — it can appear on any attribute in the tag.
<!-- ❌ Bad: missing = on the style attribute -->
<p class="intro" style"color: red;">Hello</p>
<!-- ✅ Fixed: = added before style value -->
<p class="intro" style="color: red;">Hello</p>
How to fix it
- Locate the line reported by the validator and look at the element’s attributes.
- Check every attribute follows the name="value" pattern with no missing = signs.
- Count your quotes — every opening " should have exactly one matching closing " for each attribute value.
- Watch for smart quotes — curly quotes (" ") copied from word processors are not valid HTML attribute delimiters. Replace them with straight quotes (").
- Use a code editor with syntax highlighting — mismatched or extra quotes are usually easy to spot when your editor color-codes attribute values.
Ready to validate your sites?
Start your free trial today.