# HTML Deep Dive — Advanced Features & Hidden Capabilities
> Comprehensive research on HTML features beyond the basics.
---
## 1. Semantic HTML Elements
### Beyond `div` and `span`
| Element | Purpose | When to Use |
|---------|---------|-------------|
| `<article>` | Self-contained content | Blog posts, news articles, forum posts |
| `<section>` | Thematic grouping | Chapters, sections with headings |
| `<nav>` | Navigation links | Primary nav, breadcrumbs, pagination |
| `<aside>` | Tangential content | Sidebars, pull quotes, ads |
| `<main>` | Primary page content | One per page, excludes headers/navs |
| `<header>` | Introductory content | Page header, article header, section header |
| `<footer>` | Section footer | Page footer, article footer |
| `<figure>` | Self-contained media | Images with captions, diagrams, code |
| `<figcaption>` | Figure caption | Inside `<figure>` |
| `<details>`/`<summary>` | Collapsible content | FAQs, expandable sections |
| `<dialog>` | Modal/dialog box | Popups, modals (native!) |
| `<mark>` | Highlighted text | Search results, emphasis |
| `<time>` | Machine-readable dates | `datetime="2025-01-15"` |
| `<abbr>` | Abbreviations | `title="HyperText Markup Language"` |
| `<address>` | Contact information | Author contact, business address |
### Practical Example
```html
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<article>
<header>
<h1>Article Title</h1>
<p>Published on <time datetime="2025-05-08">May 8, 2025</time></p>
</header>
<section>
<h2>Introduction</h2>
<p>Content here...</p>
</section>
<aside>
<p>Related sidebar content</p>
</aside>
<figure>
<img src="diagram.png" alt="Architecture diagram">
<figcaption>Figure 1: System Architecture</figcaption>
</figure>
<details>
<summary>Technical Notes</summary>
<p>Expanded content here...</p>
</details>
<footer>
<p>By <abbr title="John Doe">JD</abbr></p>
</footer>
</article>
</main>
<footer>
<address>
Contact: <a href="mailto:info@example.com">info@example.com</a>
</address>
</footer>
</body>
```
---
## 2. Advanced Form Features
### Hidden Input Types
```html
<!-- Date/time pickers -->
<input type="date" name="birthdate">
<input type="datetime-local" name="appointment">
<input type="month" name="billing_cycle">
<input type="week" name="sprint">
<input type="time" name="alarm">
<!-- Specialized inputs -->
<input type="color" name="theme_color" value="#6366f1">
<input type="range" name="volume" min="0" max="100" step="5">
<input type="search" name="q">
<input type="tel" name="phone">
<input type="url" name="website">
<input type="email" name="address" multiple>
<input type="file" name="avatar" accept="image/*" capture="user">
<!-- Number with constraints -->
<input type="number" name="qty" min="1" max="99" step="0.5" value="1">
```
### `<datalist>` — Autocomplete Without Libraries
```html
<label for="browser">Choose a browser:</label>
<input list="browsers" name="browser" id="browser" placeholder="Type to search...">
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
<option value="Opera">
</datalist>
```
### `<output>` — Computation Results
```html
<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
<input type="number" name="a" value="0"> +
<input type="number" name="b" value="0"> =
<output name="result">0</output>
</form>
```
### Advanced Form Validation
```html
<!-- Pattern matching (regex) -->
<input type="text" name="code" pattern="[A-Z]{2}\d{4}"
title="Two letters followed by four digits (e.g., AB1234)">
<!-- Custom validation via JS -->
<input type="text" name="username" id="username" required>
<script>
const input = document.getElementById('username');
input.addEventListener('input', () => {
if (input.value.length < 3) {
input.setCustomValidity('Username must be at least 3 characters');
} else {
input.setCustomValidity(''); // Clear error
}
});
</script>
<!-- Constraint Validation API -->
<script>
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
const firstInvalid = form.querySelector(':invalid');
firstInvalid.reportValidity(); // Show browser error bubble
}
});
</script>
```
### `fieldset` / `legend` — Grouping Controls
```html
<fieldset>
<legend>Payment Method</legend>
<label><input type="radio" name="payment" value="card"> Credit Card</label>
<label><input type="radio" name="payment" value="paypal"> PayPal</label>
<label><input type="radio" name="payment" value="crypto"> Crypto</label>
</fieldset>
```
---
## 3. Web Components
### Custom Elements
```javascript
// Define a custom element
class GreetingCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const name = this.getAttribute('name') || 'World';
const color = this.getAttribute('color') || '#6366f1';
this.shadowRoot.innerHTML = `
<style>
:host { display: block; padding: 1rem; border-radius: 8px; }
h2 { color: ${color}; margin: 0; }
p { margin: 0.5rem 0 0; }
</style>
<h2>Hello, ${name}!</h2>
<slot name="body">Default body content</slot>
`;
}
// Observe attribute changes
static get observedAttributes() { return ['name', 'color']; }
attributeChangedCallback(name, oldVal, newVal) {
this.connectedCallback(); // Re-render
}
}
customElements.define('greeting-card', GreetingCard);
```
```html
<greeting-card name="Grepples" color="#10b981">
<span slot="body">Custom body content here</span>
</greeting-card>
```
### `<template>` — Inert Content
```html
<template id="card-template">
<style>
.card { padding: 1rem; border: 1px solid #ddd; border-radius: 8px; }
</style>
<article class="card">
<h3><slot name="title"></slot></h3>
<p><slot name="content"></slot></p>
</article>
</template>
<script>
const template = document.getElementById('card-template');
const clone = template.content.cloneNode(true);
document.body.appendChild(clone);
</script>
```
---
## 4. Modern HTML APIs
### Intersection Observer — Lazy Loading & Scroll Effects
```javascript
// Detect when elements enter the viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
// For lazy loading:
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, {
threshold: 0.1,
rootMargin: '50px' // Start loading 50px before visible
});
// Observe all lazy images
document.querySelectorAll('.lazy').forEach(el => observer.observe(el));
```
### Resize Observer — Responsive Without Media Queries
```javascript
// Detect element size changes
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log(`Element is ${width}×${height}`);
// Adjust layout based on actual element size
if (width < 300) {
entry.target.classList.add('narrow');
} else {
entry.target.classList.remove('narrow');
}
}
});
observer.observe(document.querySelector('.card'));
```
### MutationObserver — Watch DOM Changes
```javascript
// Detect when content changes
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.type === 'childList') {
console.log('Children added/removed');
}
if (mutation.type === 'attributes') {
console.log(`${mutation.attributeName} changed`);
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class', 'data-state']
});
```
### Fullscreen API
```javascript
// Enter fullscreen
document.getElementById('video').requestFullscreen();
// Exit fullscreen
document.exitFullscreen();
// Check state
if (document.fullscreenElement) {
console.log('In fullscreen');
}
// Listen for changes
document.addEventListener('fullscreenchange', (e) => {
console.log(document.isFullscreen ? 'Entered' : 'Exited');
});
```
### Clipboard API
```javascript
// Copy to clipboard
navigator.clipboard.writeText('Text to copy');
// Read from clipboard
const text = await navigator.clipboard.readText();
// Copy rich content
const blob = new Blob(['<b>Hello</b>'], { type: 'text/html' });
navigator.clipboard.write([new ClipboardItem({ 'text/html': blob })]);
```
---
## 5. Accessibility (a11y)
### ARIA Roles, States, and Properties
```html
<!-- Landmark roles -->
<nav aria-label="Main navigation">
<main role="main">
<aside aria-label="Sidebar">
<footer role="contentinfo">
<!-- Live regions for dynamic content -->
<div aria-live="polite" aria-atomic="true">
<!-- Announced to screen readers when content changes -->
</div>
<div aria-live="assertive">
<!-- Interrupts current announcement (errors, alerts) -->
</div>
<!-- Button with loading state -->
<button aria-busy="true" aria-label="Loading..." disabled>
Submit
</button>
<!-- Progress indicator -->
<progress value="70" max="100" aria-label="Upload progress">70%</progress>
<!-- Tab interface -->
<div role="tablist" aria-label="Settings">
<button role="tab" aria-selected="true" aria-controls="panel-1">General</button>
<button role="tab" aria-selected="false" aria-controls="panel-2">Privacy</button>
</div>
<div role="tabpanel" id="panel-1">...</div>
<div role="tabpanel" id="panel-2" hidden>...</div>
<!-- Skip navigation link -->
<a href="#main-content" class="skip-link">Skip to main content</a>
```
### Keyboard Navigation
```html
<!-- tabindex control -->
<div tabindex="0" role="button">Focusable div</div>
<div tabindex="-1">Programmatically focusable</div>
<!-- Custom focus styles -->
<style>
*:focus-visible {
outline: 3px solid #6366f1;
outline-offset: 2px;
}
/* Remove focus ring for mouse users */
*:focus:not(:focus-visible) {
outline: none;
}
</style>
```
---
## 6. Performance Optimization
### Resource Hints
```html
<!-- Preconnect: Establish early connection to origin -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Prefetch: Load in background for future navigation -->
<link rel="prefetch" href="/next-page.html">
<!-- Preload: High-priority resource needed soon -->
<link rel="preload" href="hero.webp" as="image">
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="critical.js" as="script">
<!-- Module preloading -->
<link rel="modulepreload" href="module.js">
```
### Image Optimization
```html
<!-- Responsive images with srcset -->
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1024px) 50vw,
33vw"
alt="Description"
loading="lazy"
decoding="async"
fetchpriority="low">
<!-- Art direction with <picture> -->
<picture>
<source media="(max-width: 768px)" srcset="hero-mobile.avif" type="image/avif">
<source media="(max-width: 768px)" srcset="hero-mobile.webp" type="image/webp">
<source srcset="hero-desktop.avif" type="image/avif">
<source srcset="hero-desktop.webp" type="image/webp">
<img src="hero.jpg" alt="Hero image">
</picture>
<!-- Lazy loading for below-the-fold images -->
<img src="below-fold.jpg" loading="lazy" alt="...">
<!-- Eager load for above-the-fold (default behavior) -->
<img src="hero.jpg" fetchpriority="high" alt="...">
```
---
## 7. SEO and Meta Tags
### Open Graph & Social
```html
<head>
<!-- Page metadata -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Title | Site Name</title>
<meta name="description" content="Page description for search results">
<link rel="canonical" href="https://example.com/page">
<!-- Open Graph (Facebook, LinkedIn) -->
<meta property="og:type" content="article">
<meta property="og:title" content="Article Title">
<meta property="og:description" content="Article description">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:site_name" content="Site Name">
<!-- Twitter Cards -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Article Title">
<meta name="twitter:description" content="Description">
<meta name="twitter:image" content="https://example.com/image.jpg">
<!-- Structured Data (JSON-LD) -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Article Title",
"author": { "@type": "Person", "name": "Author Name" },
"datePublished": "2025-05-08",
"image": "https://example.com/image.jpg"
}
</script>
</head>
```
---
## 8. Hidden HTML Attributes
### `contenteditable` — Inline Editing
```html
<div contenteditable="true">
Click here to edit this text directly!
</div>
<!-- Limit to single line -->
<div contenteditable="true"
style="caret-color: #6366f1; outline: 2px solid #6366f1;"
onkeydown="if(event.key==='Enter'){event.preventDefault();this.blur();}">
Single-line editable
</div>
```
### `popover` — Native Popover (2024+)
```html
<!-- Manual popover -->
<button popovertarget="menu">Open Menu</button>
<div id="menu" popover="manual">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
</div>
<!-- Auto popover (opens on click, closes outside) -->
<button popovertarget="info">Info</button>
<div id="info" popover>
<p>This auto-closes when you click outside!</p>
</div>
<!-- Light dismiss (tap outside to close) -->
<div popover>
<form method="dialog">
<button type="submit">Close</button>
</form>
</div>
<!-- JS API -->
<script>
const popover = document.getElementById('menu');
popover.showPopover(); // Open
popover.show(); // Open (no light dismiss)
popover.hidePopover(); // Close
popover.togglePopover(); // Toggle
</script>
```
### `inert` — Disable Interaction
```html
<!-- Makes subtree non-interactive, skipped by tab, hidden from a11y -->
<aside inert>Sidebar content is disabled</aside>
<!-- Toggle programmatically -->
<button onclick="document.querySelector('.sidebar').toggleAttribute('inert')">
Toggle Sidebar
</button>
```
### `draggable` — Native Drag and Drop
```html
<img src="photo.jpg" draggable="true"
ondragstart="event.dataTransfer.setData('text/plain', 'photo.jpg')">
<div ondragover="event.preventDefault()"
ondrop="console.log(event.dataTransfer.getData('text/plain'))">
Drop zone
</div>
```
### `hidden` and `translate`
```html
<!-- Hidden element (display: none) -->
<div hidden>Not visible</div>
<!-- Prevent browser auto-translation -->
<p translate="no">Don't translate this</p>
```
---
## 9. HTML5 Storage APIs
### localStorage / sessionStorage
```javascript
// localStorage — persists across sessions
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
localStorage.removeItem('theme');
localStorage.clear();
// sessionStorage — cleared when tab closes
sessionStorage.setItem('cart', JSON.stringify(items));
// Store objects (must stringify)
localStorage.setItem('user', JSON.stringify({ name: 'Grepples', age: 25 }));
const user = JSON.parse(localStorage.getItem('user'));
```
### IndexedDB — Client-Side Database
```javascript
// Open database
const request = indexedDB.open('MyDB', 1);
request.onupgradeneeded = (e) => {
const db = e.target.result;
db.createObjectStore('users', { keyPath: 'id' });
};
request.onsuccess = (e) => {
const db = e.target.result;
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
// Add data
store.add({ id: 1, name: 'Grepples', email: 'g@example.com' });
// Get data
const getReq = store.get(1);
getReq.onsuccess = () => console.log(getReq.result);
// Query
const all = store.getAll();
all.onsuccess = () => console.log(all.result);
};
```
---
## Quick Reference: HTML Feature Checklist
- [ ] Use semantic elements (`article`, `section`, `nav`, `main`)
- [ ] Add `alt` text to all images
- [ ] Use `loading="lazy"` for below-the-fold images
- [ ] Include `fetchpriority="high"` for LCP images
- [ ] Add structured data (JSON-LD) for rich results
- [ ] Use `prefetch`/`preconnect` for critical resources
- [ ] Implement skip navigation links
- [ ] Use `aria-live` for dynamic content updates
- [ ] Use `contenteditable` for inline editing
- [ ] Use native `<dialog>` instead of custom modals
- [ ] Use `<details>`/`<summary>` for collapsible content
- [ ] Use `popover` attribute for tooltips and menus
- [ ] Add `lang` attribute to `<html>`
- [ ] Use `<time>` with `datetime` for dates
- [ ] Implement proper form validation
- [ ] Use `fieldset`/`legend` for form grouping