Guías HTML para etiqueta de cierre
Aprende a identificar y corregir errores comunes de validación HTML marcados por el W3C Validator, para que tus páginas cumplan con los estándares y se muestren correctamente en todos los navegadores. También consulta nuestras Guías de accesibilidad.
The HTML specification explicitly forbids nesting <a> elements inside other <a> elements. This is defined as part of the content model for the <a> element — it is “transparent” but must not contain any interactive content, which includes other <a> elements. When the validator encounters a closing </a> tag that would violate these nesting rules, it raises this error.
This typically happens in one of two scenarios:
- A missing closing </a> tag — You forget to close one link, so the next link appears to be nested inside it.
- Intentionally wrapping one link inside another — You try to place a clickable link inside a larger clickable area, which is invalid HTML.
Why this matters
When an <a> element is nested inside another <a> element, browsers must guess what you intended. Different browsers may handle this differently — some will auto-close the first link before starting the second, while others may produce unexpected DOM structures. This leads to:
- Unpredictable behavior — Click targets may not work as expected across different browsers.
- Accessibility issues — Screen readers rely on a well-structured DOM. Ambiguous nesting confuses assistive technologies and makes navigation difficult for users who depend on them.
- Broken styling — CSS selectors that depend on proper parent-child relationships may not apply correctly.
How to fix it
- Find the offending <a> tags — The validator will point to the line with the problematic closing </a>. Look at that line and the lines above it to find where the nesting issue begins.
- Add missing closing tags — If you forgot a </a>, add it before the next <a> opens.
- Restructure if needed — If you intended to have a link inside a larger clickable area, redesign the markup so that the links are siblings rather than nested.
Examples
❌ Missing closing tag causes implicit nesting
The first <a> is never closed, so the second <a> appears to be nested inside it:
<nav>
<a href="one.html">Page 1
<a href="two.html">Page 2</a>
</nav>
✅ Fixed by adding the missing closing tag
<nav>
<a href="one.html">Page 1</a>
<a href="two.html">Page 2</a>
</nav>
❌ Intentionally nesting links (invalid)
Wrapping a link inside a larger link is not allowed, even if it seems useful for UI purposes:
<a href="/article">
<h2>Article Title</h2>
<p>A short summary of the article.</p>
<a href="/author">Author Name</a>
</a>
✅ Fixed by restructuring with sibling links
Use CSS positioning or a different layout strategy to achieve the same visual result without nesting:
<article>
<a href="/article">
<h2>Article Title</h2>
<p>A short summary of the article.</p>
</a>
<p>By <a href="/author">Author Name</a></p>
</article>
❌ Forgetting to close links in a list
This is especially common in navigation menus built with lists:
<ul>
<li><a href="/home">Home</li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
Here, the first <a> is never closed. The </li> tag implicitly closes the <li>, but the <a> remains open, causing nesting issues with the subsequent links.
✅ Fixed by properly closing each link
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
A good habit is to write both the opening and closing <a> tags together before filling in the content. This prevents accidental omission and keeps your HTML well-structured.
The <code> element is an inline-level (phrasing content) element designed to represent a fragment of computer code. According to the HTML specification, it can only contain other phrasing content — elements like <span>, <em>, <strong>, <a>, and text nodes. It cannot contain block-level (flow content) elements such as <div>, <p>, <ul>, <h1>–<h6>, or <table>.
When the validator reports that an end tag </code> violates nesting rules, it means one of two things is happening:
-
Disallowed content inside <code>: A block-level element has been placed inside the <code> element. When the browser encounters a block-level element where only phrasing content is allowed, it may implicitly close the <code> element. The subsequent </code> end tag then has no matching open tag, causing the nesting violation.
-
Overlapping or misnested tags: Tags inside <code> are improperly overlapped, meaning an element opened inside <code> is closed outside it, or vice versa.
This matters for several reasons. Browsers will attempt to “fix” the broken nesting by rearranging the DOM in ways you may not expect, leading to inconsistent rendering and styling. Screen readers and other assistive technologies rely on a well-formed DOM tree, so broken nesting can harm accessibility. Additionally, other validator errors in your document may cascade from this single nesting issue, so fixing it can resolve multiple warnings at once.
When debugging this error, look at other validation errors reported near the same line. Often, a prior error — such as an unclosed tag or an unexpected block element — is the root cause, and the </code> nesting violation is a downstream consequence.
Examples
❌ Block-level element inside <code>
Placing a <div> inside <code> violates the content model. The browser implicitly closes <code> before the <div>, leaving the </code> end tag orphaned.
<p>Example: <code>some text <div>block content</div> more text</code></p>
✅ Use only phrasing content inside <code>
Replace the block-level element with an inline alternative like <span>:
<p>Example: <code>some text <span>inline content</span> more text</code></p>
❌ Overlapping tags with <code>
Here, <em> is opened inside <code> but closed after </code>, creating an overlap:
<p>See <code>myFunction(<em>arg</code>)</em> for details.</p>
✅ Properly nested tags
Ensure every element opened inside <code> is also closed inside it:
<p>See <code>myFunction(<em>arg</em>)</code> for details.</p>
❌ Paragraph inside <code>
A <p> element is not allowed inside <code>:
<code>
<p>First line of code</p>
<p>Second line of code</p>
</code>
✅ Use <pre><code> for multi-line code blocks
For multi-line code, wrap <code> inside a <pre> element and use line breaks instead of paragraphs:
<pre><code>First line of code
Second line of code</code></pre>
❌ List inside <code>
<code>
<ul>
<li>step one</li>
<li>step two</li>
</ul>
</code>
✅ Separate the list from the code markup
Use <code> individually around the inline code portions:
<ul>
<li><code>step one</code></li>
<li><code>step two</code></li>
</ul>
How to Fix
- Find the line referenced by the validator error and look at what’s inside the <code> element.
- Check for block-level elements like <div>, <p>, <ul>, <table>, or headings nested inside <code>. Replace them with phrasing content alternatives or restructure your markup.
- Check for overlapping tags where an element started inside <code> is closed outside it (or the reverse). Make sure every tag opened inside <code> is closed inside it.
- Review related errors in the validator output. Often, fixing an earlier nesting or unclosed-tag error will resolve the </code> violation automatically.
When the browser encounters a </body> tag while elements like <div>, <section>, <p>, or <span> are still open, it must guess where those elements were supposed to end. Different browsers may guess differently, leading to inconsistent rendering and a DOM structure that doesn’t match your intent. This can cause layout problems, broken styling, and accessibility issues — screen readers rely on a well-formed DOM to convey the correct document structure to users.
The root causes of this error typically include:
- Forgetting a closing tag — the most common scenario, especially with deeply nested structures.
- Mismatched tags — closing tags that don’t correspond to their opening tags (e.g., opening a <div> but closing it with </section>).
- Copy-paste errors — duplicating or deleting code that leaves behind orphaned opening tags.
- Incorrect nesting — overlapping elements where tags cross boundaries instead of being properly nested.
To fix the issue, work through the validator’s error list from top to bottom. The error message usually identifies which elements are unclosed. Find each one and either add the missing closing tag in the correct position or remove the unnecessary opening tag. Using consistent indentation makes it much easier to spot mismatches visually.
Examples
Missing closing tag
This triggers the error because the <section> element is never closed:
<body>
<section>
<h1>Welcome</h1>
<p>Hello, world!</p>
</body>
Add the missing </section> closing tag:
<body>
<section>
<h1>Welcome</h1>
<p>Hello, world!</p>
</section>
</body>
Multiple unclosed elements
Here, both the <div> and the <ul> are left open:
<body>
<div class="sidebar">
<ul>
<li>Home</li>
<li>About</li>
</body>
Close each element in the correct (reverse) order:
<body>
<div class="sidebar">
<ul>
<li>Home</li>
<li>About</li>
</ul>
</div>
</body>
Mismatched closing tag
A mismatch between opening and closing tags can also produce this error. The <div> is opened but </section> is used to close it, leaving the <div> unclosed:
<body>
<div class="content">
<p>Some text here.</p>
</section>
</body>
Fix the closing tag so it matches the opening tag:
<body>
<div class="content">
<p>Some text here.</p>
</div>
</body>
Overlapping (improperly nested) elements
Elements that overlap instead of nesting properly will also trigger this error. Here the <b> and <i> tags cross each other’s boundaries:
<body>
<p><b>Bold and <i>italic</b> text</i></p>
</body>
Ensure elements are closed in the reverse order they were opened:
<body>
<p><b>Bold and <i>italic</i></b><i> text</i></p>
</body>
The HTML specification is clear on this point: an end tag consists solely of </, the tag name, optional whitespace, and >. No attributes, no values, no extra content of any kind is permitted. This rule applies universally to every HTML element.
This error usually occurs due to one of a few common mistakes:
- Misplaced attributes: An attribute like class or id was accidentally typed on the closing tag instead of (or in addition to) the opening tag.
- Copy-paste errors: When duplicating or restructuring code, attributes may end up attached to the wrong tag.
- Typos or malformed tags: A missing > on the opening tag can cause the browser or validator to interpret what follows as part of the end tag.
While most browsers are forgiving and will simply ignore attributes on closing tags, this is still a problem. It signals malformed markup that can cause unpredictable behavior in parsers, screen readers, and other tools that process HTML. It also makes your code harder to read and maintain, and it may indicate a deeper structural issue — such as an attribute that was meant to be on the opening tag and is therefore not being applied at all.
Examples
Attribute accidentally placed on the closing tag
This triggers the error because class appears on the </p> end tag:
<p>Welcome to the site.</p class="welcome">
Remove the attribute from the closing tag and place it on the opening tag:
<p class="welcome">Welcome to the site.</p>
Attribute duplicated on both tags
Sometimes attributes appear on both the opening and closing tags:
<div id="sidebar" class="panel">
<p>Sidebar content</p>
</div id="sidebar">
The fix is to remove all attributes from the closing tag:
<div id="sidebar" class="panel">
<p>Sidebar content</p>
</div>
Missing > on the opening tag causing a cascade
A subtle typo on the opening tag can lead to this error. Here, the missing > after the opening <h2 causes the validator to misinterpret the markup:
<h2 class="title"Chapter One</h2>
Adding the missing > fixes the structure:
<h2 class="title">Chapter One</h2>
Multiple elements with the same mistake
This pattern sometimes appears when developers add attributes to closing tags as informal “comments” to track which element is being closed:
<div class="header">
<nav class="main-nav">
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav class="main-nav">
</div class="header">
If you want to annotate closing tags for readability, use HTML comments instead:
<div class="header">
<nav class="main-nav">
<ul>
<li><a href="/">Home</a></li>
</ul>
<!-- .main-nav -->
<!-- .header -->
HTML follows a strict stack-based nesting model. When you open an element, it becomes the “current” element, and any new element you open becomes a child of it. Closing tags must mirror the opening order in reverse. When the validator encounters </i> but the most recently opened unclosed element is something else — like <strong>, <b>, <span>, or <a> — the nesting rules are violated because the <i> element and the other element are overlapping rather than containing one another.
For example, if you write <i>...<strong>...</i>...</strong>, the <i> and <strong> elements overlap. The <i> tries to close while <strong> is still open inside it, and then <strong> tries to close outside of <i>. This creates an ambiguous structure that no valid DOM tree can represent as written. Browsers will attempt to “fix” this using error-recovery algorithms, but the result may differ across browsers and is unlikely to match your intent.
Why this matters
- Unpredictable rendering: Browser error-recovery can silently restructure your markup, leading to missing styles, broken links, or misplaced text.
- Accessibility: Screen readers rely on a well-formed DOM tree. Mis-nested elements can cause assistive technology to misinterpret the structure, reading content out of order or missing emphasis cues entirely.
- Maintainability: Overlapping tags make code harder to read and debug. Future edits are more likely to introduce additional errors.
Common causes
- Overlapping inline elements: Opening <i> and then <b> (or <strong>, <em>, <span>, etc.) but closing </i> before </b>.
- Tags crossing an anchor boundary: Starting <i> outside an <a> element but closing it inside, or vice versa.
- Copy-paste errors: Duplicating a block of HTML that includes icons (e.g., Font Awesome <i> tags) or screen-reader-only <span> elements, then editing part of it without fixing the tag order.
- Mixing presentational and semantic markup: Wrapping <i> around content that already contains <em> or <strong>, then accidentally closing in the wrong sequence.
How to fix it
- Identify the overlapping pair. The validator message usually points to the line where </i> appears. Look for the nearest unclosed element that was opened after <i>.
- Reorder the closing tags so they mirror the opening order in reverse. If you opened <i> then <strong>, close </strong> then </i>.
- If the overlap is intentional (e.g., you want bold-italic text that transitions to just bold), restructure by closing and reopening elements at the boundary rather than overlapping them.
- Consider semantic alternatives. The <i> element is for idiomatic text (technical terms, foreign phrases, thoughts). If you need emphasis, use <em>. If you only need italic styling, use CSS font-style: italic;. Whichever element you choose, the nesting rules are the same.
Examples
Incorrect — overlapping <i> and <strong>
The </i> closes while <strong> is still open inside it:
<p>
<a href="/about"><i>About <strong>Us</i></strong></a>
</p>
Correct — properly nested
Close <strong> first, then <i>:
<p>
<a href="/about"><i>About <strong>Us</strong></i></a>
</p>
Incorrect — <i> crossing an anchor boundary
<p>
<i><a href="/contact">Contact us</i></a> for more info.
</p>
Correct — keep <i> fully inside or fully outside the link
<p>
<a href="/contact"><i>Contact us</i></a> for more info.
</p>
Incorrect — overlapping inline elements with a style transition
Trying to make “bold italic” transition to “just bold” by overlapping:
<p>
<i>Italic and <b>bold-italic</i> then just bold.</b>
</p>
Correct — close and reopen at the boundary
<p>
<i>Italic and <b>bold-italic</b></i><b> then just bold.</b>
</p>
Incorrect — icon element mis-nested with a span
<button>
<i class="icon-search"><span class="sr-only">Search</i></span>
</button>
Correct — close <span> before <i>
<button>
<i class="icon-search"><span class="sr-only">Search</span></i>
</button>
A quick way to check your nesting is to read through your opening tags in order and then confirm the closing tags appear in exactly the reverse order. If you opened <a>, <i>, <strong>, the closing sequence must be </strong>, </i>, </a>. When in doubt, use your editor’s bracket-matching or tag-highlighting feature to visually trace each pair.
HTML follows strict nesting rules: elements must be closed in the reverse order they were opened, like a stack. When the validator encounters </X> but the current open element is Y, it means something has gone wrong in the document structure. The browser’s parser will attempt to recover from this mismatch, but the result may not reflect your intended layout or semantics.
There are several common causes for this error:
- Typos in tag names — for example, opening a <div> but closing it with </dvi>.
- Mismatched tags — opening one element but closing a different one, such as <strong> closed with </em>.
- Incorrect nesting order — overlapping elements where tags cross boundaries instead of being properly nested.
- Missing closing tags — a forgotten closing tag causes subsequent closing tags to be misaligned with the parser’s expectation.
This matters because improperly nested HTML can cause unpredictable rendering across browsers, break CSS styling, interfere with JavaScript DOM manipulation, and create accessibility problems for screen readers that rely on a well-formed document tree.
To fix this error, trace back from the reported line to find where the mismatch originates. Ensure that every opening tag has a corresponding closing tag with the exact same name, and that elements are closed in the correct order (last opened, first closed).
Examples
Typo in the closing tag
<!-- ❌ Wrong: closing tag is misspelled -->
<section>
<p>Hello world</p>
</secton>
<!-- ✅ Fixed: closing tag matches the opening tag -->
<section>
<p>Hello world</p>
</section>
Mismatched tags
<!-- ❌ Wrong: <strong> is closed with </em> -->
<p>This is <strong>important</em> text.</p>
<!-- ✅ Fixed: closing tag matches the opening tag -->
<p>This is <strong>important</strong> text.</p>
Incorrectly nested (overlapping) elements
<!-- ❌ Wrong: <b> and <i> overlap each other -->
<p><b>Bold <i>and italic</b> text</i></p>
The validator sees </b> when the current open element is <i>. Elements must nest completely inside one another without overlapping.
<!-- ✅ Fixed: elements are properly nested -->
<p><b>Bold <i>and italic</i></b><i> text</i></p>
Missing closing tag causing a cascade of errors
<!-- ❌ Wrong: missing </div> for the inner div -->
<div class="outer">
<div class="inner">
<p>Content</p>
</div>
Here the single </div> closes inner, leaving outer unclosed. If more HTML follows, subsequent closing tags will be misaligned, potentially producing this error further down in the document.
<!-- ✅ Fixed: both divs are properly closed -->
<div class="outer">
<div class="inner">
<p>Content</p>
</div>
</div>
Tips for debugging
- Work from the first error — in HTML validation, one early mistake can cascade into many subsequent errors. Fix the first reported mismatch and re-validate before tackling later errors.
- Use consistent indentation — properly indented code makes it much easier to spot where nesting goes wrong.
- Use an editor with bracket/tag matching — most code editors can highlight matching opening and closing tags, making mismatches immediately visible.
Every valid HTML document follows a strict structure: a <!DOCTYPE html> declaration, followed by an <html> element containing exactly two children — <head> and <body>. All visible content and its associated markup must live inside <body>. Once the browser encounters the </body> closing tag, it expects nothing else except the closing </html> tag.
When an end tag appears after </body> has been closed, the browser’s parser enters an error-recovery mode. While most browsers will attempt to handle this gracefully, the behavior is not guaranteed to be consistent. This can lead to unexpected DOM structures, which may cause issues with JavaScript that relies on the DOM tree, break CSS styling, or create accessibility problems for screen readers that depend on proper document structure.
This issue commonly arises from:
- Extra or duplicate closing tags — for example, an extra </div> that doesn’t match any open element inside <body>.
- Accidentally placing elements after </body> — such as moving a <script> or </div> outside the body during editing.
- Copy-paste errors — fragments of markup pasted in the wrong location.
- Template or CMS issues — server-side templates that inject closing tags in the wrong order.
To fix this, review your document structure carefully. Make sure every opening tag inside <body> has a matching closing tag also inside <body>. Ensure nothing appears between </body> and </html> except whitespace.
Examples
Incorrect — end tag after body is closed
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<div>
<p>Hello world</p>
</div>
</body>
</div>
</html>
Here, an extra </div> sits between </body> and </html>. This triggers the validation error because the body has already been closed when the parser encounters </div>.
Incorrect — script tag placed after body
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
<script src="app.js"></script>
</html>
While browsers will typically still execute the script, placing it after </body> is invalid and produces this warning.
Correct — all content and tags inside body
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<div>
<p>Hello world</p>
</div>
<script src="app.js"></script>
</body>
</html>
All elements, including <script> tags, are properly nested inside the <body> element. The only thing that follows </body> is </html>.
Debugging tip
If your document is large and you’re having trouble finding the stray tag, try these approaches:
- Count your tags — make sure every opening tag (like <div>) has exactly one matching </div> inside <body>.
- Use an editor with bracket matching — most code editors can highlight matching open/close tags, making orphaned tags easy to spot.
- Check the validator’s line number — the W3C validator reports the line where the stray end tag was found, which points you directly to the problem.
- Indent properly — consistent indentation makes structural problems visually obvious.
The HTML parser processes tags sequentially, maintaining a stack of open elements. When it encounters an end tag like </div>, it looks for a matching open <div> in the current scope. If no matching open element exists, the end tag is “stray” — it has nowhere to go and violates the HTML specification. Browsers will silently ignore stray end tags in most cases, but their presence signals structural problems in your markup that can lead to unpredictable rendering and layout issues.
This error matters for several reasons. First, stray end tags often indicate a deeper structural problem — if you have an extra </div>, your layout nesting may be wrong even if the browser renders it acceptably today. Second, assistive technologies like screen readers rely on correct document structure to convey meaning, and malformed HTML can confuse them. Third, clean, valid markup is easier to maintain and debug, especially in collaborative projects.
There are several common causes of this error:
Duplicate closing tags — The most frequent cause. You accidentally close the same element twice, so the second closing tag is stray.
Copy-paste remnants — When moving or deleting blocks of HTML, a closing tag gets left behind without its corresponding opening tag.
Mismatched nesting — Elements are improperly nested, causing the parser to close tags in an unexpected order and leaving orphaned end tags.
Closing void elements — Void elements like <br>, <img>, <hr>, and <input> never have closing tags. Writing </br> or </img> will produce this error.
To fix the issue, search your document for the stray end tag mentioned in the error, then either remove it if it’s a duplicate or add/move the corresponding opening tag if one is missing.
Examples
Duplicate closing tag
This is the most common scenario — an element is closed twice:
<!-- ❌ Bad: duplicate </ul> -->
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
</ul>
Remove the extra closing tag:
<!-- ✅ Good -->
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
Copy-paste leftover
After editing, a closing tag remains without its opening counterpart:
<!-- ❌ Bad: stray </p> with no matching <p> -->
<div>
<h2>Title</h2>
</p>
<span>Some text</span>
</div>
Remove the orphaned </p>:
<!-- ✅ Good -->
<div>
<h2>Title</h2>
<span>Some text</span>
</div>
Mismatched nesting
Incorrectly nested elements can produce stray end tags:
<!-- ❌ Bad: </section> closes before </div>, leaving </div> stray -->
<section>
<div>
<p>Content here</p>
</section>
</div>
Fix the nesting so inner elements close before outer ones:
<!-- ✅ Good -->
<section>
<div>
<p>Content here</p>
</div>
</section>
Closing a void element
Void elements have no closing tag. Adding one produces a stray end tag error:
<!-- ❌ Bad: <br> and <img> are void elements -->
<p>Line one<br></br>Line two</p>
<img src="photo.jpg" alt="A photo"></img>
Remove the closing tags for void elements:
<!-- ✅ Good -->
<p>Line one<br>Line two</p>
<img src="photo.jpg" alt="A photo">
Multiple stray tags from a removed wrapper
When you remove a wrapper element’s opening tag but forget the closing tag:
<!-- ❌ Bad: <main> was removed but </main> remains -->
<body>
<h1>Welcome</h1>
<p>Hello world</p>
</main>
</body>
Either remove the stray </main> or restore the opening tag:
<!-- ✅ Good: stray tag removed -->
<body>
<h1>Welcome</h1>
<p>Hello world</p>
</body>
<!-- ✅ Also good: wrapper restored -->
<body>
<main>
<h1>Welcome</h1>
<p>Hello world</p>
</main>
</body>
When dealing with deeply nested HTML, using consistent indentation and an editor with bracket/tag matching makes it much easier to spot these issues before they reach validation. Many code editors also highlight unmatched tags in real time.
¿Listo para validar tus sitios?
Comienza tu prueba gratuita hoy.