HTML Fundamentals & Advanced Structures

SA
StudyAI Editorial
Reviewed by StudyAI tutors
· Published Updated

From the I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic curriculum

HTML Fundamentals & Advanced Structures

TL;DR

You'll walk into the interview able to explain how a browser turns raw HTML bytes into a rendered page, why semantic tags matter beyond "cleaner code," and how native form validation actually works under the hood. You'll also be able to write accessible, production-grade markup on a whiteboard without reaching for <div> as a default. That's the difference between "knows HTML" and "understands HTML."

1. The Mental Model

HTML isn't a styling language — it's a data structure describing meaning, and the browser, screen readers, and search engines all read that meaning to decide what to do. Every tag you choose is a signal you're sending to machines that can't see pixels. Get the structure right and accessibility, SEO, and CSS hooks come almost for free. HTML is the API you expose to every non-human consumer of your page.

2. The Core Material

2.1 Semantic HTML & the Accessibility Tree

Close-up of HTML code lines highlighting web development concepts and techniques.
Photo by Pixabay on Pexels

A <div> tells the browser nothing. A <nav>, <main>, or <button> tells it exactly what role that element plays, and the browser builds a second tree alongside the DOM — the accessibility tree — from those semantics. Screen readers navigate that tree, not your visual layout. This is why a <div onclick="..."> styled to look like a button is a real bug: it has no keyboard focus, no role="button", no Enter/Space activation, and shows up as nothing to assistive tech.

<header>
  <nav aria-label="Primary">
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/products">Products</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h1>Q3 Earnings Report</h1>
    <section aria-labelledby="summary-heading">
      <h2 id="summary-heading">Summary</h2>
      <p>Revenue grew 12% year over year.</p>
    </section>
  </article>
  <aside aria-label="Related links">...</aside>
</main>
<footer>© 2024 Acme Corp</footer>

Key interview facts:
- Each page should have exactly one <h1>, and heading levels shouldn't skip (h1h3 with no h2 breaks the outline screen readers rely on).
- <section> requires an accessible name (via aria-labelledby or aria-label) to register as a landmark — otherwise it's just a styling hook.
- Native elements (<button>, <input>, <select>) come with keyboard behavior, focus states, and ARIA roles built in for free. Re-implementing a <button> with a <div> means you now own all of that yourself.

2.2 The Parsing Pipeline: Bytes → DOM → Render

Close view of computer screen displaying HTML code with an authentication error.
Photo by Markus Spiske on Pexels

This is the classic "explain what happens when you load a page" question. The browser doesn't wait for the whole HTML file — it streams bytes through a tokenizer, builds DOM nodes incrementally, and starts rendering before the full document arrives.

flowchart LR
    A["Raw HTML bytes"] --> B["Tokenizer"]
    B --> C["Tree construction (DOM)"]
    D["CSS bytes"] --> E["CSSOM"]
    C --> F{"Script tag encountered?"}
    F -- "Plain <script src>" --> G["Parser blocks: fetch + execute JS"]
    F -- "async" --> H["Fetch in parallel, execute ASAP, may reorder"]
    F -- "defer" --> I["Fetch in parallel, execute after DOM complete, in order"]
    G --> C
    C --> J["Render Tree = DOM + CSSOM"]
    E --> J
    J --> K["Layout (geometry)"]
    K --> L["Paint"]
    L --> M["Composite (GPU layers)"]

The critical detail: a plain <script> tag blocks HTML parsing entirely until it downloads and executes, because the script might call document.write() and mutate the tree. That's why the old advice was "put scripts at the bottom of <body>" — and why async/defer exist now to avoid that block without moving the tag.

  • async: downloads in parallel, executes the instant it's ready — order not guaranteed, can interrupt parsing.
  • defer: downloads in parallel, executes only after parsing finishes, in document order. This is almost always what you want for app scripts.
  • CSS never blocks parsing of the DOM, but it does block rendering — the browser won't paint until it has the CSSOM, because painting half-styled content is worse than a blank flash.

2.3 Forms & the Constraint Validation API

Close-up view of hands signing an adoption form with a pen atop a white table.
Photo by Kindel Media on Pexels

Forms are where "I know HTML" gets tested for real, because native validation is powerful and most engineers reinvent it in JS unnecessarily.

<form id="signup" novalidate>
  <label for="email">Email</label>
  <input type="email" id="email" name="email" required
         pattern=".+@company\.com" />
  <span class="error" aria-live="polite"></span>

  <label for="age">Age</label>
  <input type="number" id="age" name="age" min="18" max="99" required />

  <button type="submit">Sign up</button>
</form>
const form = document.getElementById('signup');
const email = document.getElementById('email');

form.addEventListener('submit', (e) => {
  if (!form.checkValidity()) {
    e.preventDefault();
    if (email.validity.patternMismatch) {
      email.setCustomValidity('Must be a company.com address');
    } else {
      email.setCustomValidity('');
    }
    form.reportValidity();
  }
});

The ValidityState object (email.validity) exposes booleans like valueMissing, typeMismatch, patternMismatch, rangeUnderflow — you rarely need to hand-roll regex checks in JS when the browser already computed this. novalidate on the <form> disables the browser's default popup bubbles so you can render your own error UI while still using its validation logic. FormData is the modern way to read submitted values without manually querying every input:

form.addEventListener('submit', (e) => {
  e.preventDefault();
  const data = new FormData(form);
  console.log(Object.fromEntries(data.entries()));
  // { email: "a@company.com", age: "24" }
});

3. Worked Example

Task: Build an accessible signup form that validates a username is 3–15 characters, alphanumeric only, and shows a live error message — no external libraries, pure HTML + JS.

<form id="signup-form" novalidate>
  <div class="field">
    <label for="username">Username</label>
    <input
      type="text"
      id="username"
      name="username"
      required
      minlength="3"
      maxlength="15"
      pattern="[A-Za-z0-9]+"
      aria-describedby="username-error"
    />
    <span id="username-error" role="alert" class="error"></span>
  </div>
  <button type="submit">Create account</button>
</form>
const form = document.getElementById('signup-form');
const username = document.getElementById('username');
const errorEl = document.getElementById('username-error');

function validateUsername() {
  username.setCustomValidity(''); // reset before re-checking
  if (username.validity.patternMismatch) {
    username.setCustomValidity('Letters and numbers only, no symbols');
  } else if (username.validity.tooShort) {
    username.setCustomValidity('Needs at least 3 characters');
  } else if (username.validity.valueMissing) {
    username.setCustomValidity('Username is required');
  }
  errorEl.textContent = username.validationMessage;
}

username.addEventListener('input', validateUsername);

form.addEventListener('submit', (e) => {
  validateUsername();
  if (!form.checkValidity()) {
    e.preventDefault();
    username.focus();
    return;
  }
  const data = Object.fromEntries(new FormData(form).entries());
  console.log('Submitting:', data);
});

Walk through what happens on a keystroke of "a!":

  1. The input event fires, calling validateUsername().
  2. setCustomValidity('') clears any prior error so we get a fresh check.
  3. The browser evaluates the pattern attribute against "a!" — it fails because ! isn't in [A-Za-z0-9]+, so username.validity.patternMismatch is true.
  4. We call setCustomValidity(...) with our own message, which overrides checkValidity() — the form will now report invalid even though nothing else is wrong.
  5. errorEl.textContent is set to username.validationMessage, which is exactly the string we passed to setCustomValidity. Because errorEl has role="alert", screen readers announce it immediately without the user needing to tab to it.
  6. On submit, if the user fixes it to "abc123", all validity flags clear, checkValidity() returns true, and FormData collects { username: "abc123" } for a real AJAX call.

This is the pattern interviewers want to see: native HTML validation doing the heavy lifting, JS only supplying custom messages and wiring accessibility — not reimplementing regex checks by hand in onsubmit.

4. Production Pitfalls & Best Practices

4.1 Real-World Best Practices

Captivating view of New York City skyline featuring a prominent globe sculpture and tall skyscrapers.
Photo by Following NYC on Pexels

  • Use <button type="button"> explicitly inside forms for non-submit actions — the default type for a <button> inside a <form> is submit, a classic accidental-form-submission bug.
  • Always pair <label> with for/id, not just placeholder text — placeholders disappear on input and aren't reliably read by all screen readers.
  • One <h1> per page, and treat headings as an outline, not a font-size tool — use CSS for size, headings for hierarchy.
  • Prefer defer over inline scripts at the bottom of <body> — it keeps script tags in <head> (easier to find) without blocking the parser.
  • Use <template> for client-rendered repeated markup instead of string-concatenating HTML — it's parsed once, inert until cloned, and avoids injection risk from string building.
  • Set lang on <html> — screen readers use it to pick pronunciation rules; forgetting it is a top accessibility audit failure.
  • Validate on both client and server — client-side pattern/required is UX, never security; a curl request bypasses all of it.

4.2 Common Bugs & Anti-Patterns

Bug 1: Clickable div instead of button

<!-- BAD -->
<div class="btn" onclick="submitForm()">Submit</div>
<!-- FIXED -->
<button type="submit" class="btn">Submit</button>

Bug 2: Multiple labels pointing to nothing

<!-- BAD: label not linked, screen reader announces nothing -->
<label>Email</label>
<input type="email" name="email">
<!-- FIXED -->
<label for="email">Email</label>
<input type="email" id="email" name="email">

**Bug 3: Blocking render with synchronous scrip

Frequently asked about HTML Fundamentals & Advanced Structures

You'll walk into the interview able to explain how a browser turns raw HTML bytes into a rendered page, why semantic tags matter beyond "cleaner code," and how native form validation actually works under the hood. Read the full notes above for the details.

HTML Fundamentals & Advanced Structures is a core topic in I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic. Most exam papers test it via a mix of definitions, worked examples, and applied problems. The notes above cover the high-yield sub-topics, common pitfalls, and the kind of questions examiners typically set.

Yes. Every note in the StudyAI Campus Hub is free to read. Create a free account if you want to clone the full plan, generate your own notes from your textbook, or get AI-powered practice quizzes and flashcards.

More from I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic


Get the full I want notes on jQuery, html and mysql to prepare for an interview in 2 hours. Advanced hardness. Make each a topic curriculum

Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.

Create Free Account