Right-click any element on a page and choose Inspect. Chrome opens DevTools with that element selected in the Elements panel, and you can read its tag, attributes, applied styles and position in the tree. Ctrl+Shift+C (Cmd+Shift+C on macOS) does the same thing without the context menu: it puts you straight into element-picking mode.
That gets you looking at markup in about two seconds. The harder part is knowing what you're looking at, because the HTML in the Elements panel is usually not the HTML the server sent.
View source and inspect show you different things
Ctrl+U opens the raw response body: exactly the bytes the server returned, before the browser parsed anything. The Elements panel shows the live DOM after parsing, after error correction, and after every script on the page has finished mutating it.
On a server-rendered site the two are close. On a React or Vue app they can be completely different documents. If you're debugging why Google sees an empty page, view-source is the one that matters. If you're debugging why a click handler isn't firing, the DOM is the one that matters.
| Question | Where to look |
|---|---|
| Did the server send this markup? | View source (Ctrl+U) |
| What does the page look like right now? | Elements panel |
Why did the browser move my <div> out of my <table>? | Both, compared side by side |
| What will a crawler that doesn't run JS see? | View source |
| What will a screen reader announce? | Accessibility tree, not either one |
A workflow for tracking down a markup bug
- 1
Start from the symptom, not the tree
Pick the element that looks wrong, not the section that contains it. Inspecting the visible symptom takes you to the exact node; scrolling the DOM tree looking for it wastes time.
- 2
Walk up the ancestors
Layout problems are almost always inherited. In the Elements panel, the breadcrumb trail at the bottom shows the ancestor chain. Click up it one level at a time and watch which parent is actually setting the width, the overflow or the stacking context.
- 3
Check what the element really is
A
<div role="button">and a<button>look identical on screen and behave nothing alike. Confirm the tag before you debug the behaviour. - 4
Compare against the source
If the DOM has elements your template never wrote, something injected them: a script, an extension, or the parser fixing invalid nesting.
- 5
Edit in place to confirm
Double-click an attribute and change it. If removing a class fixes the layout, you've found your culprit without touching the codebase.
The markup problems worth checking on every page
Most HTML bugs aren't syntax errors. They're structural choices that quietly break something else downstream.
Heading order
Headings are a document outline, not a font-size picker. A page that goes h1 → h3 → h2 reads as a broken hierarchy to screen readers and to search engines. Two <h1> elements on the same page is a smell, though not the ranking disaster it's sometimes made out to be.
Duplicate IDs
document.getElementById returns the first match and silently ignores the rest. So does <label for="…">. Duplicate IDs are one of the most common causes of "the click handler works on the first card but not the others."
Invalid nesting
<!-- Looks fine. Parses into three separate elements. -->
<p>
Some intro text
<div class="callout">A callout</div>
</p>
<!-- Interactive content can't nest -->
<a href="/pricing">
<button>Buy now</button>
</a>Elements with no accessible name
Icon-only buttons, links wrapped around a bare <svg>, inputs with a placeholder but no label. Visually they're fine. In the accessibility tree they're anonymous, and anyone using a screen reader hears "button" with no idea what it does.
Deprecated and abandoned markup
<center>, <font>, align attributes, <table> used for layout. These still render, which is exactly why they survive in old templates for years.

Seeing structure without reading the tree
Reading a DOM tree is precise but slow. For structural questions, drawing the answer onto the page itself is usually faster: outline every heading and read the hierarchy at a glance, outline every table cell to spot a layout table, outline positioned elements to find the one breaking your stacking order.
This is the kind of thing Web Developer Tools is built for. Its HTML & DOM category has around 48 tools that annotate the live page: Outline Headings labels every h1–h6 in place, Display Id & Class Details stamps each element with its identifiers, Display ARIA Roles shows which elements carry a role, and Display Element Information docks a panel that updates as you hover. There are also targeted detectors for the problems above, including Duplicate HTML IDs, Invalid HTML Nesting Detector, Empty Elements Detector and Missing Lang Attribute Detector.
None of this replaces DevTools. It sits alongside it, for the moments when you want a whole-page answer instead of a single-node one.
Editing HTML on a live page
The Elements panel is editable, and changes apply immediately. That makes it a fast way to test a fix before writing any code.
- Double-click a tag name to rename an element
- Double-click an attribute value to change it
- Press
F2(or right-click → Edit as HTML) to edit a whole subtree as text - Right-click → Copy → Copy outerHTML to lift the markup into your editor
- Drag a node in the tree to move it, which is a quick way to test whether source order is the problem
Everything you change is thrown away on reload. That's a feature: you can be as destructive as you like.
When the markup you need is hidden
Three cases regularly stop people:
- 1Shadow DOM. Web components hide their internals behind a shadow root. DevTools shows them under a
#shadow-rootnode, butdocument.querySelectorwon't reach inside. - 2Iframes. Embedded widgets, payment forms and ad slots are separate documents with separate DOMs. Select the iframe's context in the Console dropdown before running anything.
- 3Elements that disappear on hover. Dropdowns and tooltips vanish the moment you move the mouse toward DevTools. Right-click the trigger in the Elements panel and use Force state →
:hover, or set adebuggerstatement on the event that closes it.
Validate before you go looking for ghosts
If a page behaves strangely in one browser and not another, run it through the W3C validator before spending an afternoon on it. Unclosed tags and duplicate attributes produce different error recovery in different engines, and that inconsistency is usually the whole bug.
WDT can hand the current URL straight to the validator with Validate HTML, which saves the copy-paste step. For pages behind a login, validating the generated source is more useful than validating the URL, since the validator can't see anything that requires a session.
Where to go next
Markup problems rarely stay markup problems. Missing labels and broken heading order turn into accessibility failures; missing canonical tags and thin <head> metadata turn into technical SEO issues. If you're inspecting HTML because a release is coming, the pre-launch QA checklist covers the structural checks worth doing systematically rather than ad hoc.