Frontend · Guide

HTML

The document itself: semantic structure, forms and native validation, media, and the metadata everything else reads.

— min read Frontend

Why HTML Comes First

Every framework you meet later compiles down to this. A React app ships HTML; if the HTML is wrong, the framework cannot save it.

HTML describes what something is, not what it looks like. A <button> is a button because of the tag, not because it is styled like one. That distinction is the whole subject: the tag you choose decides what the browser, assistive technology and search engines understand.

Get it right and a great deal comes free. A real <button> is already focusable, already fires on Enter and Space, already announces itself as a button, and already works before your JavaScript has loaded. A <div onclick> has none of that, and every attempt to add it back is a bug waiting to happen.

The document has a fixed shape: <!DOCTYPE html>, then <html lang="en">, then a <head> of metadata nobody sees and a <body> of content everybody does. The lang attribute is not decoration — screen readers pick a pronunciation from it.

Browsers never refuse to render broken HTML. They guess, silently, and their guesses differ from yours. That is why a validator is worth more here than in most languages: nothing else will tell you.

Semantic Elements

Semantic elements name the region they wrap. They produce the document outline a screen-reader user navigates by, the way a sighted reader skims headings.

ElementUse it forNotes
<header>Introductory content for the page or a sectionMore than one per page is fine
<nav>A block of navigation linksLabel it if there are several
<main>The unique content of this pageExactly one, and skip links target it
<article>Something that stands aloneA post, a card, a comment
<section>A thematic groupingNeeds a heading, or use a div
<aside>Tangential contentSidebars, pull quotes
<footer>Closing contentAuthorship, links, copyright

Headings carry the outline. <h1> to <h6> must descend without gaps — an <h4> directly under an <h2> tells a screen reader a level is missing. Choose the level for its position in the document, never for its size; size is CSS.

The test that catches most mistakes: strip every stylesheet. If the page still reads in a sensible order with an obvious hierarchy, the markup is doing its job.

Forms & Native Validation

Forms are where HTML gives away the most for free — and where hand-rolled replacements go wrong most often. Every input needs a <label> tied to it, because that label is both the accessible name and a bigger tap target.

HTML — a form the browser already understands
<!-- the label's for= matches the input's id -->
<label for="email">Work email</label>
<input
  id="email"
  name="email"
  type="email"          <!-- right keyboard on mobile, free format check -->
  autocomplete="email"
  required>

<label for="pw">Password</label>
<input id="pw" type="password" minlength="12" required>

<button>Create account</button>  <!-- submits by default -->

The type attribute is the highest-value character in a form. email, tel, url, number, date and search each change the mobile keyboard, and several bring validation with them. autocomplete lets a password manager fill the field correctly, which measurably raises completion.

AttributeWhat it enforces
requiredCannot submit while empty
minlength / maxlengthCharacter bounds on text
min / max / stepNumeric and date bounds
patternA regular expression the value must match
Native validation is a convenience for the person filling the form, never a security control. Anything can post to your endpoint. Validate on the server too, always.

Images, Video & Responsive Media

Images are usually the heaviest thing on a page, so the markup decisions here move your performance numbers more than most code will.

Always set width and height. The browser uses the ratio to reserve space before the file arrives, which stops the page jumping as images load — the single largest cause of a poor layout-shift score.

HTML — let the browser pick the file
<img
  src="photo-800.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
  sizes="(max-width: 700px) 100vw, 700px"
  width="800" height="600"
  loading="lazy"
  alt="A harbour at dawn, boats still moored">

srcset offers the browser several files and sizes tells it how wide the image will actually be laid out, so it can choose before layout happens. loading="lazy" defers anything below the fold — but never put it on the image at the top, which is usually the one being measured.

Alt text follows one rule: write what the image tells the reader, not what the picture contains. If it is purely decorative use alt="", which tells a screen reader to skip it entirely. Omitting alt altogether is the worst option — the file name gets read aloud instead.

Metadata & SEO Basics

The <head> is what everything except the reader consumes: search engines, social cards, the browser tab, and the phone deciding whether your page can be installed.

HTML — the head that matters
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Harbour at Dawn — Field Notes</title>
<meta name="description" content="What the page is about, in one sentence.">
<link rel="canonical" href="https://example.com/harbour">

<!-- the social card -->
<meta property="og:title" content="Harbour at Dawn">
<meta property="og:image" content="https://example.com/card.png">

Without the viewport tag a phone pretends to be a desktop and shrinks everything — none of your responsive CSS will apply. canonical tells search engines which URL is the real one when the same content is reachable several ways, which is how duplicate-content penalties are avoided.

Nothing in the head compensates for bad structure. Semantic markup, real headings and fast media do more for search ranking than any meta tag.

Common Mistakes

MistakeWhy it hurtsInstead
<div onclick> as a buttonNot focusable, no keyboard, not announced<button>
Heading level chosen for sizeBreaks the outline people navigate byPick by position, size with CSS
Missing altThe file name is read aloudDescribe it, or alt="" if decorative
Placeholder used as a labelVanishes on typing, poor contrastA real <label>
No width/height on imagesPage jumps as images loadAlways set both
Several <h1>, or noneNo clear page title in the outlineOne per page

Interview Questions

Why prefer a <button> over a styled <div>?

The button is focusable, activates on Enter and Space, is announced as a button, participates in form submission, and works before JavaScript loads. Reproducing all of that on a div takes a tabindex, a role, two key handlers and still misses cases.

What does the viewport meta tag actually do?

It tells a mobile browser to lay out at the device width rather than pretending to be a roughly 980px desktop and scaling down. Without it your media queries never match and everything renders tiny.

srcset versus sizes — what is the difference?

srcset lists the files available and how wide each one is. sizes tells the browser how wide the image will be once laid out. It needs both to choose correctly before layout has happened.

When should alt be empty?

When the image adds nothing a reader would miss — decoration, a spacer, an icon beside text that already says the same thing. Empty alt makes a screen reader skip it. Omitting alt entirely is different, and worse.

Is client-side validation enough?

No. It is a convenience for the person filling in the form. Anything can post to your endpoint directly, so the server has to validate regardless.

Quick Quiz

1. How many <main> elements should a page have?
2. Setting width and height on an image mainly prevents…
3. A purely decorative image should have…
4. Which gives a mobile user the right keyboard for an email field?
5. Heading levels should be chosen by…