Programming with AI
ENRU
8.2

Reading HTML

structure, semantics, attributes

What it is

HTML is not a programming language but markup: it describes what a page is made of. Reading it is easy, and for working with an AI that is enough: you have to understand what structure it proposed and be able to say what you want instead.

What it looks like in code

<article class="card" data-city="oslo">
  <h2 class="card__title">Oslo</h2>
  <p class="card__temp">Currently <strong>+4</strong></p>
  <button type="button" aria-label="Remove subscription">×</button>
</article>

How to read it

A tag opens and closes: <p> … </p>. Some need no closing: <img>, <input>, <br>.

Nesting = structure. <strong> inside <p> inside <article> — a tree, the DOM from article 8.1. Indentation in the code affects nothing; only the nesting matters.

Attributes are name="value" pairs in the opening tag:

AttributeWhat for
classa hook for CSS and JS; many elements can share one
ida unique name; there should be one per page
data-*your own data: data-city="oslo" can be read from JS
type, href, srcmeaningful ones, depending on the tag
aria-*hints for screen readers

Semantics

Tags differ not in appearance but in meaning. <div> means nothing; <article>, <nav>, <header>, <button> do.

The difference is practical, not aesthetic:

<div class="btn" onclick="remove()">×</div>   <!-- don't do this -->
<button type="button" onclick="remove()">×</button>

A <button> is reachable from the keyboard by itself, activates on space and Enter by itself, and tells screen readers by itself that it is a button. A <div> does none of that — all of it has to be added by hand, and usually gets forgotten.

The reading rule: when you see a <div> with a click handler, there should almost always be a <button> or an <a> there.

Forms

<form>
  <label for="city">City</label>
  <input id="city" name="city" type="text" required minlength="2">
  <button type="submit">Subscribe</button>
</form>

Three things to check in forms:

  • The label is tied to the field by for = id. Without it, clicking the label doesn't put the cursor in the field.
  • name — the value travels to the server under this name. No name and the field isn't sent at all.
  • required, minlength, type="email" — validation on the browser side. Convenient for the user, and no substitute for validation on the server (article 7.3): a request can be sent bypassing the form.

The document's structure

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Weather</title>
    <link rel="stylesheet" href="/style.css">
  </head>
  <body>
    …
    <script src="/app.js"></script>
  </body>
</html>

<head> is housekeeping, invisible on the page. <body> is what is visible. lang="en" affects hyphenation and how screen readers pronounce things, and viewport affects how the page looks on a phone. Without it a mobile browser shows a shrunken desktop version.

What to tell the AI

Prompt
Rewrite this markup semantically: divs with handlers become
buttons, navigation blocks become nav, headings by level.
Don't touch the classes or the styles.
Prompt
Check the form: does every field have a name and a linked
label, are the basic constraints there? A list of problems,
no edits.
Prompt
I want a city card: name, temperature, remove button.
Propose the markup — semantic, with BEM-style classes.
No styles needed yet.

What to look for

A <div> instead of a button or a link. The most common problem in generated markup.

No alt on images. <img src="..." alt=""> — an empty alt is fine for decorative images, a missing one is not.

Headings out of order. <h1> then straight to <h4> — the document's structure breaks for anyone reading it with a program.

Styles inline in the markup. style="margin-top: 10px" on every element means changing it later in twenty places.

A repeated id. It must be unique; duplicates break CSS, JS, and the label-to-field link.

Markup five <div> levels deep. A sign the AI built the structure around the appearance rather than the meaning.

Cheat sheet

  • Nesting is the structure; indentation affects nothing.

  • class for many, id for one, data-* for your own data.

  • A <div> with a click handler should almost always be a <button>.

  • In a form check: name, a linked label, constraints.

  • Browser validation does not replace server validation.

  • viewport in the <head>, or the page shrinks on a phone.