// Complete Course · Beginner to Confident

Learn HTML
A to Z

Master every HTML tag, element, and concept in 3 focused days. With real examples, hands-on tasks, quizzes, and a final project.

📅 Day 1 — Foundations 📅 Day 2 — Structure & Forms 📅 Day 3 — Advanced & Project
Day 01
Foundations
  • What is HTML & how browsers work
  • Document structure & boilerplate
  • Headings, paragraphs, text tags
  • Links, images, lists
  • Build your first page
Day 02
Structure & Forms
  • Tables & data display
  • Forms, inputs, buttons
  • Semantic HTML5 elements
  • Div, Span, layout blocks
  • Attributes, Meta, SEO
Day 03
Advanced & Project
  • Audio, video, iframes
  • HTML5 APIs (Canvas, Storage)
  • Accessibility & ARIA
  • HTML + CSS + JS connections
  • Final Portfolio Project
01
Day One
Foundations of HTML
Structure, text, links, images, lists
Lesson 01

What is HTML?

HTML (HyperText Markup Language) is the standard language for creating web pages. It tells the browser what content to show and what structure it has.

How it works

A browser reads your HTML file from top to bottom. Each tag wraps content and tells the browser how to treat it. HTML is NOT a programming language — it's a markup language.

💡 HTML vs CSS vs JS: HTML = Structure (skeleton). CSS = Style (skin & clothes). JavaScript = Behavior (muscles & brain).

Tags, Elements & Attributes

Tag
A keyword inside angle brackets. Example: <p>. Most tags come in pairs: opening <p> and closing </p>. The slash / means "closing tag"
Element
Opening tag + content + closing tag together. <p>Hello</p> is one paragraph element.
Attribute
Extra info added inside the opening tag. Example: <a href="url">href is the attribute, "url" is its value.
Void tag
Self-closing tags that have no content. Examples: <br>, <img>, <input>. They do not need a closing tag.
anatomy.html
<!-- This is an element -->
<p class="greeting">Hello, World!</p>

<!-- └── opening tag   attribute  value  content  closing tag -->

<!-- Void element (self-closing) -->
<img src="photo.jpg" alt="A photo">
Lesson 02

HTML Document Structure

Every HTML page follows a standard boilerplate. This is the skeleton every page must have.

index.html — full boilerplate
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My First Web Page</title>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <h1>Hello, World!</h1>
    <p>This is my first page.</p>

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

</html>
<!DOCTYPE>
Tells browser this is HTML5. Always the very first line. Without it, browser goes into "quirks mode" (old, broken rendering). First line of every HTML file
<html>
Root element. Wraps everything. The lang attribute tells search engines and screen readers the page language. Wraps entire document
<head>
Invisible section. Contains meta info, title, links to CSS/fonts. Nothing here appears on screen. Inside <html>, before <body>
<title>
Page title shown in browser tab and search engine results. Very important for SEO. Inside <head>
<body>
Everything visible on the page goes here. Text, images, links, buttons, everything. Inside <html>, after <head>
<meta charset>
Sets character encoding to UTF-8 — supports all languages including Bengali, Arabic, Japanese, emojis 🎉. Inside <head>
<meta viewport>
Makes the page mobile-responsive. Without this, phones show a zoomed-out desktop version. Inside <head>
🔗 Connection
The <head> section is where you link CSS (<link>) and load JS (<script>). The browser reads head first — that's why CSS loads before the page renders, preventing a flash of unstyled content.
Lesson 03

Headings & Paragraphs

The most fundamental text elements. Headings create hierarchy; paragraphs wrap prose content.

<h1>
Main page heading. Only ONE per page. Biggest, boldest. Crucial for SEO — search engines use it to understand page topic. Once per page, inside <body>
<h2>
Section headings. Use for major sections. Can be used multiple times. Inside sections or articles
<h3> — <h6>
Sub-section headings. h3 inside h2 sections, h4 inside h3, etc. Think of it like an outline. As needed for nested sections
<p>
Paragraph of text. Browsers automatically add space above and below. The most common text element. Any block of prose text
<br>
Line break. Moves to next line without starting a new paragraph. Used in poems, addresses, lyrics. Inside p, address, poetry
<hr>
Horizontal rule. Creates a visible dividing line between content sections. Between major content sections
headings.html
<h1>My Blog</h1>
<h2>Web Development</h2>
<h3>Getting Started with HTML</h3>
<p>HTML is the backbone of every website on the internet.</p>
<p>Once you learn it, you can build anything.</p>
<hr>
<h2>CSS Basics</h2>
<p>After HTML, you style things with CSS.</p>
⚠️ Don't use headings for size. Never use <h3> just because you want smaller text. Use headings for structure. Use CSS for size. Screen readers navigate pages by heading hierarchy.
Lesson 04

Text Formatting Tags

HTML has a rich set of tags for marking up and formatting text — from bold and italic to quotes and abbreviations.

<strong>
Important text — renders bold AND tells browsers/screen readers "this is important". Inside paragraphs for important words
<b>
Bold text — visually bold but NO semantic meaning. Use <strong> for importance; use <b> for style-only bold (like product names).
<em>
Emphasized text — italic + semantic emphasis. Screen readers stress the word when reading aloud.
<i>
Italic text — visual only. Good for foreign words, technical terms, book titles.
<u>
Underlined text. Careful — users often confuse underlined text with links. Use sparingly.
<s>
Strikethrough text. Used for prices that have been reduced, deleted items, etc. $99 → $49.
<mark>
Highlighted text — like a yellow marker. Used for search result highlights.
<small>
Fine print / smaller text. Copyright notices, legal disclaimers, footnotes.
<sup>
Superscript — raised text. Used for math (x²), footnotes, ordinals (1st).
<sub>
Subscript — lowered text. Used for chemical formulas: H₂O, CO₂.
<code>
Inline code snippet. Renders in monospace font. For showing code within sentences. Inside paragraphs with code references
<pre>
Preformatted text — preserves ALL whitespace and line breaks. Used for code blocks, ASCII art. For multi-line code samples
<blockquote>
Long quotes from other sources. Browser indents it. Use cite attribute for source URL.
<q>
Short inline quote. Browser adds quotation marks automatically.
<abbr>
Abbreviation. Use title attribute for full form. Shows tooltip on hover.
<address>
Contact information. Email, phone, physical address. Renders in italic by default.
<time>
Date/time in machine-readable format. <time datetime="2025-01-01">New Year</time>
<del> / <ins>
Deleted and inserted text. For showing document edits or changelog-style diffs.
text-formatting.html
<p>The price is <s>$99</s> now <strong>$49</strong><small> (limited time)</small></p>

<p>Water is H<sub>2</sub>O. Area = πr<sup>2</sup></p>

<p>Search results for <mark>HTML course</mark></p>

<abbr title="HyperText Markup Language">HTML</abbr>

<blockquote cite="https://example.com">
  The web is more a social creation than a technical one.
</blockquote>

<pre><code>
  function greet() {
    return "Hello";
  }
</code></pre>
Lesson 05

Links & Navigation

The <a> (anchor) tag is one of the most important HTML elements. It's what makes the web a web — everything is connected through links.

<a href>
Creates a hyperlink. href = destination URL. Can link to external sites, pages, sections, emails, phone numbers.
target="_blank"
Opens link in new tab. Always add rel="noopener noreferrer" with it for security.
href="#id"
Anchor link — jumps to an element with that ID on the same page. Used for table of contents, skip links.
href="mailto:"
Opens email client. <a href="mailto:you@email.com">
href="tel:"
Dials phone number on mobile. <a href="tel:+8801700000000">
download
Forces download instead of navigating. <a href="file.pdf" download>
links.html
<!-- External link (opens in new tab) -->
<a href="https://google.com" target="_blank" rel="noopener noreferrer">
  Visit Google
</a>

<!-- Internal page link -->
<a href="about.html">About Us</a>

<!-- Jump to section on same page -->
<a href="#contact">Jump to Contact</a>
<section id="contact">Contact Section</section>

<!-- Email link -->
<a href="mailto:hello@shifat.dev">Send Email</a>

<!-- Phone link (works on mobile) -->
<a href="tel:+8801700000000">Call Us</a>

<!-- Download link -->
<a href="resume.pdf" download>Download CV</a>
🔗 Connection to CSS & JS
Links are styled with CSS using a { color: blue; } and states like a:hover, a:visited. In JavaScript, you can navigate with window.location.href = 'url' and intercept link clicks with event.preventDefault().
Lesson 06

Images & Media

Images make pages visual. HTML supports raster images (jpg, png, gif, webp) and vector images (svg).

<img>
Embeds an image. src = image path/URL. alt = description for screen readers and when image fails. ALWAYS include alt attribute. No closing tag needed.
width / height
Size attributes on <img>. Setting both prevents layout shift while image loads (good for performance).
loading="lazy"
Lazy loading — image only loads when it enters viewport. Huge performance boost for image-heavy pages.
<figure>
Container for image + caption. Semantically groups an image with its caption. When image needs a caption
<figcaption>
Caption for a figure. Goes inside <figure>, before or after the image.
<picture>
Responsive images. Lets browser choose the best image format/size for device. Uses <source> elements inside.
<svg>
Scalable Vector Graphics. Can be inline in HTML. Scales to any size without blur. Used for icons, logos, charts.
<map> / <area>
Image maps — clickable areas within a single image. Rarely used today but good to know.
images.html
<!-- Basic image -->
<img src="profile.jpg" alt="Profile photo of Shifat" width="300" height="300">

<!-- Lazy-loaded image -->
<img src="hero-bg.jpg" alt="Hero background" loading="lazy">

<!-- Image with caption -->
<figure>
  <img src="chart.png" alt="Q3 Revenue Chart">
  <figcaption>Q3 Revenue — 40% increase over Q2</figcaption>
</figure>

<!-- Responsive image (browser picks best format) -->
<picture>
  <source srcset="hero.webp" type="image/webp">
  <source srcset="hero.jpg" type="image/jpeg">
  <img src="hero.jpg" alt="Hero image">
</picture>

<!-- Inline SVG icon -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
  <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
</svg>
Lesson 07

Lists

Lists are everywhere on the web — navigation menus, bullet points, numbered steps, definition glossaries. HTML has 3 types.

<ul>
Unordered list — bullet points. When order doesn't matter. Ingredients, features, options.
<ol>
Ordered list — numbered. When sequence matters. Steps, rankings, instructions.
<li>
List item. Goes inside <ul> or <ol>. Can contain any HTML.
<dl>
Description list — term + definition pairs. Like a glossary or FAQ.
<dt>
Description term — the word or term being defined. Goes inside <dl>.
<dd>
Description detail — the definition. Pairs with <dt> inside <dl>.
lists.html
<!-- Unordered list -->
<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

<!-- Ordered list (steps) -->
<ol>
  <li>Create HTML file</li>
  <li>Write structure</li>
  <li>Open in browser</li>
</ol>

<!-- Nested list -->
<ul>
  <li>Frontend
    <ul>
      <li>HTML</li>
      <li>CSS</li>
    </ul>
  </li>
</ul>

<!-- Description list (glossary) -->
<dl>
  <dt>HTML</dt>
  <dd>HyperText Markup Language — structures web pages</dd>
  <dt>CSS</dt>
  <dd>Cascading Style Sheets — styles web pages</dd>
</dl>
💡 Navigation menus are lists! Almost all web navbars are built with <ul><li><a> and then styled with CSS to look horizontal. This is the semantic correct pattern.
Day 1 — Task

Build Your First Page 🏗️

🎯 Task: Personal Bio Page
Build a complete personal bio page using only what you've learned today:
  1. Create index.html with full boilerplate
  2. Add a proper <title> and <h1>
  3. Write 2–3 paragraphs about yourself
  4. Add your skills as an unordered list
  5. Add 3+ links (GitHub, Twitter, email)
  6. Add at least one image with descriptive alt text
  7. Use <strong>, <em>, <mark> somewhere
  8. Bonus: Add a "Tech Stack" description list (<dl>)
Quick Quiz: What tag should you use for the most important heading on a page?
<heading>
<h1>
<h2>
<title>
02
Day Two
Structure, Forms & Semantics
Tables, inputs, semantic layout, attributes, meta
Lesson 08

Tables

Tables display tabular data — spreadsheet-style. They're not for page layout (that's CSS Grid/Flexbox). Use them for schedules, pricing, data comparisons.

<table>
Container for the whole table. All other table elements go inside.
<thead>
Table header section. Groups the header rows. Screen readers and browsers treat it differently.
<tbody>
Table body. Groups the data rows. Required for accessibility.
<tfoot>
Table footer. Totals, averages, summary row. Browser renders it at the bottom even if coded elsewhere.
<tr>
Table row. Goes inside thead, tbody, or tfoot.
<th>
Table header cell. Bold, centered by default. Use scope="col" or scope="row" for accessibility.
<td>
Table data cell. Regular cell. Use colspan to span columns, rowspan to span rows.
<caption>
Table title/description. Goes immediately after <table>. Important for accessibility.
table.html
<table>
  <caption>Course Pricing Plans</caption>

  <thead>
    <tr>
      <th scope="col">Plan</th>
      <th scope="col">Price</th>
      <th scope="col">Features</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Free</td>
      <td>$0</td>
      <td>5 courses</td>
    </tr>
    <tr>
      <td>Pro</td>
      <td>$29/mo</td>
      <td colspan="1">Unlimited courses</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td colspan="3">All plans include 30-day money back</td>
    </tr>
  </tfoot>

</table>
Lesson 09

Forms & Inputs

Forms are how users send data to your server — sign-ups, logins, checkouts, search bars. Mastering forms is essential.

<form>
Form container. action = where data goes. method = GET (in URL) or POST (in body, for sensitive data).
<input>
Most versatile element. Controlled by type attribute. Over 20 types available. Void element — no closing tag.
<label>
Label for an input. Link via for attribute matching input's id. Clicking label focuses input. Critical for accessibility.
<textarea>
Multi-line text input. For long messages, comments, descriptions. Has rows and cols attributes.
<select>
Dropdown menu. Contains <option> elements. Use multiple for multi-select.
<option>
Dropdown option. Inside <select>. Use value attribute for what's submitted.
<optgroup>
Groups options in a dropdown with a label. Like category headers inside a select.
<button>
Clickable button. type="submit" submits form, type="reset" clears form, type="button" for JS use.
<fieldset>
Groups related inputs with a visual box. Use with <legend> for the group title.
<datalist>
Autocomplete suggestions for a text input. Link to input via list attribute.

All input types

TypeWhat it creates
textSingle-line text field (default)
emailEmail field — validates @ format on mobile
passwordHidden characters input
numberNumber spinner with min/max support
telPhone number — shows numeric keyboard on mobile
urlURL field — validates https:// format
searchSearch field with × clear button
checkboxToggleable on/off box
radioOne option from a group
rangeSlider between min and max
dateDate picker calendar
timeTime picker
datetime-localDate + time picker combined
monthMonth + year picker
weekWeek picker
colorColor picker
fileFile upload button
hiddenInvisible — carries data not shown to user
submitSubmit button (prefer <button>)
resetReset all fields
imageImage that acts as submit button
checkboxCheck/uncheck toggle
form.html — complete example
<form action="/submit" method="POST">

  <fieldset>
    <legend>Personal Info</legend>

    <label for="name">Full Name</label>
    <input type="text" id="name" name="name" placeholder="Shifat" required>

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

    <label for="country">Country</label>
    <select id="country" name="country">
      <option value="bd">Bangladesh</option>
      <option value="de">Germany</option>
    </select>

  </fieldset>

  <label for="message">Message</label>
  <textarea id="message" name="message" rows="4" placeholder="Write here..."></textarea>

  <!-- Radio buttons -->
  <p>Experience level:</p>
  <label><input type="radio" name="level" value="beginner"> Beginner</label>
  <label><input type="radio" name="level" value="pro"> Pro</label>

  <!-- Checkbox -->
  <label>
    <input type="checkbox" name="terms" required>
     I agree to the terms
  </label>

  <button type="submit">Submit</button>
  <button type="reset">Clear</button>

</form>

Common form attributes

AttributePurpose
requiredField must be filled before submit
disabledField is inactive — can't interact
readonlyCan be seen but not changed
placeholderGrey hint text inside the field
valuePre-filled value
min / maxRange limits for number/date inputs
maxlengthMax characters allowed
patternRegex pattern validation
autocompleteBrowser autocomplete hints
autofocusFocuses this field on page load
Lesson 10

Semantic HTML5

Semantic tags tell browsers AND developers AND search engines what a section means, not just what it looks like. This is the HTML5 revolution.

💡 Why semantic HTML matters: SEO (Google ranks pages higher), Accessibility (screen readers navigate by landmarks), Maintainability (code is self-documenting).
<header>
Page or section header. Usually contains logo, nav, tagline. A page can have multiple (one for the page, one per article).
<nav>
Navigation block. Contains main site links or table of contents. Screen readers jump to it directly. Main nav, breadcrumbs, pagination
<main>
Primary content area. Only ONE per page. Never inside header, footer, or aside. The unique, primary content of the page
<article>
Self-contained, distributable content. Could be shared on its own — blog post, news article, product card, forum post. Blog posts, news, social posts
<section>
Thematic grouping of content. Should have a heading. A chapter in a book — related content grouped together. Chapters, feature sections, tabs
<aside>
Tangentially related content. Sidebar, ads, related articles, "did you know" boxes. Sidebars, pull quotes, ads
<footer>
Footer content. Copyright, contact info, links, social icons. Pages and articles can each have their own.
<details>
Expandable/collapsible block. Built-in accordion without JavaScript! Use with <summary>.
<summary>
Visible heading of <details>. Clicking it expands/collapses the content.
<dialog>
Native modal/dialog box. HTML5.2. Control with JS .showModal() and .close().
<progress>
Progress bar. Use value and max attributes. No JS needed for static display.
<meter>
Scalar measurement. Like a gauge. min, max, low, high, optimum attributes.
semantic-layout.html
<body>

  <header>
    <nav>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/blog">Blog</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <section>
      <h2>Latest Posts</h2>
      <article>
        <h3>Why I Chose Web3</h3>
        <p>My journey into decentralized tech...</p>
        <footer>
          Published <time datetime="2025-06-01">June 1, 2025</time>
        </footer>
      </article>
    </section>

    <aside>
      <h3>About the Author</h3>
      <p>Shifat — Web3 builder from Bangladesh.</p>
    </aside>
  </main>

  <footer>
    <p>&copy; 2025 shifat.dev</p>
  </footer>

</body>
details-dialog.html
<!-- No JS needed for accordion -->
<details>
  <summary>What is Web3?</summary>
  <p>Web3 is the next iteration of the internet built on blockchain...</p>
</details>

<!-- Progress bar -->
<label>Course progress:</label>
<progress value="60" max="100">60%</progress>

<!-- Native modal -->
<dialog id="myModal">
  <h2>Confirm Action</h2>
  <button onclick="document.getElementById('myModal').close()">Close</button>
</dialog>
<button onclick="document.getElementById('myModal').showModal()">Open Modal</button>
Lesson 11

Div & Span — Generic Containers

When no semantic tag fits, use <div> (block) or <span> (inline) as generic containers for CSS styling or JS targeting.

<div>
Block-level container. Takes full width. Stacks vertically. Use when you need to group elements for layout, CSS, or JS — with no semantic meaning available. Layout wrappers, card containers, grids
<span>
Inline container. Flows within text. Use to target part of text with CSS or JS without breaking the flow. Highlighting a word, adding color, JS targeting
div-span.html
<!-- div: layout card -->
<div class="card">
  <div class="card-header"><h3>Web3 Guide</h3></div>
  <div class="card-body"><p>Learn about DeFi and NFTs.</p></div>
</div>

<!-- span: inline styling -->
<p>Price is <span style="color:green; font-weight:bold">$49</span> today only.</p>

<!-- span: JS target -->
<p>You have <span id="count">0</span> notifications.</p>
⚠️ Don't "div-itis". Beginners overuse <div> for everything. Rule: if a semantic tag exists and fits, use it. If not, use div/span.
Lesson 12

Global HTML Attributes

These attributes work on ANY HTML element. They're essential for CSS targeting, JavaScript, accessibility, and behavior.

AttributePurposeExample
id Unique identifier — one per page. Used by CSS (#id), JS (getElementById), anchor links (#id) id="hero"
class Reusable label — multiple elements can share a class. CSS targeting, JS querySelectorAll class="card active"
style Inline CSS. Quick for demos, but avoid for production (use CSS files) style="color:red"
title Tooltip shown on hover. Also adds semantic context for screen readers title="Click to expand"
hidden Hides element from display AND assistive tech. Better than display:none for semantic hiding hidden
tabindex Controls tab key order. 0 = natural order, -1 = skip, positive = explicit order tabindex="0"
contenteditable Makes element editable like a text field. Used for rich-text editors contenteditable="true"
draggable Makes element draggable with native HTML5 drag-and-drop API draggable="true"
data-* Custom data attributes for storing info. Read by JS with dataset data-user-id="42"
lang Language of element content. Override page language for mixed-language content lang="bn"
dir Text direction: ltr (left-to-right) or rtl (right-to-left for Arabic) dir="rtl"
spellcheck Enable/disable browser spellcheck on editable elements spellcheck="false"
translate Whether browser translate tools should translate this element translate="no"
data-attributes.html
<!-- data-* attributes for JS -->
<div class="product" data-id="101" data-price="49" data-category="web3">
  Solana Course
</div>

<!-- Read in JavaScript -->
<script>
  const product = document.querySelector('.product');
  console.log(product.dataset.id);       // "101"
  console.log(product.dataset.price);    // "49"
  console.log(product.dataset.category); // "web3"
</script>
Lesson 13

Meta Tags & SEO

Meta tags live in <head> and control how your page appears in search results, social shares, and browser behavior.

meta-seo.html — complete head section
<head>
  <!-- Essential -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>shifat.dev — Frontend Developer & Web3 Builder</title>

  <!-- SEO -->
  <meta name="description" content="Shifat's personal site — web3 ambassador, frontend dev, community builder.">
  <meta name="keywords" content="web3, html, javascript, bangladesh">
  <meta name="author" content="Shifat">
  <meta name="robots" content="index, follow">

  <!-- Open Graph (Facebook, WhatsApp, Discord previews) -->
  <meta property="og:title" content="shifat.dev">
  <meta property="og:description" content="Web3 builder & frontend dev">
  <meta property="og:image" content="https://shifat.dev/og-image.jpg">
  <meta property="og:url" content="https://shifat.dev">
  <meta property="og:type" content="website">

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@shifat0g">
  <meta name="twitter:title" content="shifat.dev">
  <meta name="twitter:image" content="https://shifat.dev/og-image.jpg">

  <!-- Favicon -->
  <link rel="icon" href="favicon.ico">
  <link rel="apple-touch-icon" href="apple-touch-icon.png">

  <!-- Canonical URL (prevents duplicate content penalty) -->
  <link rel="canonical" href="https://shifat.dev">

  <!-- Theme color (Android chrome header color) -->
  <meta name="theme-color" content="#0a0a0f">

  <!-- CSS -->
  <link rel="stylesheet" href="style.css">
</head>
Day 2 — Task

Build a Portfolio Page 🏗️

🎯 Task: Full Portfolio Structure
Upgrade your Day 1 page into a proper portfolio using semantic HTML:
  1. Add full meta tags for SEO and social sharing
  2. Structure page with <header>, <main>, <footer>
  3. Add a <nav> with at least 3 links
  4. Create a "Projects" <section> with 3 project <article>s
  5. Build a contact form with name, email, message fields
  6. Add a pricing/skills comparison <table>
  7. Add a <details> FAQ section
  8. Bonus: Add Open Graph tags and verify them at metatags.io
Which tag should wrap a blog post that could stand alone and be shared independently?
<div>
<section>
<article>
<main>
03
Day Three
Advanced HTML & Final Project
Media, APIs, Accessibility, HTML+CSS+JS, and building your portfolio
Lesson 14

Audio & Video

HTML5 brought native media elements — no more Flash. Play audio and video directly in the browser.

<video>
Embeds a video. Attributes: src, controls (shows play/pause), autoplay, loop, muted, poster (thumbnail).
<audio>
Embeds audio. Same attributes as video. For podcasts, music, sound effects.
<source>
Multiple format fallbacks inside video/audio. Browser picks first it can play (webm → mp4 → ogg).
<track>
Subtitles/captions for video. Uses .vtt files. Types: subtitles, captions, descriptions, chapters.
media.html
<!-- Video with multiple formats + captions -->
<video controls poster="thumbnail.jpg" width="640">
  <source src="video.webm" type="video/webm">
  <source src="video.mp4" type="video/mp4">
  <track src="subtitles-en.vtt" kind="subtitles" srclang="en" label="English">
  Your browser doesn't support video.
</video>

<!-- Autoplay muted background video -->
<video autoplay muted loop playsinline>
  <source src="bg-loop.mp4" type="video/mp4">
</video>

<!-- Audio player -->
<audio controls>
  <source src="podcast.mp3" type="audio/mpeg">
  <source src="podcast.ogg" type="audio/ogg">
</audio>
Lesson 15

iFrame & Embedding

Embed external content — YouTube videos, Google Maps, social posts, other pages — directly into your HTML.

<iframe>
Inline frame — embeds another webpage. Used for YouTube, Google Maps, payment forms, social widgets. Key attributes: src, width, height, title (required for accessibility), loading="lazy"
<embed>
Embeds external content like PDFs, Flash (legacy). Less common now. <embed src="doc.pdf" type="application/pdf">
<object>
Embeds any external resource with fallback content inside. Older but still valid for PDFs in some setups.
iframe.html
<!-- YouTube video embed -->
<iframe
  src="https://www.youtube.com/embed/VIDEO_ID"
  title="My YouTube Video"
  width="560"
  height="315"
  loading="lazy"
  allowfullscreen
></iframe>

<!-- Google Maps embed -->
<iframe
  src="https://www.google.com/maps/embed?pb=..."
  title="Location Map"
  width="600"
  height="450"
  loading="lazy"
></iframe>

<!-- Sandboxed iframe (security) -->
<iframe
  src="https://other-site.com"
  sandbox="allow-scripts allow-same-origin"
  title="Sandboxed content"
></iframe>
🔒 Security: Use sandbox attribute to restrict what embedded content can do. Without it, iframes can access parent page data. Always add a title attribute for accessibility.
Lesson 16

HTML5 Elements & APIs

HTML5 added powerful built-in capabilities that used to require plugins or heavy JavaScript.

<canvas>
Drawing surface for JavaScript. Used for games, charts, image editing, animations. Everything drawn with JS getContext('2d') or WebGL.
<template>
Inert HTML fragment. Not rendered until JS clones it. Used for repeating UI patterns.
<slot>
Web Components placeholder. Part of Shadow DOM — lets you slot content into custom elements.
<output>
Result of a calculation. Semantically marks a computed value. Like a calculator display.
<noscript>
Fallback for no-JS browsers. Content inside shows when JavaScript is disabled.
<wbr>
Word Break Opportunity. Suggests where a long word can break across lines. For URLs, code strings.
<ruby>
Ruby annotation for East Asian typography. Shows pronunciation above characters. Uses <rt> for the annotation.
<bdi>
Bidirectional Isolate. Isolates text that might have different direction (Arabic/Hebrew in English text).
canvas-template.html
<!-- Canvas: draw with JS -->
<canvas id="myCanvas" width="400" height="200">
  Canvas not supported
</canvas>
<script>
  const ctx = document.getElementById('myCanvas').getContext('2d');
  ctx.fillStyle = '#f0e040';
  ctx.fillRect(10, 10, 200, 100);
  ctx.fillStyle = '#0a0a0f';
  ctx.font = '20px monospace';
  ctx.fillText('Hello Canvas!', 20, 60);
</script>

<!-- Template: reusable HTML -->
<template id="card-template">
  <div class="card">
    <h3 class="card-title"></h3>
    <p class="card-body"></p>
  </div>
</template>
<script>
  const tmpl = document.getElementById('card-template');
  const clone = tmpl.content.cloneNode(true);
  clone.querySelector('.card-title').textContent = 'Web3 Guide';
  document.body.appendChild(clone);
</script>

<!-- Output element -->
<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
  <input type="number" id="a" value="10"> +
  <input type="number" id="b" value="20"> =
  <output name="result">30</output>
</form>
Lesson 17

Accessibility (a11y)

Accessibility means making your site usable for everyone — including people using screen readers, keyboard-only navigation, or low vision. It's also a legal requirement in many countries.

alt text
Describe images for screen readers and when images fail. Decorative images: alt="". Meaningful images: describe what's there.
aria-label
Labels elements that have no visible text. E.g. an icon button: <button aria-label="Close menu">✕</button>
aria-hidden
Hides from screen readers. Use for decorative icons that would be confusing if read aloud.
role
Defines element role to assistive tech. E.g. role="navigation", role="alert", role="dialog".
aria-expanded
State of collapsible elements. aria-expanded="false" → collapsed. Update with JS when toggling.
aria-live
Announces dynamic changes. aria-live="polite" announces when user is idle. Used for notifications, search results.
tabindex
Keyboard focus control. Ensure all interactive elements can be reached by Tab key.
:focus-visible
CSS focus indicator. Never remove outline without replacing it. Keyboard users need to see what's focused.
accessibility.html
<!-- Skip link (lets keyboard users skip to main content) -->
<a href="#main" class="skip-link">Skip to main content</a>

<!-- Landmark roles -->
<header role="banner"></header>
<nav aria-label="Main navigation"></nav>
<main id="main" role="main"></main>

<!-- Icon button (accessible) -->
<button aria-label="Close menu" aria-expanded="false">
  <svg aria-hidden="true">...</svg>
</button>

<!-- Live region for notifications -->
<div aria-live="polite" aria-atomic="true" id="notifications"></div>

<!-- Form with full accessibility -->
<div role="group" aria-labelledby="pwd-label">
  <label id="pwd-label" for="password">Password</label>
  <input type="password" id="password"
         aria-describedby="pwd-hint" required>
  <p id="pwd-hint">Min 8 characters, one number required</p>
</div>
Lesson 18

HTML + CSS + JS — How They Connect

HTML, CSS, and JavaScript work together. Understanding exactly how they connect is the key insight that ties everything together.

How CSS connects to HTML

css-connection.html
<!-- 1. External CSS (best practice) -->
<link rel="stylesheet" href="style.css">

<!-- 2. Internal CSS (inside head) -->
<style>
  .card { background: #111; padding: 20px; }
  #hero { font-size: 48px; }
  h1 { color: yellow; }
</style>

<!-- 3. Inline CSS (avoid for complex styles) -->
<p style="color: red; font-size: 18px">Red text</p>

<!-- CSS targets HTML via: -->
<!-- Tag name: h1, p, div        -->
<!-- Class: .card, .btn-primary   -->
<!-- ID: #hero, #nav              -->
<!-- Attribute: [type="text"]     -->
<!-- State: a:hover, p:first-child -->

How JavaScript connects to HTML

js-connection.html
<!-- Link external JS (before /body) -->
<script src="app.js" defer></script>

<!-- defer: wait for HTML to parse, then run -->
<!-- async: run as soon as downloaded -->

<!-- JS selects HTML elements by: -->
<script>
  // By ID
  const hero = document.getElementById('hero');

  // By class (returns NodeList)
  const cards = document.querySelectorAll('.card');

  // By CSS selector
  const btn = document.querySelector('button[type="submit"]');

  // Change content
  hero.textContent = 'New Title';
  hero.innerHTML = '<strong>Bold Title</strong>';

  // Change CSS class
  hero.classList.add('active');
  hero.classList.toggle('dark-mode');

  // Change attributes
  document.querySelector('img').src = 'new-image.jpg';

  // Listen for events
  btn.addEventListener('click', () => {
    alert('Form submitted!');
  });

  // Create elements dynamically
  const newDiv = document.createElement('div');
  newDiv.className = 'card';
  newDiv.textContent = 'New card';
  document.body.appendChild(newDiv);
</script>
🔗 The Big Picture
HTML creates elements → CSS selects them with tag/class/id and styles them → JavaScript selects them with querySelector and manipulates them. The class and id attributes are the bridge between all three.
Lesson 19

HTML Best Practices

Writing correct HTML is one thing. Writing great HTML is another. These are the professional standards.

Validate
Run your HTML through validator.w3.org. It catches unclosed tags, wrong nesting, invalid attributes.
Indentation
2 or 4 spaces per level. Consistent indentation makes nesting errors obvious.
One <h1>
Only one h1 per page. Establishes primary topic for SEO and accessibility. Never skip heading levels (h1 → h3).
Semantic first
Always choose semantic over generic. <nav> not <div class="nav">. <article> not <div class="post">.
Always alt text
Every <img> needs alt. Either descriptive text, or alt="" for decorative images.
Labels for inputs
Every form input needs a <label>. Never rely on placeholder text alone — it disappears when typing.
Lowercase tags
Write all tags in lowercase. <div> not <DIV>. Industry standard.
Quote attributes
Always quote attribute values. class="card" not class=card. Avoid hard-to-debug errors.
CSS in <head>
Link CSS in <head>. Browser applies styles before rendering. If in body, user sees unstyled flash.
JS before </body>
Or use defer. Scripts block HTML parsing. Load them last (or defer) so page renders first.

HTML Entities

Special characters must be escaped in HTML:

CharacterEntityWhen to use
&&amp;In text content
<&lt;Less-than sign in text
>&gt;Greater-than sign in text
"&quot;Quote inside attribute value
 &nbsp;Non-breaking space
©&copy;Copyright symbol
®&reg;Registered trademark
&rarr;Right arrow
&check;Checkmark
Day 3 — Final Project

Build Your Complete Portfolio 🚀

Final Project: Personal Portfolio Website

Combine everything from all 3 days into a complete, accessible, SEO-ready portfolio page.

  • 01Full HTML5 boilerplate with complete meta tags (OG, Twitter Card, canonical)
  • 02Semantic layout: header → nav → main → sections → footer
  • 03Hero section with h1, tagline, two CTA links
  • 04About section with image (with alt text), bio paragraphs, skills list
  • 05Projects section: 3 article cards with title, description, links
  • 06A comparison table (skills, tech stack, or pricing)
  • 07A contact form with name, email, message, submit button
  • 08A details/summary FAQ section with 3+ questions
  • 09Social links with aria-labels (GitHub, Twitter/X, LinkedIn)
  • 10Footer with copyright (&copy;), year, your name
  • 11Embedded YouTube video or Google Map (optional)
  • 12Validate at validator.w3.org — zero errors
🎯 Submission Checklist
Before you ship, confirm:
  • Opens correctly in Chrome, Firefox, Safari
  • Looks good on mobile (resize browser)
  • All links work
  • Images have alt text
  • Form inputs all have labels
  • Passes W3C validator with 0 errors
  • Open Graph tags generate a preview (test at opengraph.xyz)
Where should you place <script> tags for best page load performance?
At the top of <head>
After <title>
Before </body> (or with defer attribute)
Inside <main>
🎉 You finished Learn HTML!

You've covered every core HTML tag, element, and concept.
Next step: Learn CSS to style your pages, then Learn JavaScript to add interactivity.