• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Learn web development
  1. MDN
  2. Learn web development
  3. HTML
  4. Introduction to HTML
  5. Debugging HTML

Debugging HTML

In This Article
  1. Debugging isn't scary
  2. HTML and debugging
    1. Permissive code
    2. Active learning: Studying permissive code
    3. HTML validation
    4. Active learning: Validating an HTML document
      1. Interpreting the error messages
  3. Summary
Previous Overview: Introduction to HTML Next

 

Writing HTML is fine, but what if something goes wrong, and you can't work out where the error in the code is? This article will introduce you to some tools that can help you.

Prerequisites: HTML familiarity, as covered in for example Getting started with HTML, HTML text fundamentals, and Creating hyperlinks.
Objective: Learn the basics of using debugging tools to find problems in HTML.

Debugging isn't scary

When writing code of some kind, everything is usually fine, until that dreaded moment when an error occurs — you've done something wrong, so your code doesn't work — either not at all, or not quite how you wanted it to. For example, the following shows an error reported when trying to compile a simple program written in the Rust language.

A console window showing the result of trying to compile a rust program with a missing quote around a string in a print statement. The error message reported is error: unterminated double quote string.Here, the error message is relatively easy to understand — "unterminated double quote string". If you look at the listing, you can probably see how println!(Hello, world!"); might logically be missing a double quote. However, error messages can quickly get more complicated and less easy to interpret as programs get bigger, and even simple cases can look a little intimidating to someone who doesn't know anything about Rust.

Debugging doesn't have to be scary though —  the key to being comfortable with writing and debugging any programming language or code is familiarity — with both the language and the tools.

HTML and debugging

HTML is not as complicated to understand as Rust — HTML is not compiled into a different form before the browser parses it and shows the result (it is interpreted, not compiled.) And HTML's element syntax is arguably a lot easier to understand than a "real programming language" like Rust, JavaScript or Python. The way that browsers run HTML is however a lot more permissive than how programming languages are run, which is both a good and a bad thing.

Permissive code

So what do we mean by permissive? Well, generally when you do something wrong in code, there are two main types of error that you'll come across:

  • Syntax errors: These are spelling errors in your code that actually cause the program not to run, like the Rust error shown above. These are usually ok to fix, as long as you are familiar with the right tools, and know what the error messages mean!
  • Logic errors: These are errors where the syntax is actually correct, but the code is not what you intended it to be, meaning that program runs incorrectly. These are often harder to fix than syntax errors, as there isn't an error message to direct you to the source of the error.

HTML itself doesn't tend to suffer from syntax errors because browsers run it permissively, meaning that the code still runs even if there are syntax errors present! Browsers have built-in rules to state how to interpret incorrectly written markup, so you'll get something running, even if it might not be quite what you expected. This of course can still be a problem!

Note: HTML is run permissively because when the Web was first created, it was decided that allowing people to get their content published was more important than making sure all the syntax was absolutely correct. The Web would probably not be as popular as it is today, if it had been more strict from the very beginning.

Active learning: Studying permissive code

It's time to study the permissive nature of HTML code for yourselves.

  1. First, get hold of a copy of our debug-example demo and save it somewhere locally. This is deliberately written to have some errors in it for us to explore (the HTML markup is said to be badly-formed, as opposed to well-formed.)
  2. Next, try opening it in a browser — you will see something like this: A simple HTML document with a title of HTML debugging examples, and some information about common HTML errors, such as unclosed elements, badly nested elements, and unclosed attributes.
  3. This immediately doesn't look great; let's look at the source code to see if we can work out why (only the body contents are shown):
    <h1>HTML debugging examples</h1>
    <p>What causes errors in HTML?
    <ul>
      <li>Unclosed elements: If an element is <strong>not closed properly,
          then its effect can spread to areas you didn't intend
      <li>Badly nested elements: Nesting elements properly is also very important
          for code behaving correctly. <strong>strong <em>strong emphasised?</strong>
          what is this?</em>
      <li>Unclosed attributes: Another common source of HTML problems. Let's
          look at an example: <a href="https://www.mozilla.org/>link to Mozilla
          homepage</a>
    </ul>
  4. Let's review the problems we can see here:
    • The paragraph and list item elements have no closing tags. Looking at the image above, this doesn't seem to have affected the markup rendering too badly, as it is easy to infer where one element should end, and another should begin.
    • The first <strong> element has no closing tag. This is a bit more problematic, as it isn't easy to tell where the element is supposed to end. In fact, the whole of the rest of the text looks to have been strongly emphasised.
    • This section is badly nested: <strong>strong <em>strong emphasised?</strong> what is this?</em>. It is not easy to tell how this has been interpreted, because of the previous problem.
    • The href attribute value has a missing closing double quote. This seems to have caused the biggest problem — the link has not rendered at all.
  5. Now let's look at the markup the browser has rendered, as opposed to the markup in the source code. To do this, we can use the browser developer tools. If you are not familiar with how to use your browser's developer tools, take a few minutes out to review Discover browser developer tools, then come back.
  6. In the DOM inspector, you can see what the rendered markup looks like: The HTML inspector in Firefox, with our example's paragraph highlighted, showing the text "What causes errors in HTML?" Here you can see that the paragraph element has been closed by the browser.
  7. Using the DOM inspector, let's explore our code in detail to see how the browser has tried to fix our HTML errors (we did the review in Firefox; other modern browsers should give the same result):
    • The paragraphs and list items have been given closing tags.
    • It isn't clear where the first <strong> element should be closed, so the browser has wrapped each separate block of text with its own strong tag, right down to the bottom of the document!
    • The  incorrect nesting has been fixed by the browser like this:
      <strong>strong
        <em>strong emphasised?</em>
      </strong>
      <em> what is this?</em>
    • The link with the missing attribute double quote has been deleted altogether. The last list item just looks like this:
      <li>
        <strong>Unclosed attributes: Another common source of HTML problems.
        Let's look at an example: </strong>
      </li>

HTML validation

So you can see from the above example that you really want to make sure your HTML is well-formed! But how? In a small example like the one seen above, it is pretty easy to search through the lines and find the errors, but what about a huge, complex HTML document?

The best strategy is to start by running your HTML page through the Markup Validation Service — created and maintained by the W3C, the organization that looks after the specifications that define HTML, CSS, and other web technologies. This webpage takes an HTML document as an input, goes through it, and gives you a report to tell you what is wrong with your HTML.

The HTML validator homepage

To specify the HTML to validate, you can give it a web address to point to, upload an HTML file, or directly input some HTML code.

Active learning: Validating an HTML document

Let's give this a try, and have a go at validating our sample document.

  1. First, load up the Markup Validation Service in one of your browser tabs, if it isn't already.
  2. Click on/activate the Validate by Direct Input tab.
  3. Copy the whole of the sample document's code (not just the body) and paste it into the large text area shown in the Markup Validation Service.
  4. Press the Check button.

This should give you a list of errors and other information.

A list of of HTML validation results from the W3C markup validation service

Interpreting the error messages

The list of error messages you are presented with by the validator is usually helpful, sometimes not so helpful; with a bit of practice you can work out how to interpret these to fix your code. Let's go through the error messages and what they mean. You'll see that each messages comes with a line and column number, to help you to locate the error more easily.

  • End tag li implied, but there were open elements (2 instances): These messages indicate that an element is open that should be closed. The ending tag is implied, but not actually there. The line/column information points to the first line after the line where the closing tag should really be, but this is a good enough clue to see what is up.
  • Unclosed element strong: This is really easy to understand — a <strong> element is unclosed, and the line/column information points right to where it is.
  • End tag strong violates nesting rules: This points out the incorrectly nested elements, and the line/column information points out where it is.
  • End of file reached when inside an attribute value. Ignoring tag: This one is rather cryptic; it refers to the fact that there is an attribute value not properly formed somewhere, possibly near the end of the file because the end of the file appears inside the attribute value. The fact that the browser doesn't render the link should give us a good clue as to what element is at fault.
  • End of file seen and there were open elements: This is a bit ambiguous, but basically refers to the fact there are open elements that need to be properly closed. The lines numbers point to the last few lines of the file, and this error message comes with a line of code that points out an example of an open element:
    example: <a href="https://www.mozilla.org/>link to Mozilla homepage</a> ↩ </ul>↩ </body>↩</html>

    Note: An attribute missing a closing quote mark can result in an open element, as the rest of the document is interpreted as the attribute's content.

  • Unclosed element ul: This is not very helpful, as the <ul> element is closed correctly. This error comes up because the <a> element is not closed, due to the missing closing quote mark.

If you can't work out what every error message means, don't worry about it — a good idea is to try fixing a few errors at a time, then try revalidating your HTML to show what errors are left. Sometimes fixing an earlier error will also get rid of multiple other error messages — several errors can often be caused by a single problem, in a domino effect.

You will know when all your errors are fixed when you see the following banner in your output:

Banner that reads "The document validates according to the specified schema(s) and to additional constraints checked by the validator."

Summary

So there we have it, an introduction to debugging your HTML, which should give you some useful skills to count on when you start to debug CSS, JavaScript, and other types of code later on in your career. This also marks the end of the Introduction to HTML module learning articles — now you can go on to testing yourself with our assessments: the first one is linked below.

Previous Overview: Introduction to HTML Next

 

Document Tags and Contributors

Tags: 
  • Beginner
  • CodingScripting
  • Debugging
  • Error
  • Guide
  • HTML
  • Validation
  • validator
 Contributors to this page: sideshowbarker, mustak, chrisdavidmills, breno785au, richardzacur, sockofleas
 Last updated by: sideshowbarker, May 31, 2017, 3:43:06 PM
See also
  1. Complete beginners start here!
  2. Getting started with the Web
    1. Getting started with the Web overview
    2. Installing basic software
    3. What will your website look like?
    4. Dealing with files
    5. HTML basics
    6. CSS basics
    7. JavaScript basics
    8. Publishing your website
    9. How the Web works
  3. HTML — Structuring the Web
  4. Introduction to HTML
    1. Introduction to HTML overview
    2. Getting started with HTML
    3. What's in the head? Metadata in HTML
    4. HTML text fundamentals
    5. Creating hyperlinks
    6. Advanced text formatting
    7. Document and website structure
    8. Debugging HTML
    9. Assessment: Marking up a letter
    10. Assessment: Structuring a page of content
  5. Multimedia and embedding
    1. Multimedia and embedding overview
    2. Images in HTML
    3. Video and audio content
    4. From object to iframe — other embedding technologies
    5. Adding vector graphics to the Web
    6. Responsive images
    7. Assessment: Mozilla splash page
  6. HTML tables
    1. HTML tables overview
    2. HTML table basics
    3. HTML Table advanced features and accessibility
    4. Assessment: Structuring planet data
  7. CSS — Styling the Web
  8. Introduction to CSS
    1. Introduction to CSS overview
    2. How CSS works
    3. CSS syntax
    4. Selectors introduction
    5. Simple selectors
    6. Attribute selectors
    7. Pseudo-classes and pseudo-elements
    8. Combinators and multiple selectors
    9. CSS values and units
    10. Cascade and inheritance
    11. The box model
    12. Debugging CSS
    13. Assessment: Fundamental CSS comprehension
  9. Styling text
    1. Styling text overview
    2. Fundamental text and font styling
    3. Styling lists
    4. Styling links
    5. Web fonts
    6. Assessment: Typesetting a community school homepage
  10. Styling boxes
    1. Styling boxes overview
    2. Box model recap
    3. Backgrounds
    4. Borders
    5. Styling tables
    6. Advanced box effects
    7. Assessment: Creating fancy letterheaded paper
    8. Assessment: A cool-looking box
  11. CSS layout
    1. CSS layout overview
    2. Introduction
    3. Floats
    4. Positioning
    5. Practical positioning examples
    6. Flexbox
    7. Grids
  12. JavaScript — Dynamic client-side scripting
  13. JavaScript first steps
    1. JavaScript first steps overview
    2. What is JavaScript?
    3. A first splash into JavaScript
    4. What went wrong? Troubleshooting JavaScript
    5. Storing the information you need — Variables
    6. Basic in JavaScript — Numbers and operators
    7. Handling text — Strings in JavaScript
    8. Useful string methods
    9. Arrays
    10. Assessment: Silly story generator
  14. JavaScript building blocks
    1. JavaScript building blocks overview
    2. Making decisions in your code — Conditionals
    3. Looping code
    4. Functions — Reusable blocks of code
    5. Build your own function
    6. Function return values
    7. Introduction to events
    8. Assessment: Image gallery
  15. Introducing JavaScript objects
    1. Introducing JavaScript objects overview
    2. Object basics
    3. Object-oriented JavaScript for beginners
    4. Object prototypes
    5. Inheritance in JavaScript
    6. Working with JSON data
    7. Object building practise
    8. Assessment: Adding features to our bouncing balls demo
  16. Accessibility — Make the web usable by everyone
  17. Accessibility guides
    1. Accessibility overview
    2. What is accessibility?
    3. HTML: A good basis for accessibility
    4. CSS and JavaScript accessibility best practices
    5. WAI-ARIA basics
    6. Accessible multimedia
    7. Mobile accessibility
  18. Accessibility assessment
    1. Assessment: Accessibility troubleshooting
  19. Tools and testing
  20. Cross browser testing
    1. Cross browser testing overview
    2. Introduction to cross browser testing
    3. Strategies for carrying out testing
    4. Handling common HTML and CSS problems
    5. Handling common JavaScript problems
    6. Handling common accessibility problems
    7. Implementing feature detection
    8. Introduction to automated testing
    9. Setting up your own test automation environment
  21. Server-side website programming
  22. First steps
    1. First steps overview
    2. Introduction to the server-side
    3. Client-Server overview
    4. Server-side web frameworks
    5. Website security
  23. Django web framework (Python)
    1. Django web framework (Python) overview
    2. Introduction
    3. Setting up a development environment
    4. Tutorial: The Local Library website
    5. Tutorial Part 2: Creating a skeleton website
    6. Tutorial Part 3: Using models
    7. Tutorial Part 4: Django admin site
    8. Tutorial Part 5: Creating our home page
    9. Tutorial Part 6: Generic list and detail views
    10. Tutorial Part 7: Sessions framework
    11. Tutorial Part 8: User authentication and permissions
    12. Tutorial Part 9: Working with forms
    13. Tutorial Part 10: Testing a Django web application
    14. Tutorial Part 11: Deploying Django to production
    15. Web application security
    16. Assessment: DIY mini blog
  24. Express Web Framework (node.js/JavaScript)
    1. Express Web Framework (Node.js/JavaScript) overview
    2. Express/Node introduction
    3. Setting up a Node (Express) development environment
    4. Express tutorial: The Local Library website
    5. Express Tutorial Part 2: Creating a skeleton website
    6. Express Tutorial Part 3: Using a database (with Mongoose)
    7. Express Tutorial Part 4: Routes and controllers
    8. Express Tutorial Part 5: Displaying library data
    9. Express Tutorial Part 6: Working with forms
    10. Express Tutorial Part 7: Deploying to production
  25. Further resources
  26. Advanced learning material
    1. WebGL: Graphics processing
  27. Common questions
    1. HTML questions
    2. CSS questions
    3. JavaScript questions
    4. How the Web works
    5. Tools and setup
    6. Design and accessibility
  28. How to contribute