Skip to main content

🚀 Advanced HTML

Explore modern HTML5 features and capabilities.

HTML5 APIs

Canvas API

<!-- Create a canvas for drawing -->
<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// Draw rectangle
ctx.fillStyle = '#FF0000';
ctx.fillRect(20, 20, 100, 100);

// Draw circle
ctx.beginPath();
ctx.arc(200, 150, 50, 0, Math.PI * 2);
ctx.fillStyle = '#00FF00';
ctx.fill();
</script>

SVG Embedding

<!-- Embed SVG inline -->
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="blue" />
<rect x="10" y="10" width="30" height="30" fill="red" />
</svg>

<!-- Embed SVG from file -->
<object data="image.svg" type="image/svg+xml"></object>

<!-- SVG as image -->
<img src="image.svg" alt="SVG Image">

Geolocation API

<button onclick="getLocation()">Get My Location</button>

<script>
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
alert("Geolocation not supported");
}
}

function showPosition(position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
console.log(`Latitude: ${lat}, Longitude: ${lng}`);
}
</script>

Local Storage

<script>
// Store data
localStorage.setItem('username', 'John');

// Retrieve data
const name = localStorage.getItem('username');

// Remove item
localStorage.removeItem('username');

// Clear all
localStorage.clear();

// Check length
console.log(localStorage.length);
</script>

Session Storage

// Similar to localStorage but for current session only
sessionStorage.setItem('sessionToken', 'abc123');
const token = sessionStorage.getItem('sessionToken');
sessionStorage.removeItem('sessionToken');

Data Attributes

Custom Data Attributes

<!-- Store custom data -->
<div
id="product"
data-product-id="123"
data-price="99.99"
data-category="electronics"
>
Laptop
</div>

<script>
const product = document.getElementById('product');

// Access data attributes
console.log(product.dataset.productId); // "123"
console.log(product.dataset.price); // "99.99"
console.log(product.dataset.category); // "electronics"

// Update data attribute
product.dataset.price = "79.99";
</script>

Data Attributes in Lists

<ul id="users">
<li data-user-id="1" data-role="admin">Alice</li>
<li data-user-id="2" data-role="user">Bob</li>
<li data-user-id="3" data-role="user">Charlie</li>
</ul>

<script>
const users = document.querySelectorAll('#users li');
users.forEach(user => {
console.log(user.dataset.userId, user.dataset.role);
});
</script>

Web Workers

<!-- Main HTML file -->
<p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
</p>

<p>Count: <output id="result"></output></p>

<script>
let worker;

function startWorker() {
worker = new Worker('worker.js');
worker.onmessage = function(event) {
document.getElementById('result').textContent = event.data;
};
}

function stopWorker() {
worker.terminate();
}
</script>

worker.js (separate file):

let count = 0;
setInterval(function() {
count++;
postMessage(count);
}, 1000);

Progressive Enhancement

Fallback for Older Browsers

<!-- Video with fallback -->
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
Your browser doesn't support HTML5 video.
</video>

<!-- Picture for responsive images -->
<picture>
<source media="(min-width: 768px)" srcset="large.jpg">
<source media="(min-width: 480px)" srcset="medium.jpg">
<img src="small.jpg" alt="Responsive image">
</picture>

Drag and Drop

<style>
#droppable {
width: 200px;
height: 200px;
border: 2px solid blue;
padding: 10px;
}
.dragging {
opacity: 0.5;
}
</style>

<!-- Draggable elements -->
<p draggable="true" id="draggable">Drag me</p>

<!-- Drop zone -->
<div id="droppable">Drop here</div>

<script>
const draggable = document.getElementById('draggable');
const droppable = document.getElementById('droppable');

draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', e.target.textContent);
draggable.classList.add('dragging');
});

draggable.addEventListener('dragend', (e) => {
draggable.classList.remove('dragging');
});

droppable.addEventListener('dragover', (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
});

droppable.addEventListener('drop', (e) => {
e.preventDefault();
const data = e.dataTransfer.getData('text/plain');
droppable.textContent = `Dropped: ${data}`;
});
</script>

Web Components

Custom Elements

<!-- Define custom element -->
<script>
class CustomCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<div style="border: 1px solid #ccc; padding: 10px;">
<h3>${this.getAttribute('title')}</h3>
<p>${this.getAttribute('content')}</p>
</div>
`;
}
}

customElements.define('custom-card', CustomCard);
</script>

<!-- Use custom element -->
<custom-card
title="My Card"
content="This is a custom web component"
></custom-card>

Shadow DOM

<script>
class ShadowCard extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
:host {
display: block;
border: 1px solid blue;
padding: 10px;
}
</style>
<h3>Shadow DOM Card</h3>
<slot></slot>
`;
}
}

customElements.define('shadow-card', ShadowCard);
</script>

<shadow-card>
This content goes into the slot
</shadow-card>

Responsive Images

Art Direction

<!-- Different images for different screen sizes -->
<picture>
<source
media="(min-width: 1200px)"
srcset="large.jpg 1200w"
>
<source
media="(min-width: 768px)"
srcset="medium.jpg 768w"
>
<img
src="small.jpg"
alt="Responsive image"
sizes="(min-width: 1200px) 1200px, (min-width: 768px) 768px, 100vw"
>
</picture>

Responsive Sizing

<!-- Images scale responsively -->
<img
src="image.jpg"
alt="Responsive image"
sizes="(min-width: 1200px) 1200px,
(min-width: 768px) 768px,
(min-width: 480px) 480px,
100vw"
srcset="small.jpg 480w,
medium.jpg 768w,
large.jpg 1200w,
xlarge.jpg 1920w"
>

Metadata & SEO

Open Graph Tags

<head>
<meta property="og:title" content="My Article">
<meta property="og:description" content="Article description">
<meta property="og:image" content="image.jpg">
<meta property="og:url" content="https://example.com/article">
<meta property="og:type" content="article">
</head>

Twitter Card Tags

<head>
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="My Article">
<meta name="twitter:description" content="Article description">
<meta name="twitter:image" content="image.jpg">
</head>

Structured Data (Schema.org)

<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Article Title",
"image": "image.jpg",
"author": {
"@type": "Person",
"name": "John Doe"
},
"datePublished": "2024-01-15"
}
</script>

Performance Features

Preload & Prefetch

<head>
<!-- Preload critical resources -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="preload" href="critical.css" as="style">

<!-- Prefetch resources for next page -->
<link rel="prefetch" href="next-page.html">

<!-- DNS prefetch -->
<link rel="dns-prefetch" href="//cdn.example.com">

<!-- Preconnect -->
<link rel="preconnect" href="https://fonts.googleapis.com">
</head>

Lazy Loading

<!-- Lazy load images -->
<img
src="placeholder.jpg"
loading="lazy"
alt="Image"
>

<!-- Lazy load iframe -->
<iframe
src="video.html"
loading="lazy"
></iframe>

Complete Advanced Example

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced HTML Demo</title>

<!-- Preload fonts -->
<link rel="preload" href="font.woff2" as="font" crossorigin>

<!-- Structured data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Advanced HTML Demo"
}
</script>
</head>
<body>
<!-- Custom web component -->
<custom-card
title="Advanced Features"
content="Using HTML5 APIs"
></custom-card>

<!-- Canvas -->
<canvas id="myCanvas" width="300" height="200"></canvas>

<!-- Responsive image -->
<picture>
<source media="(min-width: 768px)" srcset="large.jpg">
<img src="small.jpg" alt="Responsive">
</picture>

<!-- Data attributes -->
<div id="data" data-user="123" data-role="admin">
User Info
</div>

<!-- Local storage -->
<button onclick="saveData()">Save Data</button>

<script>
// Custom element
class CustomCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<div style="border: 1px solid #ccc; padding: 10px;">
<h3>${this.getAttribute('title')}</h3>
<p>${this.getAttribute('content')}</p>
</div>
`;
}
}
customElements.define('custom-card', CustomCard);

// Canvas drawing
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#FF0000';
ctx.fillRect(50, 50, 100, 100);

// Data attributes
const dataDiv = document.getElementById('data');
console.log(dataDiv.dataset.user, dataDiv.dataset.role);

// Local storage
function saveData() {
localStorage.setItem('visitedAt', new Date().toISOString());
alert('Data saved!');
}
</script>
</body>
</html>

Best Practices

DO:

  • Use semantic HTML as foundation
  • Progressive enhance with APIs
  • Provide fallbacks for older browsers
  • Use data attributes for component data
  • Preload critical resources
  • Implement lazy loading
  • Use structured data for SEO

DON'T:

  • Over-use advanced features unnecessarily
  • Ignore browser compatibility
  • Forget fallbacks
  • Abuse custom elements
  • Store sensitive data in local storage
  • Load everything upfront

Next Steps

Common Tags ReferenceSemantic HTMLForms & Inputs