Meta tags provide metadata about the HTML document. They live inside the <head>:
<meta charset="UTF-8">
<meta name="description" content="Free HTML tutorial for beginners">
<meta name="keywords" content="HTML, tutorial, beginner, web development">
<meta name="author" content="Your Name">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Open Graph (for social media sharing) -->
<meta property="og:title" content="HTML Tutorial">
<meta property="og:description" content="Learn HTML from scratch">
<meta property="og:image" content="images/og-preview.png">
<meta property="og:url" content="https://example.com/html-tutorial">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
Improve your site's visibility on search engines:
<article>, <nav>, <header>)<title> and <meta name="description"> for each page<h1> per page)alt text to imagesARIA (Accessible Rich Internet Applications) attributes help assistive technology understand your page:
<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<button aria-label="Close dialog" onclick="closeModal()">
×
</button>
<div role="alert" aria-live="polite">
Form submitted successfully!
</div>
Microdata helps search engines understand your content better:
<article itemscope itemtype="https://schema.org/Article">
<h1 itemprop="headline">How to Learn HTML</h1>
<p itemprop="description">A beginner's guide to HTML.</p>
<span itemprop="author" itemscope itemtype="https://schema.org/Person">
<span itemprop="name">John Doe</span>
</span>
<time itemprop="datePublished" datetime="2026-01-15">Jan 15, 2026</time>
</article>
Custom data-* attributes store extra information in HTML elements:
<button data-user-id="123" data-role="admin" onclick="showUser(this)">
User Profile
</button>
<script>
function showUser(btn) {
const userId = btn.dataset.userId;
const role = btn.dataset.role;
alert(`User ${userId} is an ${role}`);
}
</script>
The <template> tag holds HTML that isn't rendered until JavaScript clones it:
<template id="card-template">
<div class="card">
<img src="" alt="">
<h3></h3>
<p></p>
</div>
</template>
<script>
const clone = document.getElementById('card-template').content.cloneNode(true);
clone.querySelector('h3').textContent = 'Dynamic Title';
document.body.appendChild(clone);
</script>
Take your hobby page from Chapter 2 and enhance it with:
data-* attribute on an element