Chapter 14 of 14
Top 114 HTML Interview Questions
A rapid-fire reference covering the questions most likely to come up in a real interview - organized by topic and difficulty, with explanations that go beyond a one-line definition and a runnable code example for each one, so the concept sticks. Search or filter to find what you need, and share a direct link to any question.
Showing 114 of 114 questions
The first 15 of 114 questions are free to read. Sign up free to unlock every answer and track your progress.
Unlock all 114HTML (HyperText Markup Language) defines the structure and meaning of content on a web page - headings, paragraphs, lists, links, and so on. It doesn’t control appearance or behavior; CSS handles presentation and JavaScript handles interactivity. Together they form the three layers browsers combine to render a working page.
Example
<!-- HTML: structure -->
<button id="btn">Click me</button>
<!-- CSS: presentation -->
<style>#btn { color: blue; }</style>
<!-- JS: behavior -->
<script>btn.onclick = () => alert('Hi!');</script><!DOCTYPE html> tells the browser to render the page in standards mode rather than quirks mode, which mimics old, inconsistent browser behavior from the 1990s. Without it, browsers may apply different box-model and layout rules, causing subtle rendering bugs. It isn’t an HTML tag itself - it’s an instruction to the parser.
Example
<!DOCTYPE html>
<html>
<head><title>Standards Mode</title></head>
<body>Hello</body>
</html>A tag is the markup syntax itself, like <p> or </p>, while an element is the full unit - opening tag, content, and closing tag - that the tag represents. People often use the words interchangeably in casual conversation, but technically the tag is just the label and the element is the whole structure the browser builds from it.
Example
<p>Hello</p>
<!-- <p> and </p> are tags; the whole <p>Hello</p> is the element -->The DOM (Document Object Model) is the tree-like, in-memory representation the browser builds after parsing HTML. It’s what CSS selectors match against and what JavaScript reads and mutates at runtime - so the DOM can diverge from the original HTML source once scripts start modifying it. Viewing “page source” shows the original HTML; inspecting elements in devtools shows the live DOM.
Example
<ul id="list">
<li>Item</li>
</ul>
<!-- Browser builds: Document > ul#list > li -->Void elements never wrap content and have no closing tag because there’s nothing to close - examples include <br>, <img>, <hr>, <input>, <meta>, and <link>. In HTML5 the trailing slash (<br />) is optional and purely stylistic, unlike in strict XHTML where it was required.
Example
<img src="cat.jpg" alt="A cat">
<br>
<hr>
<input type="text">No - tag names and attribute names in HTML5 are case-insensitive, so <DIV> and <div> behave identically. That said, lowercase is the universal convention because it’s more readable and matches how XHTML and most style guides expect markup to look. Attribute values, however, can be case-sensitive depending on what they represent, like a file path.
Example
<DIV>Same as</DIV>
<div>this div</div>HTML comments are written as <!-- comment text -->, and the browser ignores everything between those markers when rendering. They’re not visible in the rendered page, but anyone can still see them by viewing the page source, so they should never contain sensitive information like internal notes or credentials.
Example
<!-- This won't be visible on the page -->
<p>Visible text</p>A valid document starts with <!DOCTYPE html>, then an <html> root element containing a <head> for metadata (title, charset, links to stylesheets) and a <body> for the visible content. Browsers are forgiving and will often render pages missing pieces of this structure, but omitting them risks inconsistent rendering and accessibility issues.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Page</title>
</head>
<body>
<p>Content goes here</p>
</body>
</html>Browsers ignore unknown tags entirely for rendering purposes but still add them to the DOM as generic inline elements, and they’ll still render any text content inside. This forgiving behavior is why custom elements and web components work - the browser doesn’t reject unfamiliar markup, it just treats it plainly until JavaScript upgrades it.
Example
<foo-bar>Still rendered as text</foo-bar>
<!-- Browser adds an unknown HTMLElement to the DOM -->HTML5 is the current major version of the HTML specification, introducing semantic elements (header, nav, article, section), native form validation, multimedia tags like <video> and <audio>, canvas, and APIs like local storage and geolocation. Earlier versions relied heavily on generic <div> soup and plugins like Flash for anything HTML couldn’t natively do.
Example
<!-- HTML5 semantic elements -->
<header>Site Header</header>
<nav>Navigation</nav>
<article>Post content</article>Global attributes are attributes that can be applied to virtually any HTML element, such as id, class, style, title, lang, tabindex, and data-* attributes. They exist because certain behaviors - identification, styling hooks, accessibility, custom data - are useful regardless of what element you’re working with.
Example
<p id="intro" class="lead" title="Tooltip" data-user-id="42">Hello</p>data-* attributes let you embed custom data directly on an element without inventing non-standard attributes that would fail validation, such as data-user-id="42". JavaScript can read them conveniently through the element’s dataset property, and they’re commonly used to pass server-rendered values to client-side scripts or CSS selectors.
Example
<li data-user-id="42">Jane</li>
<script>
console.log(document.querySelector('li').dataset.userId); // "42"
</script>Setting contenteditable="true" on an element makes its content directly editable by the user in the browser, similar to a rich text editor. It’s the foundation many WYSIWYG editors are built on, though it comes with quirks around pasting, cursor handling, and inconsistent behavior across browsers that usually require extra JavaScript to smooth over.
Example
<div contenteditable="true">Click and start typing here...</div>Block-level elements, like <div>, <p>, and <section>, start on a new line and take up the full available width by default. Inline elements, like <span>, <a>, and <strong>, flow within the surrounding text and only take up as much width as their content needs. This default behavior can be overridden with CSS display, but the distinction still shapes how browsers treat nesting rules.
Example
<div>Block: full width, new line</div>
<span>Inline: flows with text</span>An id must be unique within the page and is meant to identify a single specific element - useful for anchor links, form label association, and JavaScript targeting. A class can be applied to many elements and is meant for grouping elements that share styling or behavior. Using duplicate ids is invalid HTML and can cause unpredictable behavior with APIs like getElementById.
Example
<div id="header" class="box highlighted">...</div>
<div class="box">...</div>