Document structure, semantic elements, media, a11y & Web Components
Every HTML document needs <!DOCTYPE html>, <html>, <head> (metadata, title, links), and <body> (visible content). The doctype tells the browser to use standards mode.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Page</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>Block elements take full width and start on a new line (div, p, h1-h6, section). Inline elements only take needed width and flow within text (span, a, strong, em, img).
<!-- Block โ full width, new line -->
<div>I take the full width</div>
<p>So do I</p>
<!-- Inline โ flows with text -->
<p>This has <strong>bold</strong> and <a href="#">a link</a> inline.</p>Semantic elements describe their meaning: header, nav, main, article, section, aside, footer. They improve accessibility, SEO, and code readability vs generic divs.
<header>
<nav>...</nav>
</header>
<main>
<article>
<h2>Post Title</h2>
<section>...</section>
</article>
<aside>Sidebar</aside>
</main>
<footer>ยฉ 2025</footer>Use the <a> tag with href attribute. target="_blank" opens in new tab (add rel="noopener noreferrer" for security). Links can be absolute, relative, or anchor links.
<!-- External link -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Visit</a>
<!-- Relative link -->
<a href="/about">About Us</a>
<!-- Anchor link -->
<a href="#section2">Jump to Section 2</a>
<h2 id="section2">Section 2</h2>
<!-- Email/phone -->
<a href="mailto:[email protected]">Email</a>
<a href="tel:+1234567890">Call</a>Use <img> with src and alt (required for accessibility). Use width/height to prevent layout shift. <picture> and srcset for responsive images.
<!-- Basic image -->
<img src="photo.jpg" alt="A sunset over mountains" width="600" height="400">
<!-- Responsive -->
<picture>
<source media="(min-width: 800px)" srcset="large.jpg">
<source media="(min-width: 400px)" srcset="medium.jpg">
<img src="small.jpg" alt="Responsive image">
</picture>
<!-- Lazy loading -->
<img src="photo.jpg" alt="..." loading="lazy">Unordered list (ul) for bullet points, ordered list (ol) for numbered items, description list (dl) for term-definition pairs. Lists can be nested.
<!-- Unordered -->
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
<!-- Ordered -->
<ol type="1" start="1">
<li>First step</li>
<li>Second step</li>
</ol>
<!-- Description list -->
<dl>
<dt>HTML</dt>
<dd>HyperText Markup Language</dd>
</dl>h1 through h6, h1 being most important. Use one h1 per page. Follow hierarchy โ don't skip levels. Headings create document outline for accessibility and SEO.
<h1>Page Title</h1> <!-- One per page -->
<h2>Main Section</h2> <!-- Major sections -->
<h3>Subsection</h3> <!-- Under h2 -->
<h4>Detail</h4> <!-- Under h3 -->
<!-- BAD: skipping levels -->
<h1>Title</h1>
<h4>Subsection</h4> <!-- Skipped h2, h3 -->Use table, thead, tbody, tfoot for structure. tr for rows, th for headers, td for data cells. Use scope attribute on th for accessibility. caption for table title.
<table>
<caption>Quarterly Sales</caption>
<thead>
<tr>
<th scope="col">Quarter</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<td>Q1</td>
<td>$10,000</td>
</tr>
</tbody>
</table>Meta tags provide metadata about the page. Essential: charset (UTF-8), viewport (responsive), description (SEO), and Open Graph tags (social sharing).
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Learn HTML fundamentals">
<meta name="robots" content="index, follow">
<!-- Open Graph (social sharing) -->
<meta property="og:title" content="My Page">
<meta property="og:description" content="Description">
<meta property="og:image" content="https://example.com/img.jpg">Entities display reserved characters: < (<), > (>), & (&), " ("), (non-breaking space), © (ยฉ). Use when you need literal special characters in content.
<!-- Reserved characters -->
<p>Use <div> for containers</p>
<p>Price: $5 & up</p>
<!-- Special characters -->
<p>© 2025 CodeDeck</p>
<p>10 km</p> <!-- non-breaking space -->
<p>— em dash</p>
<p>→ arrow โ</p>Use <video> and <audio> with source elements for format fallbacks. Add controls attribute for player UI. Provide multiple formats for browser compatibility.
<!-- Video -->
<video controls width="640" poster="thumb.jpg">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
Your browser doesn't support video.
</video>
<!-- Audio -->
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.ogg" type="audio/ogg">
</audio>div is a block-level generic container (sections, wrappers). span is an inline generic container (styling text fragments). Both have no semantic meaning โ use semantic elements when possible.
<!-- div โ block container -->
<div class="card">
<h3>Title</h3>
<p>Content here</p>
</div>
<!-- span โ inline container -->
<p>Your order is <span class="status-ok">confirmed</span>.</p>
<!-- Prefer semantic elements -->
<article> instead of <div class="article">
<strong> instead of <span class="bold">Custom data-* attributes store extra information on elements. Accessible via JavaScript with element.dataset. Useful for storing state, IDs, or config without extra markup.
<!-- HTML -->
<button data-action="delete" data-id="42">
Delete Item
</button>
<div data-theme="dark" data-lang="en">
<!-- JavaScript -->
const btn = document.querySelector('button');
console.log(btn.dataset.action); // "delete"
console.log(btn.dataset.id); // "42"id must be unique per page โ for one specific element (anchors, JS targeting). class can be reused on many elements โ for styling groups. An element can have multiple classes but only one id.
<!-- id โ unique, one per page -->
<section id="hero">...</section>
<a href="#hero">Go to hero</a>
<!-- class โ reusable -->
<div class="card card-featured">
<div class="card">
<div class="card card-dimmed">
<!-- Specificity: id (#) > class (.) -->
#hero { } /* higher specificity */
.card { } /* lower specificity */Native HTML disclosure widget โ toggleable content without JavaScript. summary is the visible label, the rest is hidden until expanded. Great for FAQs and collapsible sections.
<details>
<summary>What is CodeDeck?</summary>
<p>CodeDeck is a developer flashcard platform
for learning programming concepts.</p>
</details>
<!-- Open by default -->
<details open>
<summary>Installation</summary>
<pre>npm install codedeck</pre>
</details>Template holds HTML that isn't rendered on load. Used as a blueprint for JavaScript-generated content. Content is inert โ scripts don't run, images don't load until cloned.
<template id="card-template">
<div class="card">
<h3 class="card-title"></h3>
<p class="card-body"></p>
</div>
</template>
<script>
const template = document.getElementById('card-template');
const clone = template.content.cloneNode(true);
clone.querySelector('.card-title').textContent = 'Hello';
document.body.appendChild(clone);
</script>Use semantic elements, proper heading hierarchy, alt text on images, labels on form inputs, ARIA attributes when needed, sufficient color contrast, and keyboard navigability.
<!-- Label linked to input -->
<label for="email">Email:</label>
<input type="email" id="email" required>
<!-- ARIA for custom widgets -->
<button aria-expanded="false" aria-controls="menu">
Menu
</button>
<ul id="menu" role="menu" hidden>...</ul>
<!-- Skip navigation -->
<a href="#main" class="skip-link">Skip to content</a>
<main id="main">...</main>iframes embed another HTML document inside the current page. Common for maps, videos, third-party widgets. Security: use sandbox attribute and Content-Security-Policy frame-ancestors.
<!-- YouTube embed -->
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
width="560" height="315"
allowfullscreen
loading="lazy"
></iframe>
<!-- Sandboxed (restricted) -->
<iframe src="widget.html"
sandbox="allow-scripts allow-same-origin"
></iframe>strong/em are semantic โ strong means important, em means emphasis (screen readers change tone). b/i are visual-only โ bold/italic without meaning. Prefer semantic tags.
<!-- Semantic (meaningful) -->
<p><strong>Warning:</strong> This action is permanent.</p>
<p>You <em>must</em> save before closing.</p>
<!-- Visual only (no meaning) -->
<p>The movie <i>Inception</i> was great.</p>
<p>The <b>bold</b> style is decorative here.</p>Web Components are native browser APIs for creating reusable custom elements. Three specs: Custom Elements (define new tags), Shadow DOM (encapsulated styling), HTML Templates (reusable markup).
// Define custom element
class MyCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<div class="card">
<h3>${this.getAttribute('title')}</h3>
<slot></slot>
</div>`;
}
}
customElements.define('my-card', MyCard);
// Use in HTML
<my-card title="Hello">
<p>Card content here</p>
</my-card>