# 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
