Home  ›  Web Development  ›  HTML

WEB DEVELOPMENT / HTML

HTML: Complete Guide to HTML5, Elements, Tags & Best Practices

Learn how HTML structures modern websites — from document basics and semantic elements to forms, media, accessibility, SEO and practical HTML5 development.

This is a working reference as much as a tutorial: every concept comes with a short, valid example you can copy and adapt.

EXAMPLE: CODE AND RENDERED RESULT
index.html
<h1>Build for the Web</h1>
<p>HTML structures web content.</p>
Browser preview
Build for the Web
HTML structures web content.
HTML code editor and browser preview illustrating web document structure

THE BASICS

What Is HTML?

HTML stands for HyperText Markup Language. It’s the language used to give web content structure and meaning — marking up which part of a document is a heading, which is a paragraph, which is a link, an image, a list, a table, a form, a navigation region or a self-contained article.

HTML is a markup language, not a programming language. It has no variables, loops or logic. What it does is describe content: this text is the main heading, this group of links is the navigation, this image illustrates that figure.

When a browser receives an HTML file it parses the markup and builds an internal representation of the document, which it then uses to render the page and to expose the content to assistive technologies such as screen readers. That second part is why the choice of element matters: the meaning you encode in HTML is what software has to work with.

Modern HTML is maintained as a living standard by the WHATWG, with documentation on MDN Web Docs. It evolves continuously rather than in numbered versions, which is why there’s no “HTML 6” on the way.

HTML marks up

THE FOUNDATION

HTML vs CSS vs JavaScript

HTML — Structure

Defines what the content is: headings, paragraphs, links, images, forms and regions. It carries the meaning that browsers, search engines and assistive technologies interpret.

CSS — Presentation

Controls how that content looks: colour, typography, spacing, layout and responsive behaviour. Learn more in our CSS guide.

JavaScript — Behaviour

Adds interaction and application logic: responding to events, updating the page, fetching data. Covered in our JavaScript guide.

The division is a useful mental model, not a wall. In practice the three work together constantly — CSS selectors target HTML elements and classes, JavaScript reads and modifies the document HTML produced, and some behaviour that once needed scripting is now available in HTML and CSS directly. See the wider picture in our web development guides.

HOW IT WORKS

How HTML Works: From Source to Rendered Page

The journey from file to page is roughly this: the browser requests the HTML file, parses the markup, builds a document tree known as the DOM (Document Object Model), fetches and applies CSS, runs any JavaScript, and renders the result.

The DOM is a live, structured representation of the document that scripts can read and modify. It starts from your HTML but doesn’t stay identical to it: JavaScript can add, remove or change elements after load, and browsers correct certain markup errors while parsing. Viewing the source shows what was sent; inspecting the DOM in developer tools shows what currently exists.

This is a simplified model. Real rendering involves more stages than shown here, but the sequence is enough to reason about why markup, styles and scripts affect what appears on screen.

HTML fileSent by the server
ParsingMarkup read in order
DOMDocument tree built
CSS appliedStyles resolved
JavaScriptMay modify the DOM
Rendered pageWhat the user sees
From HTML source through parsing, the DOM, CSS and JavaScript to the rendered page

DOCUMENT STRUCTURE

Basic HTML Document Structure

Nearly every HTML page starts the same way. <!DOCTYPE html> is a declaration, not an element or a tag — it tells the browser to use standards mode rather than a legacy compatibility mode. It doesn’t “enable HTML5”; it simply signals modern parsing.

<html> is the root element and carries the lang attribute. <head> holds metadata and resource references that aren’t rendered as page content. <title> names the document. <body> contains everything the visitor actually sees.

The charset declaration should come early in the head, and the viewport meta is what makes responsive CSS behave as intended on phones.

 HTML — document boilerplateEXAMPLE
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Example Page</title>
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>
 HTML — elements and attributesEXAMPLE
<!-- Element: opening tag, content, closing tag -->
<p class="intro">Hello world</p>

<!-- Void elements have no closing tag -->
<img src="photo.jpg" alt="A laptop on a desk">
<br>
<input type="email" id="email">

<!-- Attributes configure the element -->
<a href="/about/" class="button">About us</a>

SYNTAX

Elements, Tags and Attributes

An element usually consists of an opening tag, content and a closing tag: <p>Hello</p>. A tag is just the markup delimiter — <p> on its own is a tag, while <p>Hello</p> is an element. People use the words interchangeably in conversation; technically they’re different things.

Not every element has a closing tag. Void elements such as <img>, <br>, <hr>, <input>, <meta> and <link> have no content, so they have no closing tag.

Attributes appear in the opening tag and configure the element: href on a link, src and alt on an image, type on an input. Some are global attributes that work on almost any element — id, class, title, lang, hidden, tabindex, data-* and the aria-* family. Others belong to specific elements only; href means nothing on a paragraph.

METADATA

The Head, Title, Metadata and Language

The <head> holds information about the document rather than content for the page: the title, metadata, stylesheet and script references, and occasionally a <base> element.

<title> appears in the browser tab and bookmarks, is announced by screen readers when a page loads, and is commonly used by search engines when generating a result title. Make it describe the page specifically.

The meta description is metadata that search engines may use when generating a snippet — they often rewrite it based on the query, and it isn’t a ranking guarantee. See our website SEO guides.

The viewport meta tells mobile browsers to use the device width rather than a wide virtual viewport, which is what allows responsive CSS to work as intended — more in responsive design. The lang attribute on <html> declares the document’s actual language, helping screen readers pronounce content correctly and assisting translation tools. Set it to whatever the content really is.

Comments use <!-- ... -->. They’re useful for organising markup, but they’re visible in the page source — never put anything sensitive in one.

 HTML — the headEXAMPLE
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HTML Guide: Elements, Tags and Best Practices</title>
  <meta name="description" content="Learn HTML elements, semantic markup, forms, accessibility and best practices.">
  <link rel="stylesheet" href="styles.css">
  <!-- Comments are visible in the page source -->
</head>

SEMANTIC MARKUP

Semantic HTML

Semantic HTML means choosing elements according to what the content is, rather than how you want it to look. <div class="header"> and <header> can look identical on screen; only one of them tells software anything.

The benefits are practical: assistive technologies can offer navigation by landmark and heading, the markup is easier for other developers to read, content structure is clearer to search engines, and CSS and JavaScript have meaningful hooks to work with. It’s a foundation, not a guarantee — semantic elements alone don’t make a page accessible or improve rankings, but their absence makes both harder.

<header>

Introductory or navigational content for a page or a section within it.

<nav>

A block of major navigation links. Not every group of links needs one.

<main>

The primary content of the document. One per page, and not inside header, nav, aside or footer.

<section>

A thematic grouping of content, normally with a heading.

<article>

Self-contained content that would make sense on its own — a post, a comment, a product card.

<aside>

Content tangentially related to the surrounding content, such as a sidebar or pull quote.

<footer>

Footer content for its nearest sectioning ancestor, not necessarily the whole page.

EXAMPLE: NON-SEMANTIC VS SEMANTIC
Non-semantic
<div class="header">
<div class="nav">
<div class="content">
<div class="footer">
Semantic
<header>
<nav>
<main>
<footer>
Semantic HTML structure compared with generic div-based structure

<div> and <span>

<div> is a generic block-level container and <span> a generic inline one. Both are useful when no more appropriate element exists — typically for grouping purely for styling or scripting purposes.

The anti-pattern is reaching for them first. If the content is a navigation region, an article, a button or a list, the specific element communicates more and behaves better.

TEXT

Headings, Paragraphs and Text Semantics

Headings run from <h1> to <h6> and express document structure. Choose the level that reflects the content hierarchy, then style it with CSS — picking <h4> because it looked the right size breaks navigation for screen-reader users who move between headings. Use one <h1> that states what the page is about.

Paragraphs use <p>. Don’t create spacing with strings of <br> elements; that’s a job for CSS margins.

Text-level semantics convey meaning inside a paragraph. <strong> marks strong importance and <em> stress emphasis — both differ from purely visual bold and italic. <mark> highlights relevance, <small> indicates side comments, <abbr> expands abbreviations, <time> supplies a machine-readable date, and <sub> and <sup> handle subscript and superscript.

For technical text: <code> for code fragments, <pre> for preformatted blocks, <kbd> for keyboard input, <samp> for program output and <var> for variables. For quotations, <blockquote> handles longer passages, <q> inline quotes and <cite> the title of a referenced work.

 HTML — text content and semanticsEXAMPLE
<h1>Page title</h1>
<h2>Section heading</h2>
<p>A paragraph of text with <strong>strong importance</strong>
and <em>emphasis</em>.</p>

<p>Press <kbd>Ctrl</kbd> + <kbd>S</kbd> to save.</p>
<p>Use the <code>alt</code> attribute on images.</p>
<p>Published <time datetime="2024-03-08">8 March</time>.</p>

<blockquote cite="https://example.com/source/">
  <p>A quoted passage.</p>
  <footer><cite>Source title</cite></footer>
</blockquote>
 HTML — linksEXAMPLE
<!-- Relative: within the same site -->
<a href="/web-development/css/">Learn CSS</a>

<!-- Absolute: full URL -->
<a href="https://example.com/guide/">External guide</a>

<!-- Fragment: jump within the page -->
<a href="#html-structure">Document structure</a>

<!-- Email -->
<a href="mailto:hello@example.com">Email us</a>

LINKS

Links and URLs

The anchor element <a> with an href attribute is what makes the web a web. The text between the tags is the accessible name of the link, so it should describe the destination on its own — screen-reader users often list all links out of context, where “click here” repeated eight times is useless.

Relative URLs such as /web-development/css/ point within the same site and keep working if the domain changes. Absolute URLs include the full address and are needed for external links, feeds and some metadata. Fragment links using #id jump to an element on the page. mailto: and tel: links open the relevant application.

A link navigates; it shouldn’t be used to trigger an action on the current page. That’s what a button is for — covered below.

IMAGES

Images, Alt Text and Responsive Media

<img> takes a src and an alt. Setting width and height lets the browser reserve space so the page doesn’t shift as images load, and loading="lazy" defers off-screen images — though not the main hero image, which you want as early as possible.

Alt text depends on the image’s role. An informative image gets a description of what it conveys. A functional image inside a link or button is described by its action. A decorative image takes an empty alt="" so assistive technology skips it — omitting the attribute entirely is not the same thing. Complex diagrams usually need a fuller description nearby. Never keyword-stuff alt text; see website accessibility.

srcset and sizes let the browser choose an appropriately sized file for the viewport and screen density. <picture> goes further, allowing different crops for art direction or modern formats with a fallback — the inner <img> is required and carries the alt text. <figure> with <figcaption> associates a visible caption with an image, diagram or code sample.

 HTML — imagesEXAMPLE
<!-- Informative image -->
<img src="editor.jpg" alt="Laptop displaying an HTML editor"
     width="800" height="600" loading="lazy">

<!-- Decorative image: empty alt -->
<img src="divider.svg" alt="">

<!-- Responsive image -->
<img src="small.jpg"
     srcset="small.jpg 480w, large.jpg 1200w"
     sizes="(max-width: 600px) 100vw, 50vw"
     alt="Example responsive image">

<!-- Art direction and formats -->
<picture>
  <source media="(max-width: 600px)" srcset="mobile.jpg">
  <img src="desktop.jpg" alt="Example image">
</picture>

<figure>
  <img src="diagram.png" alt="HTML document structure">
  <figcaption>Illustrative HTML document structure.</figcaption>
</figure>
 HTML — lists and tablesEXAMPLE
<ul>
  <li>HTML</li>
  <li>CSS</li>
</ul>

<ol>
  <li>Plan the content</li>
  <li>Write the markup</li>
</ol>

<dl>
  <dt>HTML</dt>
  <dd>Structure and meaning</dd>
</dl>

<table>
  <caption>Frontend technologies</caption>
  <thead>
    <tr>
      <th scope="col">Technology</th>
      <th scope="col">Purpose</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">HTML</th>
      <td>Structure</td>
    </tr>
  </tbody>
</table>

LISTS & TABLES

Lists and Accessible Tables

Lists come in three kinds. <ul> for items whose order doesn’t matter, <ol> where sequence is meaningful, and <dl> with <dt> and <dd> for term-and-description pairs such as glossaries or metadata. Navigation menus are usually marked up as lists, which lets assistive technology announce how many items there are.

Tables are for tabular data — information with a genuine row-and-column relationship — not for page layout. That was a workaround from before CSS layout existed and it produces a confusing reading order for screen readers.

Accessible tables use <th> for header cells with a scope of col or row, which ties data cells to their headers so a screen reader can announce “Technology: HTML” rather than a bare value. A <caption> gives the table a title. <thead>, <tbody> and <tfoot> group rows. Complex tables with merged cells need more careful markup, and on narrow screens a table should scroll inside its own container rather than pushing the page sideways.

FORMS

HTML Forms, Labels and Inputs

Forms are where HTML’s semantics matter most, because getting them wrong locks people out of the one thing the page exists for.

Every control needs a <label> whose for attribute matches the input’s id. That association is what lets a screen reader announce the field, and it makes the label clickable, which enlarges the target. Placeholder text is not a label — it disappears as soon as someone types and often has poor contrast. <fieldset> with <legend> groups related controls such as radio buttons. More in website accessibility.

 HTML — an accessible formEXAMPLE
<form action="/contact/" method="post">
  <label for="name">Full name</label>
  <input id="name" name="name" type="text" required autocomplete="name">

  <label for="email">Email address</label>
  <input id="email" name="email" type="email" required
         autocomplete="email">

  <label for="message">Message</label>
  <textarea id="message" name="message" rows="4"></textarea>

  <fieldset>
    <legend>Preferred contact</legend>
    <input id="byEmail" name="contact" type="radio" value="email">
    <label for="byEmail">Email</label>
    <input id="byPhone" name="contact" type="radio" value="phone">
    <label for="byPhone">Phone</label>
  </fieldset>

  <button type="submit">Send message</button>
</form>
EXAMPLE RENDERED FORM
Contact form
Full name
Your name
Email address
name@example.com
Message
How can we help?
Send message
Visual example only — not a working form.
HTML form showing labels inputs and submit button

Input types

Choosing the right type gives you appropriate mobile keyboards, built-in format checking and better autofill behaviour for free.

<input type="text">

Single-line text

<input type="email">

Email with basic format checking

<input type="password">

Masked input

<input type="number">

Numeric values with optional min and max

<input type="tel">

Telephone numbers; triggers a numeric keypad

<input type="url">

Web addresses

<input type="search">

Search fields

<input type="date">

Date picker

<input type="time">

Time values

<input type="checkbox">

Zero or more options

<input type="radio">

One option from a group

<input type="file">

File upload

Validation attributes — required, min, max, minlength, maxlength, pattern and the type itself — let the browser catch obvious mistakes before submission. This improves the experience but is not a security measure: anyone can bypass client-side checks, so always validate on the server as well.

CONTROLS

Buttons vs Links

Use a button when something happens on the current page, and a link when the location changes. The distinction isn’t pedantry: each comes with different keyboard behaviour and is announced differently by assistive technology, so the wrong choice breaks expectations.

Inside a form, <button> defaults to type="submit", which is why an unlabelled button can submit unexpectedly. Set type="button" for anything that shouldn’t submit.

Aspect
Button
Link
Purpose
ButtonPerforms an action
LinkNavigates to a URL
Markup
Button<button type="button">
Link<a href="...">
Keyboard
ButtonEnter and Space
LinkEnter
Announced as
ButtonButton
LinkLink
Types
Buttonsubmit, button, reset
Linkn/a
Misuse
ButtonA div styled as a button
LinkA link used to run a script
HTML button compared with link
 HTML — buttons and linksEXAMPLE
<!-- Action on this page -->
<button type="button">Open menu</button>

<!-- Submits the form -->
<button type="submit">Send message</button>

<!-- Navigation -->
<a href="/contact/">Contact</a>
 HTML — audio, video and iframesEXAMPLE
<audio controls>
  <source src="episode.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

<video controls poster="preview.jpg" width="800" height="450">
  <source src="demo.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en"
         label="English" default>
</video>

<iframe src="/embed/map/" title="Office location map"
        loading="lazy"></iframe>

MEDIA

Audio, Video, Captions and Iframes

<audio> and <video> embed media natively. The controls attribute exposes the browser’s own player, which is keyboard accessible by default. Multiple <source> elements let the browser pick a format it supports, and any content between the tags acts as a fallback message.

<track> adds timed text such as captions from a WebVTT file — essential for people who are deaf or hard of hearing, and useful for anyone watching without sound. Video also takes a poster image. Avoid autoplay with sound, and consider the bandwidth cost on mobile.

<iframe> embeds another document — a map, a video player, a third-party widget. Always give it a title, since screen-reader users otherwise encounter an unlabelled frame. Iframes carry security and performance implications, so only embed sources you trust, use loading="lazy" where appropriate, and size them responsively with CSS rather than fixed dimensions.

INTEGRATION

Connecting HTML to CSS and JavaScript

<link rel="stylesheet"> in the head attaches a stylesheet. Keeping presentation in CSS rather than inline style attributes makes markup readable and styles reusable — see our CSS guide.

<script> loads JavaScript. The defer attribute lets the browser continue parsing HTML and run the script once the document is parsed, in order — a sensible default for scripts that need the DOM. It isn’t right in every case: async suits independent scripts, and some code genuinely needs to run immediately. More in our JavaScript guide.

data-* attributes store custom data on an element for scripts to read, such as an identifier on a button. They’re for your own application data — they carry no meaning for browsers or assistive technology, so they never replace semantic elements or ARIA attributes.

 HTML — connecting CSS and JavaScriptEXAMPLE
<!-- In the head -->
<link rel="stylesheet" href="styles.css">

<!-- Script that can wait for parsing to finish -->
<script src="script.js" defer></script>

<!-- Custom data for scripts -->
<button type="button" data-product-id="123">View product</button>
 HTML — native semantics firstEXAMPLE
<!-- Preferred: native element -->
<button type="button" aria-expanded="false">Menu</button>

<!-- Needs rebuilding keyboard behaviour by hand -->
<div role="button" tabindex="0">Menu</div>

<!-- Naming an icon-only control -->
<button type="button" aria-label="Close dialog">×</button>

<!-- Hiding decorative content from assistive tech -->
<span aria-hidden="true">★</span>

ACCESSIBILITY

ARIA and HTML Accessibility

ARIA (Accessible Rich Internet Applications) supplies roles, states and properties for components HTML has no native element for. Useful attributes include aria-label and aria-labelledby for naming, aria-describedby for supplementary description, aria-expanded for disclosure state and aria-hidden for decorative content.

The first rule of ARIA is to prefer native HTML. A <button> arrives with focusability, keyboard activation and the correct role; a <div role="button"> has only the role — ARIA changes how something is announced, never how it behaves. Incorrect ARIA is often worse than none, because it promises capabilities that don’t exist.

Good HTML accessibility comes down to fundamentals: declare the language, write a meaningful title, keep headings logical, label every form control, use buttons and links correctly, write descriptive link text and alt text, mark up tables properly, and make sure everything works by keyboard. That’s a strong foundation — full accessibility still needs testing, covered in our website accessibility guide.

HTML IN CONTEXT

HTML for SEO, Responsive Design and Performance

HTML and SEO

A descriptive <title>, logical headings, semantic structure, descriptive link text, useful alt text, crawlable internal links and clean metadata all help search engines interpret a page. Structured data can add machine-readable context. HTML supports understanding — it doesn't guarantee rankings, which depend on content quality, relevance, technical health and competition. See website SEO.

HTML and Responsive Design

HTML supplies the content structure; CSS handles the responsive layout. The HTML side contributes the viewport meta tag, responsive images with srcset and sizes, and a source order that still makes sense when everything stacks into one column. See responsive design.

HTML and Performance

Markup affects loading: image dimensions prevent layout shift, loading="lazy" defers off-screen media, script loading attributes control blocking, and deeply nested markup enlarges the DOM. HTML alone doesn't determine speed — images, scripts, fonts and hosting matter more. See website speed.

STRUCTURE

Nesting, the Document Tree and Display Behaviour

HTML is hierarchical. Elements nest inside one another, forming parent, child and sibling relationships — a <section> containing an <h2> and a <p> makes those two children of the section and siblings of each other. That hierarchy becomes the document tree, and CSS selectors and JavaScript traversal both depend on it.

Nesting has rules. Elements must close in the reverse order they opened, and certain elements may only contain certain others — a <ul> expects <li> children, and interactive elements shouldn’t be nested inside each other. Browsers silently correct some mistakes, which is why validation is worth running.

On block and inline: elements like <div>, <p>, <section> and headings default to block-level display, while <span>, <a>, <strong> and <em> default to inline. Treat these as defaults, not fixed properties — CSS display can change them, and modern layout with flexbox and grid makes the old binary far less central than it once was.

ILLUSTRATIVE DOCUMENT TREE
html
├── head
│   ├── title
│   └── meta
│
└── body
    ├── header
    ├── main
    │   ├── h1
    │   ├── p
    │   └── section
    └── footer
Illustrative HTML document tree showing nested elements
 HTML — interactive and specialised elementsEXAMPLE
<details>
  <summary>What is HTML?</summary>
  <p>HTML structures web content.</p>
</details>

<dialog id="confirm">
  <p>Save your changes?</p>
  <button type="button">Save</button>
</dialog>

<svg width="24" height="24" viewBox="0 0 24 24"
     role="img" aria-label="Star rating">
  <title>Star</title>
  <path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z"></path>
</svg>

INTERACTIVE ELEMENTS

Details, Dialog, Template, Canvas and SVG

<details> and <summary> create a native disclosure widget — expandable content with keyboard support and state announcement built in, no JavaScript required. Useful for FAQs and optional detail, though it isn’t a full accordion component.

<dialog> represents a dialog or modal, with browser-provided focus handling and an Escape-to-close behaviour when opened as a modal. It removes a lot of custom work, but it still needs testing — focus management and screen-reader behaviour vary, and native support doesn’t remove the need to check.

<template> holds inert markup that isn’t rendered until scripts clone it — the basis of most client-side templating. <canvas> provides a scriptable drawing surface; because its contents are pixels rather than elements, anything meaningful drawn there needs an accessible alternative. SVG can be embedded inline, scales cleanly at any size and can be styled with CSS — give meaningful graphics an accessible name and hide decorative ones.

ENTITIES & SECURITY

Entities, Escaping and Basic HTML Security

Some characters are part of HTML syntax, so writing them as literal text needs an entity: &lt; for <, &gt; for >, &amp; for &, &quot; for a quotation mark. &nbsp; produces a space that won’t break across lines. Entities also cover characters awkward to type directly.

Escaping is the same idea applied for safety. When user-supplied content is inserted into a page without escaping these characters, a browser may interpret it as markup rather than text — the basis of cross-site scripting (XSS). Escaping output and sanitising untrusted HTML are handled by your server-side language or framework; this page only flags the concept.

Other basics: never put credentials, API keys or private data in HTML or comments, since source is always viewable; be selective about which sources you embed in iframes; load resources over HTTPS; and treat anything a user can submit as untrusted until proven otherwise.

 HTML — entities and escapingEXAMPLE
<!-- Showing markup as text -->
<p>Use &lt;p&gt; for paragraphs.</p>

<!-- Common entities -->
&amp;   <!-- & -->
&lt;    <!-- < -->
&gt;    <!-- > -->
&quot;  <!-- " -->
&nbsp;  <!-- non-breaking space -->

QUALITY

HTML Validation and Best Practices

Running markup through a validator catches invalid nesting, missing required attributes, duplicate IDs and structural mistakes that browsers might silently paper over. The W3C provides an official validation service, and browser developer tools reveal how markup was actually parsed. Validation checks syntax and structure only — it says nothing about whether your alt text is meaningful, your headings sensible or your page accessible.

Use Semantic HTML

Choose elements by meaning, not appearance.

Keep Structure Clear

Nest logically and close elements correctly.

Use Descriptive Links

Make the destination clear from the link text alone.

Use Accessible Forms

Associate every control with a visible label.

Write Useful Alt Text

Describe informative images; empty alt for decorative ones.

Keep Headings Logical

Levels reflect structure, styling comes from CSS.

Separate Structure and Style

Avoid inline styles; keep presentation in CSS.

Load Scripts Thoughtfully

Use defer or async appropriately for the script.

Validate and Test

Check the markup, then test the real page.

PITFALLS

Common HTML Mistakes to Avoid

Using <div> for Everything

Generic containers where semantic elements would carry meaning.

Tables for Layout

Produces a confusing reading order and fragile markup.

Missing Form Labels

Controls that assistive technology cannot identify.

Placeholder-Only Forms

The hint vanishes the moment typing starts.

Empty or Generic Links

“Click here” repeated across a page tells nobody anything.

Missing or Stuffed Alt Text

Either no alternative at all, or keywords instead of a description.

Incorrect Heading Hierarchy

Levels chosen for size, breaking navigation by heading.

Invalid Nesting

Elements closed out of order or placed where they aren't allowed.

Excessive <br> for Spacing

Layout work that belongs in CSS.

Inline Styles Everywhere

Unmaintainable, hard to override and bloats the markup.

Secrets in HTML

Anything in the source can be read by anyone.

Unnecessary ARIA

Duplicating semantics native elements already provide.

Duplicate IDs

IDs must be unique; duplicates break labels and scripts.

Mouse-Only Interactions

Handlers on non-interactive elements with no keyboard path.

Ignoring Mobile Rendering

Missing viewport meta or fixed widths that overflow.

Skipping Validation and Testing

Structural errors found by users instead of the developer.

 HTML — complete example pageEXAMPLE
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HTML Example</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <header>
    <h1>Learn HTML</h1>
    <nav aria-label="Primary">
      <ul>
        <li><a href="/web-development/html/">HTML</a></li>
        <li><a href="/web-development/css/">CSS</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <section>
      <h2>HTML basics</h2>
      <p>HTML structures content for the web.</p>
      <a href="/web-development/css/">Learn CSS next</a>
    </section>
  </main>

  <footer>
    <p>Example page</p>
  </footer>

  <script src="script.js" defer></script>
</body>
</html>

PUTTING IT TOGETHER

A Complete HTML Page

This example brings the pieces together: a declared doctype and language, character encoding and viewport in the head, a semantic structure of header, navigation, main and footer, a single <h1>, navigation marked up as a list, descriptive link text, and a deferred script at the end of the body.

It’s deliberately small. Real pages add more content, but the skeleton rarely changes — which is why learning it well pays off on every project.

ILLUSTRATIVE PAGE STRUCTURE
<!DOCTYPE html>
└── html lang="en"
    ├── head
    │   ├── title
    │   ├── meta
    │   └── link
    └── body
        ├── header
        ├── nav
        ├── main
        │   ├── section
        │   └── article
        └── footer
Illustrative HTML page structure from DOCTYPE through head and body

REFERENCE

HTML Element Reference and Cheat Sheet

A categorised quick reference rather than an exhaustive list. Many of these — the sectioning elements, <figure>, the media elements, <details> and <dialog> — are part of modern HTML’s semantic and interactive vocabulary, added to the language at different points as it evolved. For the authoritative definition of any element, use the WHATWG HTML Living Standard or MDN Web Docs rather than a summary like this one.

DOCUMENT<html><head><body>
METADATA<title><meta><link><base>
STRUCTURE<header><nav><main><section><article><aside><footer>
TEXT<h1>–<h6><p><strong><em><mark><small><abbr><time>
LINKS<a>
MEDIA<img><audio><video><picture><source><track><figure><figcaption>
LISTS<ul><ol><li><dl><dt><dd>
TABLES<table><caption><thead><tbody><tfoot><tr><th><td>
FORMS<form><label><input><textarea><select><option><button><fieldset><legend>
INTERACTIVE<details><summary><dialog><template>
TECHNICAL<code><pre><kbd><samp><var><canvas><svg><iframe>
GENERIC<div><span>
Categorised HTML element reference covering document, metadata, structure, text, links, media, lists, tables, forms, interactive, technical and generic elements

IMPROVEMENTS

Better HTML: Practical Before and After

Simplified examples — real implementations depend on context. Each change swaps a generic construct for one that carries meaning.

Common markup
Better markup
Why it helps
<div class="nav">…</div>
Better markup<nav aria-label="Primary">…</nav>
Why it helpsExposes a navigation landmark to assistive technology
<div onclick="…">Contact</div>
Better markup<a href="/contact/">Contact</a>
Why it helpsKeyboard accessible, focusable and announced as a link
<input type="email" placeholder="Email">
Better markup<label for="email">Email address</label><input id="email" type="email">
Why it helpsThe field keeps its name once typing begins
<p><b>Warning</b></p>
Better markup<p><strong>Warning</strong></p>
Why it helpsConveys importance rather than only bold styling
<div><img src="chart.png"></div>
Better markup<figure><img src="chart.png" alt="…"><figcaption>…</figcaption></figure>
Why it helpsAssociates the caption and describes the image
Comparison of generic HTML markup with more semantic alternatives

CHECKLISTS

HTML Accessibility, SEO and Quality Checklists

Three review passes over the same markup. These are practical working lists — the accessibility one is not a complete WCAG conformance test, and SEO involves many factors beyond HTML.

Accessibility

SEO

Markup quality

 HTML quality checklistEXAMPLE
ACCESSIBILITY
[ ] Document language is declared
[ ] Page has a meaningful title
[ ] Heading structure is logical
[ ] Semantic elements used appropriately
[ ] Links have descriptive text
[ ] Images have appropriate alternatives
[ ] Forms have associated labels
[ ] Buttons use the right element
[ ] Tables use proper headers
[ ] Keyboard interaction is possible
[ ] Focus remains visible
[ ] Dynamic components have accessible states
[ ] ARIA used only where needed
[ ] Important content isn't hidden from assistive tech
[ ] Multimedia has appropriate alternatives

SEO
[ ] Meaningful, descriptive title
[ ] Logical heading structure
[ ] Descriptive URLs
[ ] Crawlable links in markup
[ ] Useful text content
[ ] Descriptive image alt text
[ ] Appropriate metadata
[ ] Semantic structure
[ ] Relevant internal links
[ ] Mobile-friendly structure
[ ] Performance-conscious media
[ ] Structured data where appropriate

MARKUP QUALITY
[ ] Valid document structure
[ ] Correct nesting
[ ] Closing tags where required
[ ] Correct attributes for each element
[ ] Unique IDs
[ ] Appropriate element choices
[ ] No unnecessary markup
[ ] Forms correctly associated
[ ] Media has alternatives
[ ] Tested across relevant browsers

Validation tools

INTERVIEW PREP

Common HTML Interview Questions

Concise, technically accurate answers to the HTML questions that come up most often in interviews and assessments.

WORKFLOW

How to Build an HTML Page

01

Plan Content

Know what the page needs to say.

02

Define Structure

Decide the sections and their hierarchy.

03

Create Boilerplate

Doctype, lang, charset, viewport, title.

04

Add Semantic Elements

Header, nav, main, sections, footer.

05

Add Content

Headings, text, lists and tables.

06

Add Links and Media

Descriptive links, images with alt text.

07

Build Forms

Labels, input types, validation.

08

Connect CSS

Link stylesheets; keep styling out of markup.

09

Connect JavaScript

Load scripts with the right strategy.

10

Validate

Run the markup through a validator.

11

Test Accessibility

Keyboard, headings, labels, contrast.

12

Test Responsively

Check the full range of widths.

13

Test Performance

Images, scripts, DOM size.

14

Publish and Maintain

Keep markup current as content changes.

LEARNING PATH

HTML Learning Roadmap and Practice Projects

A workable order for learning HTML, roughly from structure outward. Accessibility and SEO appear midway rather than at the end deliberately — they’re easier to build in than to retrofit.

HTML basics
Document structure
Elements
Attributes
Text content
Links and images
Lists
Tables
Forms
Semantic HTML
Media
Accessibility
SEO
Validation
CSS integration
JavaScript integration
Build projects
Test and improve

Reading about markup only goes so far. These practice projects are suggestions to build yourself, not downloadable templates — the useful part is hitting the problems that only appear with real content.

Personal Profile Page

Beginner — headings, paragraphs, an image with alt text and a few links.

Business Website Structure

Intermediate — semantic sections, navigation, responsive images.

Contact Form Page

Intermediate — labelled inputs, appropriate types, validation attributes.

Accessible Documentation Page

Advanced — deep heading hierarchy, skip link, tables, code samples.

Semantic Blog Structure

Advanced — articles, figures, time elements, related content.

Landing Page Structure

Advanced — hero, sections, form and clear content hierarchy.

Idea
Content
HTML structure
Semantic markup
CSS
JavaScript
Accessibility
Responsive testing
Validation
Publish
HTML project workflow from idea and content through structure, styling, scripting, accessibility, testing and publishing

WORDPRESS & ELEMENTOR

HTML in WordPress and Elementor

WordPress produces HTML at every level: themes and templates define the surrounding markup, the block editor and Elementor generate the content markup, and widgets, menus and forms each output their own structure. You don’t hand-code every page — but understanding what’s produced is what lets you debug layout problems, target elements with CSS, hook into them with JavaScript, fix heading hierarchies and improve accessibility.

In Elementor specifically, most widgets let you choose the HTML tag — which heading level a title uses, whether a container renders as a <section> or a <div>. Those choices are your semantic structure. The HTML widget handles genuine gaps: an embed, a snippet, a custom element. What it shouldn’t do is hold an entire page; that throws away the responsive controls and structure Elementor provides.

The most useful habit is inspecting the generated markup in browser developer tools. It shows exactly what visitors, search engines and assistive technologies receive — which is often not what the editor preview suggests. Related: WordPress guides.

Elementor HTML best practices

Use Native Containers

Build layout with real Elementor containers rather than custom HTML blocks.

Set Heading Tags by Meaning

Choose the level for structure, adjust size separately.

Limit Custom Code

Use the HTML widget only where a specific need isn't covered.

Validate Custom Markup

Check any hand-written HTML for nesting and attribute errors.

Test Accessibility

Check labels, focus visibility and keyboard access on widgets.

Test Responsively

Confirm custom markup behaves at every breakpoint.

 HTML, CSS and JavaScript togetherEXAMPLE
<!-- HTML: structure -->
<button type="button" id="menuButton" aria-expanded="false">
  Open menu
</button>

<!-- CSS: presentation -->
<style>
  #menuButton { padding: 10px 18px; border-radius: 8px; }
</style>

<!-- JavaScript: behaviour -->
<script>
  const btn = document.getElementById("menuButton");
  btn.addEventListener("click", () => {
    const open = btn.getAttribute("aria-expanded") === "true";
    btn.setAttribute("aria-expanded", String(!open));
  });
</script>

THE FRONTEND FOUNDATION

How HTML, CSS and JavaScript Work Together

One small component shows the division clearly. The HTML declares what the control is — a button, with a state attribute. The CSS decides how it looks. The JavaScript updates the state when someone interacts with it.

Notice that the accessibility information lives in the HTML and is maintained by the JavaScript. That pattern — semantic markup as the foundation, styling layered on, behaviour keeping state accurate — is what most frontend work comes down to, whatever framework sits on top.

HTML is also where frontend development connects to everything else: React and similar libraries ultimately render HTML, PHP and Laravel generate it server-side, and website APIs supply the data that populates it.

NEXT TOPICS

Continue Learning Web Development

CSS

Learn how CSS styles HTML content and controls layout, typography, colour and responsive presentation.

JavaScript

Learn how JavaScript adds behaviour and dynamic interaction to HTML pages.

PHP

Explore server-side development and dynamic web applications.

React

Learn component-based frontend development built around JavaScript.

Laravel

Explore PHP-based web application development.

Website APIs

Understand how websites and applications exchange data with external services.

Website Accessibility

Learn how semantic HTML and accessible structures support inclusive experiences.

Website Design Basics

Learn the design fundamentals that shape the pages your markup describes.

FAQ

HTML: Frequently Asked Questions

Short answers to the questions people ask most about HTML.

Build Better Websites With HTML

Learn how HTML structures modern websites and build a stronger foundation for responsive, accessible, search-friendly and maintainable web experiences.