Skip to main content

Html5 new features and apis

HTML5 new features - the 2014 standard that replaced plugin-dependent web development with native browser capabilities for semantic structure, multimedia, forms, and JavaScript APIs.

Theory

TL;DR

  • Semantic elements (<article>, <section>, <nav>) describe what content means, not how it looks
  • <video> and <audio> replaced Flash completely; provide multiple <source> tags for cross-browser support
  • Form inputs have built-in validation via type="email", required, pattern, no JavaScript needed
  • APIs (Geolocation, LocalStorage, Canvas, Web Workers) moved capabilities out of plugins into the browser
  • Canvas = pixel drawing for games and graphics; SVG = vector shapes for icons and scalable illustrations

Quick example

html
<!-- Before HTML5: meaningless divs --> <div id="header"> <div id="nav">...</div> </div> <!-- HTML5: structure has meaning --> <header> <nav>...</nav> </header> <main> <article> <h1>Product Review</h1> <section>...</section> </article> </main> <footer>...</footer> <!-- Native video, no Flash needed --> <video controls width="640"> <source src="movie.webm" type="video/webm"> <source src="movie.mp4" type="video/mp4"> </video> <!-- Built-in form validation --> <input type="email" required> <input type="date">

Screen readers and search engines read element types directly. No ARIA attributes required for basic structure.

What HTML5 actually changed

HTML4 described how content should look. HTML5 describes what content means. A <nav> tells a screen reader "this is navigation" without extra markup. An <article> signals self-contained content to search engines. This shift from presentation to semantics is the core idea.

APIs moved power from plugins to JavaScript. Before HTML5, you needed Flash for video, Java applets for graphics, and third-party libraries for geolocation. Now all of that runs natively in the browser runtime.

Semantic elements

ElementPurpose
<header>Page or section header
<nav>Navigation links
<main>Primary page content (one per page)
<article>Self-contained content (blog post, product card)
<section>Thematic grouping within an article
<aside>Related but secondary content (sidebar)
<footer>Page or section footer
<figure> / <figcaption>Image or diagram with a linked caption
<details> / <summary>Collapsible content without JavaScript

Use all of these for structural content. They cost nothing and improve accessibility and SEO.

JavaScript APIs

APIWhat it doesWhen to use
Canvas APIPixel-level drawing via <canvas>Games, image editing, custom charts
GeolocationGets user coordinates from the OSMaps, local search
LocalStorage / SessionStorageClient-side key-value storage (5-10MB)User preferences, offline data
Web WorkersBackground threads that do not block the UIHeavy computation, data processing
WebSocketPersistent two-way server connectionChat, live dashboards
Service WorkersIntercept network requests, enable offlinePWAs, caching strategies
History APIpushState / replaceState for SPA routingSingle-page app navigation
Fetch APIModern HTTP requests, replaced XMLHttpRequestAll API calls in modern code

Canvas vs SVG

FeatureCanvasSVG
TypeRaster (pixels)Vector (shapes)
ScalabilityLoses quality on zoomScales perfectly
DOM accessNone (just pixels)Full (each shape is a DOM node)
Event handlingManual, coordinate-basedBuilt-in, per element
Best forGames, image processing, data chartsIcons, logos, illustrations

One pattern I see in interviews: candidates say "use Canvas for everything graphical." That is wrong. Canvas content is not searchable, selectable, or accessible. Use SVG for anything that needs to be interactive or zoomable.

Common mistakes

Mistake 1: Using <div> where semantic elements belong

html
<!-- Wrong: screen reader sees a generic box --> <div class="nav"> <a href="/">Home</a> </div> <!-- Right: navigation is announced as navigation --> <nav> <a href="/">Home</a> </nav>

About 15% of users rely on assistive technology. A <div> tells a screen reader nothing. A <nav> lets the user skip directly to navigation.

Mistake 2: Only one video source

html
<!-- Wrong: may break on Firefox depending on codec support --> <video controls> <source src="video.mp4" type="video/mp4"> </video> <!-- Right: browser picks the first format it can decode --> <video controls> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video>

Different browsers support different codecs. WebM is smaller but not supported in all Safari versions. MP4 works broadly. Providing multiple sources ensures playback everywhere.

Mistake 3: Trusting HTML5 form validation for security

html
<!-- Wrong assumption: this protects the server --> <input type="email" required> <!-- Any user bypasses this in DevTools: element.removeAttribute('required') Or just send a request with curl directly. -->

HTML5 validation is a UX feature. It improves user experience, not security. Always validate on the server too.

Mistake 4: Storing sensitive data in LocalStorage

javascript
// Wrong: any script on the page reads this localStorage.setItem('auth_token', token); // Right: use HttpOnly cookies for tokens // Server sets: Set-Cookie: auth_token=...; HttpOnly; Secure // JavaScript cannot access it at all

XSS attacks steal LocalStorage contents. HttpOnly cookies are invisible to JavaScript and only sent with requests automatically.

Mistake 5: Running heavy computation on the main thread

javascript
// Wrong: UI freezes completely during processing function processImage(data) { for (let i = 0; i < data.length; i++) { // heavy math blocks everything } } // Right: delegate to a Web Worker const worker = new Worker('processor.js'); worker.postMessage(imageData); worker.onmessage = (e) => ctx.putImageData(e.data, 0, 0);

JavaScript runs on a single thread. Long loops block all user interaction. Web Workers run in separate OS-level threads.

Real-world usage

  • React: type="email" on inputs, <figure> for image galleries, semantic elements throughout components
  • Next.js: semantic HTML for SSR SEO, Canvas for image optimization previews
  • Figma / Excalidraw: Canvas API for drawing, Web Workers for rendering large documents without freezing the tab
  • Google Maps / Mapbox: Canvas for custom tile rendering, Geolocation for user position
  • YouTube / Vimeo: <video> with adaptive bitrate streaming, Canvas for thumbnail generation
  • PWAs: LocalStorage plus Service Workers for offline data sync

Follow-up questions

Q: What is the difference between LocalStorage and SessionStorage?
A: LocalStorage persists until manually cleared and survives browser restarts. SessionStorage clears when the tab closes. Use LocalStorage for user preferences, SessionStorage for temporary data like partially filled forms.

Q: Can I skip semantic elements if I add ARIA attributes everywhere?
A: You can, but there is no good reason to. Semantic elements give you accessibility built-in. <nav> is equivalent to <div role="navigation"> but with less code and no risk of typos. Use native elements first; ARIA only for things HTML does not cover.

Q: How does the browser decide which <source> to play in <video>?
A: It reads the type attribute and checks whether it can decode that codec. It picks the first match. For adaptive streaming (quality switching mid-playback based on bandwidth), raw <source> tags are not enough. That requires HLS or DASH manifests, typically handled by a library like HLS.js.

Q: When should I not use Web Workers?
A: Worker creation costs roughly 50ms of overhead. For tasks under 100ms, the overhead outweighs the benefit. Profile the task first. Workers make sense for image processing, parsing large JSON files, or running physics simulations.

Q: Is the Fetch API part of HTML5?
A: Technically Fetch is a separate Living Standard maintained by WHATWG, not in the original HTML5 spec. But it is a core browser API from the same era of standardization and ships in every modern browser. Grouping it with HTML5 APIs in interviews is fine.

Examples

Semantic page structure with form validation

html
<header> <nav> <a href="/">Home</a> <a href="/products">Products</a> </nav> </header> <main> <article> <h1>Wireless Headphones</h1> <section> <h2>Details</h2> <p>Premium noise-canceling headphones...</p> </section> <section> <h2>Reviews</h2> <details> <summary>Show 5-star reviews (12)</summary> <p>User review content loads here</p> </details> </section> <aside> <h3>Related Products</h3> </aside> </article> <form> <input type="email" placeholder="Email" required> <input type="number" min="1" max="10" value="1"> <input type="date" required> <button type="submit">Order</button> <!-- Browser blocks submit if fields fail validation --> </form> </main> <footer> <p>&copy; 2025 Store</p> </footer>

The <details> and <summary> combo gives a collapsible section with zero JavaScript. The form submits only after the browser validates the type="email" format and confirms required fields are filled.

Canvas with Web Workers for image processing

javascript
// main.js - runs in the browser tab const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const worker = new Worker('grayscale.js'); worker.postMessage(imageData); worker.onmessage = (event) => { ctx.putImageData(event.data, 0, 0); // Canvas updated; user could click buttons the whole time }; // grayscale.js - runs in a separate thread self.onmessage = (event) => { const imageData = event.data; const data = imageData.data; for (let i = 0; i < data.length; i += 4) { const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114; data[i] = data[i + 1] = data[i + 2] = gray; // R, G, B set to same gray value } self.postMessage(imageData); };

The Worker runs in a separate OS-level thread. The main tab's event loop stays free. Without the Worker, processing a 4K image in a loop would freeze the UI for several hundred milliseconds.

LocalStorage with expiration

javascript
// Naive: token never expires, even after logout localStorage.setItem('user_token', token); // Better: wrap with expiry metadata function setWithExpiry(key, value, ttlMs) { const item = { value: value, expiry: Date.now() + ttlMs }; localStorage.setItem(key, JSON.stringify(item)); } function getWithExpiry(key) { const raw = localStorage.getItem(key); if (!raw) return null; const item = JSON.parse(raw); if (Date.now() > item.expiry) { localStorage.removeItem(key); return null; // expired, treat as missing } return item.value; } // Token lives for one hour setWithExpiry('user_token', token, 60 * 60 * 1000);

LocalStorage has no native expiry mechanism. This pattern wraps values in an object with a timestamp. The getter handles cleanup. Still, for actual auth tokens, prefer HttpOnly cookies.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?