Here is how to debug and validate HTML: reproduce the fault, inspect the source, fix the first useful validation error and try the page again. Do not stop at a passing report. The markup may be valid while a link still takes someone to the wrong place. Debugging means finding why that happened.
Work through the broken example below with a copy of the file beside you. There is a repaired version to compare it with, followed by commands you can reuse in a project. Save the original before editing. Otherwise it is surprisingly easy to forget which of several changes fixed the fault.

How to debug and validate HTML without guessing
Identify what failed. Write this down as the very first part of your report.
If you went to “See Materials” and nothing happened then you have a specific thing to do again. A report saying only “the website was broken” will leave the person who is going to fix it trying to figure out if they need to check the HTML, CSS, JavaScript, or the server. Include the address so someone else may find the same location on your site. The local version of workshop.html (i.e., on your computer) could be different than the published version of the page.
Test the same action again after reloading. If it does not fail until you have clicked some other button, include those steps in your documentation too. Another person should be able to get back to where you were.
Before you start editing anything in the markup, make certain you are viewing your most current work. Save all changes and then reload. Locate a unique word in your previous edit. Does it exist? Check your filename and/or folder name. It is easy to waste a lot of time clearing cache issues because you forgot you put the updated file in the wrong place.
If you are still getting familiar with the document structure, our beginner’s guide to HTML provides a complete starting example. Understanding where head and body belong makes error messages much less mysterious.
Compare the source with the browser’s DOM
View Source shows the document source delivered for that page. The Elements or Inspector panel shows the current document tree, usually called the DOM. They answer different questions. Scripts can change the tree after loading, and the browser can repair some invalid nesting as it parses the source.
Take a section written inside a paragraph. That is not a permitted relationship. The browser can close the paragraph before starting the section, so the tree in the Inspector differs from the nesting you typed. The page may still look plausible. Resist the temptation to keep adding closing tags until its spacing changes.
Select the problem element in the Inspector and look around it: which element contains it, and what sits immediately before it? Compare that with the source. For a template-based site, you need the combined output. Two individually tidy components can still produce duplicate identifiers when they appear on the same page.
Debug and validate a small HTML example
Try finding the faults in this fragment before reading the explanation. Nothing in its visible wording announces a problem. That is why inspecting the rendered page alone is not enough. Run a markup check, but follow the link yourself as well. The two checks answer different questions.
<p id="materials"><h2>Materials</h2></p>
<section id="materials">Bring a notebook.</section>
<label for="email">Email</label>
<input id="address" type="email">
<a href="#supplies">See materials</a>
Start by fixing materials: it’s labeled as an “id” in two places, but IDs must be uniquely identifiable. Next check the label (email) versus the input (address). An h2 is nested inside a p, where it does not belong. Where is supplies? The link names supplies as its destination, but this fragment has no corresponding identifier. Make each fix for a good reason. Fix the materials id so that the id isn’t duplicated, fix the nesting since the source code is incorrect.
Finally, fix the link so that you’ve created the intended destination.
A corrected complete document
Save this version as workshop.html. Open it, follow the materials link, and select the email label. The link should move to the named section. The label should focus the corresponding field. This form demonstrates markup relationships; it does not send a message or save the address anywhere.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Workshop registration</title>
</head>
<body>
<main>
<h1>Workshop registration</h1>
<p><a href="#materials">See materials</a></p>
<section id="materials">
<h2>Materials</h2>
<p>Bring a notebook.</p>
</section>
<form>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email">
</form>
</main>
</body>
</html>
“Email” is the wording a reader sees. It does not, by itself, connect the label to the field. The matching for and id values do that. The jump link works through another matching pair: its fragment and the section identifier. These are useful relationships to check whenever a control looks right but behaves strangely.
Run a repeatable HTML validation check
For a local project, install a checker as a development dependency and keep its version in your project lockfile. This gives other contributors a repeatable starting point. The HTML-validate command-line documentation explains file targets, quoted glob patterns and rule options.
npm install --save-dev html-validate
npx html-validate workshop.html
First, add the dependency to your project. Then run the checker on workshop.html. Review the first message describing an actual error. Correct that error. Save your changes. Run it again. Several later errors may disappear after that repair. They can be symptoms of the same nesting mistake, rather than separate faults.
Who is responsible for interpreting a file pattern: Your shell or the checker? If you want the checker to interpret it, quote it. If you don’t use quotes, the shell may expand it before sending it to the checker. It’s also good to know about configuration files as well. Some of these messages represent team-wide conventions. The others will help you to recognize invalid markup. Understanding this distinction will enable you to correct your mistakes with confidence.
Another option is Markuplint. Its CLI guide documents file arguments and success or failure exit codes. Use one agreed configuration for the project. Running several tools without understanding their different rules can produce a long report with no clear repair order.
npm install --save-dev markuplint
npx markuplint workshop.html
Automatic fixes deserve review. Some messages require a decision about meaning, not a mechanical text replacement. Check the diff after any fixing command and rerun the browser task. Keep deliberate broken examples outside the normal passing-file pattern, or your teaching fixture will make every build fail.
Match the symptom to the right check
| Symptom | First check | What validation misses |
|---|---|---|
| Content appears in an unexpected place | Nesting and the current DOM | Your intended reading order |
| A jump link goes nowhere | Fragment spelling and unique IDs | Which section the reader needs |
| The page has no styling | Stylesheet URL and network response | Whether the CSS achieves your design |
| A custom button does nothing | Console errors and event handling | Whether application logic is correct |
| An image is missing | Resource address and response | Whether the chosen picture is appropriate |
A valid stylesheet link can still point to a missing resource. Look at the browser’s Network panel for the actual request and response. For examples of where that link belongs, see our guide to linking CSS to HTML. Fixing the document and fixing a failed download are separate jobs.
The Console helps investigate script failures. A quiet one does not certify the HTML. Similarly, an HTML report may indicate there are no errors, but it will not verify the correctness of a script. Therefore, choose the appropriate tool for answering your current questions about the page and confirm its results by repeating the relevant visitor task.
Make validation part of a short testing routine
Return to the task you wrote down at the start. Does “See materials” now get to the section after a fresh load? Try both the keyboard and mouse. Then enlarge the text and narrow the window. Use a long heading or realistic name; short placeholders can hide layout problems.
The DWP accessibility testing guidance places HTML validation alongside automated, manual and assistive software testing. That is a useful distinction: fixing markup is one part of assessing a service, not a certificate that every person can use it.
Check representative documents after the build: one with a form, one with tables and one with shared navigation. A template problem can affect many URLs. Looking only at the original component means you never examine the complete output. Leave a brief note describing what has changed in the modified file.
Indicate what was failing; describe how to duplicate this failure; and indicate what is passing. Keep the note brief, but give the next developer enough detail to repeat the check.
Separate a page defect from a checking rule
The same care applies to generated attributes. A framework may accept a special attribute in its source template and replace it during compilation. Run the appropriate template-aware checks on the source, then validate the produced HTML. Do not delete required framework instructions merely to make a checker designed for plain HTML accept the uncompiled file.
Keep the reproduction small enough to share with a colleague. Include the opening elements that establish the context and the closing elements that finish it. A copied line by itself can hide the very nesting problem you are investigating. Remove private values from a shared example while preserving the structure that triggers the failure.
Check the repair after publishing
A successful “local pass” will give you a good idea that your changes are working, but they will not be the final word on deploying your work. Go back to the published URL; check that the new text appears, and then repeat what you originally intended to do. Confirm that this page makes the appropriate request for its stylesheets and images. Relative paths can behave differently when a document moves into a deeper directory.
When you report results, clearly indicate which tests you have performed. For example, “the duplicate ID is no longer there and the jump link goes to ‘Materials'” is a precise statement. The vague “everything is correct,” does way more than those two tests show. A specific result is easier for someone else to verify.
Questions and self-check
Does valid HTML guarantee a working website?
No. Validation checks a defined set of markup rules. It does not establish that every destination exists, that calculations are right or that the layout suits your readers. Combine it with task-based browser checks.
Should I fix every warning immediately?
Read what each message means. Fix actual errors, investigate warnings and document justified project-specific decisions. Do not suppress a message simply because the page appears to work in one browser.
Inspect the intended destination, then make the fragment and the target identifier agree. Adding CSS cannot repair that relationship.
No. Parsing repairs or script changes may explain the difference. Compare the delivered source, the current tree and the steps that produced it before assigning a cause.
The post How to Debug and Validate HTML: A Practical Workflow appeared first on HTML5 Doctor.


︎





