/ HTML Checker Fixes / Unclosed Tags

How to Fix Unclosed HTML Tags

Unclosed and mismatched HTML tags are the most common HTML Checker finding. Browsers silently apply error-recovery rules so pages mostly look right, but parsers — search engines, AI crawlers, accessibility tools, CSS selectors — can interpret the same markup differently. Layout bugs that "appear randomly" usually trace back to unclosed tags somewhere upstream. This guide walks through finding, fixing, and preventing them.

1. Get the full list of unclosed tags

Step 1
Run the HTML Checker
Run the HTML Checker on your site. Export findings with URL, line number, column, and the type of error: unclosed tag, mismatched close, stray closing tag, unexpected element.
Step 2
Group findings by template
If every product page reports an unclosed div at line 234, the bug is in your product template, not in each individual product. Fixing the template fixes thousands of pages at once.

2. Trace each finding to the source

Step 1
View page source and find the line
View Source on a flagged URL. Jump to the line number reported. Look at the surrounding structure — is this template code, content from the CMS, or output from a widget/plugin?
Step 2
Identify the template
Different platforms expose templates differently:
  • WordPress: wp-content/themes/your-theme/*.php. Use Theme File Editor or SSH.
  • Shopify: Online Store → Themes → Edit Code → sections/ or snippets/.
  • Next.js / React: app/ or components/ JSX files.
  • CMS content fields: dive into the page editor; broken HTML often lives in WYSIWYG-saved content.

3. Fix common patterns

Pattern: Unclosed div

<!-- BROKEN -->
<div class="card">
  <h3>Title</h3>
  <p>Content</p>
<!-- missing </div> -->

<!-- FIXED -->
<div class="card">
  <h3>Title</h3>
  <p>Content</p>
</div>

Pattern: Mismatched closure

<!-- BROKEN -->
<section>
  <article>
    Content
  </section>
</article>

<!-- FIXED -->
<section>
  <article>
    Content
  </article>
</section>

Pattern: Wrong-syntax self-close

<!-- BROKEN (HTML5) -->
<div class="row" />

<!-- FIXED -->
<div class="row"></div>

Self-closing syntax (<tag />) only works for void elements (img, br, hr, meta, link, input) in HTML5. <div /> is parsed as a regular opening tag — the slash is ignored.

Pattern: Block element inside inline element

<!-- BROKEN (paragraph closes early) -->
<p>Some text <div>more content</div> rest of paragraph.</p>

<!-- FIXED -->
<p>Some text</p>
<div>more content</div>
<p>rest of paragraph.</p>

HTML auto-closes p when a block element appears inside. Result: the second </p> becomes a stray closing tag.

4. Audit user-generated content

⚠️ If broken HTML keeps reappearing despite template fixes, the source is probably WYSIWYG-edited content. Users pasting from Word, Google Docs, or other rich-text editors introduce malformed markup that gets saved to the database.
Step 1
Add server-side HTML sanitisation
PHP: HTMLPurifier. Node.js: DOMPurify. WordPress already runs wp_kses_post() for capabilities-limited users — extend its allowed-tags list rather than disabling it.
Step 2
Configure TinyMCE/CKEditor for strict cleanup
In TinyMCE config: valid_elements defines allowed tags, paste_word_valid_elements filters Word paste. CKEditor: config.allowedContent restricts to a known-clean schema. Reject anything outside the schema.

5. Add CI validation

Step 1
Validate every build
Add an HTML validation step to your CI pipeline:
# GitHub Actions
- name: Validate HTML
  run: npx html-validator-cli --file=dist/index.html --format=text
Fail builds on validation errors. Broken HTML never reaches production again.
Step 2
Pre-commit hooks
Even earlier: add a pre-commit hook that runs HTML validation on changed templates. Catches issues before they enter the repo.

6. Re-validate

Run the HTML Checker again. Unclosed-tag findings should drop to near-zero. Investigate any remaining errors — usually a single user-generated content piece you missed.

📐 Re-run the HTML Checker

Verify the unclosed-tag count has dropped after your fixes.

Run HTML Checker →
Related Guides: HTML Checker Fixes  ·  Fix DOCTYPE  ·  Fix Duplicate IDs  ·  HTML Checker Guide
💬 Got a problem?