HTML5 introduced a collection of powerful APIs and elements that go far beyond basic document structure. These features enable native multimedia, client-side storage, drawing, geolocation, and interactive UI components — all without plugins.
The <canvas> Element
<canvas> provides a bitmap drawing surface controlled entirely by JavaScript. Use it for charts, games, image processing, and animations.
<canvas id="myCanvas" width="400" height="300">
Canvas is not supported in your browser.
</canvas>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw a filled rectangle
ctx.fillStyle = '#4285f4';
ctx.fillRect(50, 50, 200, 100);
// Draw a circle
ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI * 2);
ctx.fillStyle = '#ea4335';
ctx.fill();
// Draw text
ctx.fillStyle = '#000';
ctx.font = '24px Arial';
ctx.fillText('Hello Canvas!', 60, 40);
// Draw a line
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(400, 300);
ctx.strokeStyle = '#34a853';
ctx.lineWidth = 3;
ctx.stroke();
Canvas Use Cases
- Interactive charts (with libraries like Chart.js)
- Browser games
- Image editing tools
- Data visualisations
- Signature pads
- Photo filters
Note: Canvas content is not accessible to screen readers. For charts, also provide a data table as a fallback.
Web Storage
HTML5 introduced two client-side storage mechanisms, far better than cookies for storing data:
localStorage
Persists indefinitely until explicitly cleared. Data survives page refreshes and browser restarts:
// Store data
localStorage.setItem('theme', 'dark');
localStorage.setItem('username', 'rahul_dev');
localStorage.setItem('cart', JSON.stringify([
{ id: 1, name: 'HTML Book', qty: 2 },
{ id: 2, name: 'CSS Course', qty: 1 }
]));
// Retrieve data
const theme = localStorage.getItem('theme'); // 'dark'
const cart = JSON.parse(localStorage.getItem('cart'));
// Remove one item
localStorage.removeItem('theme');
// Clear all stored data
localStorage.clear();
// Check if key exists
if (localStorage.getItem('theme') !== null) {
applyTheme();
}
sessionStorage
Same API as localStorage, but data is cleared when the browser tab is closed:
// Store form data temporarily to survive page refresh
sessionStorage.setItem('formStep', '2');
sessionStorage.setItem('formData', JSON.stringify({
name: 'Priya',
email: 'priya@example.com'
}));
// Retrieve on page reload
const step = sessionStorage.getItem('formStep');
const data = JSON.parse(sessionStorage.getItem('formData'));
localStorage vs sessionStorage vs Cookies
| Feature | localStorage | sessionStorage | Cookies |
|---|
| Capacity | ~5-10MB | ~5MB | ~4KB |
| Expires | Never (manual clear) | Tab close | Set by expires |
| Accessible in JS | Yes | Yes | Yes |
| Sent with requests | No | No | Yes (automatic) |
| Server can set | No | No | Yes |
| Best for | User preferences, cache | Multi-step forms | Auth tokens, session IDs |
Geolocation API
Retrieve the user's geographic location (requires user permission):
<button onclick="getLocation()">Find My Location</button>
<p id="location-output"></p>
<script>
function getLocation() {
const output = document.getElementById('location-output');
if (!navigator.geolocation) {
output.textContent = 'Geolocation is not supported by your browser.';
return;
}
output.textContent = 'Locating...';
navigator.geolocation.getCurrentPosition(
// Success callback
(position) => {
const lat = position.coords.latitude.toFixed(4);
const lon = position.coords.longitude.toFixed(4);
const accuracy = Math.round(position.coords.accuracy);
output.textContent = `Latitude: ${lat}, Longitude: ${lon} (±${accuracy}m)`;
},
// Error callback
(error) => {
switch(error.code) {
case error.PERMISSION_DENIED:
output.textContent = 'Location access denied.';
break;
case error.POSITION_UNAVAILABLE:
output.textContent = 'Location unavailable.';
break;
case error.TIMEOUT:
output.textContent = 'Location request timed out.';
break;
}
},
// Options
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 60000 // Use cached position up to 1 min old
}
);
}
</script>
Details and Summary — Native Accordion
<details> and <summary> create an expandable/collapsible widget without any JavaScript:
<!-- Basic accordion -->
<details>
<summary>What is HTML?</summary>
<p>HTML (HyperText Markup Language) is the standard language for
creating web pages. It defines the structure and content.</p>
</details>
<!-- Open by default -->
<details open>
<summary>Installation Instructions</summary>
<ol>
<li>Download VS Code from code.visualstudio.com</li>
<li>Install the Live Server extension</li>
<li>Create a new .html file and open with Live Server</li>
</ol>
</details>
<!-- FAQ Section -->
<section>
<h2>Frequently Asked Questions</h2>
<details>
<summary>Is HTML a programming language?</summary>
<p>No. HTML is a markup language. It describes the structure and
meaning of content, but contains no logic, loops, or conditions.</p>
</details>
<details>
<summary>What is the difference between HTML and HTML5?</summary>
<p>HTML5 is the latest version, adding semantic elements, native
audio/video, canvas, web storage, and many other APIs.</p>
</details>
<details>
<summary>Do I need CSS to use HTML?</summary>
<p>No — HTML works without CSS, but it will look plain. CSS
controls the visual presentation of HTML elements.</p>
</details>
</section>
Dialog Element — Native Modal
The <dialog> element creates a native browser modal dialog:
<button onclick="document.getElementById('myDialog').showModal()">
Open Modal
</button>
<dialog id="myDialog">
<h2>Confirm Action</h2>
<p>Are you sure you want to delete this item? This cannot be undone.</p>
<div>
<button onclick="document.getElementById('myDialog').close()">Cancel</button>
<button onclick="deleteItem()">Delete</button>
</div>
</dialog>
<script>
// Open as modal (with backdrop)
document.getElementById('myDialog').showModal();
// Open as non-modal (no backdrop)
document.getElementById('myDialog').show();
// Close
document.getElementById('myDialog').close();
// Close on backdrop click
document.getElementById('myDialog').addEventListener('click', (e) => {
if (e.target === e.currentTarget) e.target.close();
});
</script>
Native <dialog> advantages over custom modals:
- Built-in focus trapping (keyboard stays inside dialog)
- Accessible out of the box (ARIA roles applied automatically)
- Backdrop overlay with
::backdrop CSS pseudo-element - Escape key closes it automatically
Progress and Meter
<progress> — Task Completion
<!-- Determinate progress (known total) -->
<label for="upload-progress">Upload Progress:</label>
<progress id="upload-progress" value="65" max="100">65%</progress>
<!-- Indeterminate progress (unknown duration) -->
<progress>Loading...</progress>
<meter> — Scalar Measurement
<!-- Disk usage -->
<label for="disk">Disk Usage:</label>
<meter id="disk" value="0.7" min="0" max="1" low="0.25" high="0.75" optimum="0.5">
70% used
</meter>
<!-- Score -->
<label for="score">Test Score:</label>
<meter id="score" value="82" min="0" max="100" low="50" high="80" optimum="100">
82 out of 100
</meter>
| Attribute | Meaning |
|---|
value | Current value |
min / max | Range boundaries |
low | Below this = "low" (red/orange) |
high | Above this = "high" (green) |
optimum | Ideal value |
Template Element
<template> holds HTML that is not rendered until activated by JavaScript — useful for reusable UI patterns:
<template id="card-template">
<div class="card">
<img class="card-image" src="" alt="">
<div class="card-body">
<h3 class="card-title"></h3>
<p class="card-description"></p>
<a class="card-link" href="">Learn More →</a>
</div>
</div>
</template>
<div id="card-container"></div>
<script>
const courses = [
{ title: 'HTML Guide', desc: 'Master HTML5', link: '/html', img: '/html.png' },
{ title: 'CSS Guide', desc: 'Master CSS3', link: '/css', img: '/css.png' },
];
const template = document.getElementById('card-template');
const container = document.getElementById('card-container');
courses.forEach(course => {
const clone = template.content.cloneNode(true);
clone.querySelector('.card-title').textContent = course.title;
clone.querySelector('.card-description').textContent = course.desc;
clone.querySelector('.card-link').href = course.link;
clone.querySelector('.card-image').src = course.img;
clone.querySelector('.card-image').alt = course.title;
container.appendChild(clone);
});
</script>
Summary of HTML5 Features
| Feature | Element/API | Key Use |
|---|
| Audio | <audio> | Native audio playback |
| Video | <video> + <track> | Native video with subtitles |
| Drawing | <canvas> | 2D graphics via JavaScript |
| Persistent storage | localStorage | User preferences, cache |
| Session storage | sessionStorage | Temporary form data |
| Location | Geolocation API | Maps, local content |
| Accordion | <details> + <summary> | FAQ, collapse without JS |
| Modal | <dialog> | Native accessible modal |
| Progress | <progress> | Task completion indicator |
| Gauge | <meter> | Scalar measurement display |
| Templates | <template> | Reusable HTML fragments |
*Next: HTML Interview Preparation*