引言

欢迎来到HTML5的世界!如果你是完全的编程新手,或者想要系统地学习网页开发,那么你来对地方了。HTML5是构建现代网页和Web应用的基石,它定义了网页的结构和内容。本指南将带你从零开始,逐步掌握HTML5的核心概念、语法和实战技巧,让你能够独立创建功能丰富的网页。

为什么学习HTML5?

  • 现代Web标准:HTML5是当前Web开发的最新标准,支持丰富的多媒体、图形和交互功能。
  • 跨平台兼容:HTML5网页可以在各种设备上运行,包括桌面、手机和平板。
  • 职业发展:掌握HTML5是成为前端开发者、全栈开发者或Web设计师的必备技能。
  • 社区支持:拥有庞大的开发者社区和丰富的学习资源。

第一部分:HTML5基础概念

1.1 什么是HTML5?

HTML(HyperText Markup Language)是一种标记语言,用于创建网页的结构。HTML5是HTML的第五次重大修订,引入了许多新特性,如语义化标签、多媒体支持、图形绘制、本地存储等。

1.2 HTML5文档结构

一个基本的HTML5文档结构如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个HTML5页面</title>
</head>
<body>
    <!-- 页面内容将在这里编写 -->
</body>
</html>

代码解释

  • <!DOCTYPE html>:声明文档类型为HTML5。
  • <html>:根元素,lang属性指定语言为中文。
  • <head>:包含文档的元数据,如字符集、视口设置和标题。
  • <meta charset="UTF-8">:指定字符编码为UTF-8,支持中文。
  • <meta name="viewport">:确保页面在移动设备上正确缩放。
  • <title>:定义浏览器标签页的标题。
  • <body>:包含所有可见内容,如文本、图像、链接等。

1.3 HTML5标签与属性

HTML5使用标签来定义元素。标签通常成对出现,如<p></p>。属性提供额外信息,如<a href="https://example.com">链接</a>

常见标签

  • 标题:<h1><h6>
  • 段落:<p>
  • 链接:<a>
  • 图像:<img>
  • 列表:<ul>(无序)、<ol>(有序)、<li>
  • 表格:<table>, <tr>, <td>, <th>

HTML5新特性

  • 语义化标签:<header>, <nav>, <section>, <article>, <footer>等,用于描述内容结构。
  • 多媒体标签:<audio>, <video>, <canvas>
  • 表单增强:<input>类型如email, date, range等。

第二部分:HTML5核心技能

2.1 语义化标签

语义化标签让代码更易读,并有助于SEO和可访问性。

示例:创建一个简单的博客页面结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>我的博客</title>
</head>
<body>
    <header>
        <h1>我的博客</h1>
        <nav>
            <ul>
                <li><a href="#home">首页</a></li>
                <li><a href="#about">关于</a></li>
                <li><a href="#contact">联系</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <article>
            <h2>HTML5入门指南</h2>
            <p>HTML5是构建现代网页的核心技术...</p>
            <section>
                <h3>为什么学习HTML5?</h3>
                <p>HTML5提供了丰富的API和特性...</p>
            </section>
        </article>
    </main>

    <footer>
        <p>&copy; 2023 我的博客. 保留所有权利。</p>
    </footer>
</body>
</html>

解释

  • <header>:定义页面或文章的头部。
  • <nav>:定义导航链接。
  • <main>:定义主要内容区域。
  • <article>:定义独立的内容块(如博客文章)。
  • <section>:定义文档中的一个区域或主题。
  • <footer>:定义页面或文章的页脚。

2.2 多媒体元素

HTML5原生支持音频和视频,无需插件。

示例:嵌入视频和音频

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>多媒体示例</title>
</head>
<body>
    <h1>视频播放器</h1>
    <video controls width="640" height="360" poster="poster.jpg">
        <source src="movie.mp4" type="video/mp4">
        <source src="movie.webm" type="video/webm">
        您的浏览器不支持视频标签。
    </video>

    <h1>音频播放器</h1>
    <audio controls>
        <source src="audio.mp3" type="audio/mpeg">
        <source src="audio.ogg" type="audio/ogg">
        您的浏览器不支持音频标签。
    </audio>
</body>
</html>

解释

  • <video>:嵌入视频,controls属性显示播放控件。
  • <source>:指定多个媒体源,浏览器会选择支持的格式。
  • <audio>:嵌入音频,用法类似视频。
  • poster:视频未加载时显示的封面图。

2.3 表单与输入

HTML5表单增强了用户体验,提供了新的输入类型和验证。

示例:用户注册表单

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>注册表单</title>
</head>
<body>
    <h1>用户注册</h1>
    <form action="/submit" method="post">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" required minlength="3" maxlength="20">
        <br><br>

        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" required>
        <br><br>

        <label for="password">密码:</label>
        <input type="password" id="password" name="password" required minlength="8">
        <br><br>

        <label for="birthdate">出生日期:</label>
        <input type="date" id="birthdate" name="birthdate">
        <br><br>

        <label for="age">年龄:</label>
        <input type="range" id="age" name="age" min="18" max="100" value="25">
        <span id="ageValue">25</span>
        <br><br>

        <label for="avatar">上传头像:</label>
        <input type="file" id="avatar" name="avatar" accept="image/*">
        <br><br>

        <label for="bio">个人简介:</label>
        <textarea id="bio" name="bio" rows="4" cols="50"></textarea>
        <br><br>

        <input type="submit" value="注册">
    </form>

    <script>
        // 简单的JavaScript来更新范围滑块的值
        const ageInput = document.getElementById('age');
        const ageValue = document.getElementById('ageValue');
        ageInput.addEventListener('input', function() {
            ageValue.textContent = this.value;
        });
    </script>
</body>
</html>

解释

  • required:字段必填。
  • minlength/maxlength:文本长度限制。
  • type="email":自动验证邮箱格式。
  • type="date":日期选择器。
  • type="range":滑块控件。
  • type="file":文件上传。
  • <textarea>:多行文本输入。
  • <label>:提高可访问性,点击标签可聚焦输入框。

2.4 图形与绘图

HTML5引入了<canvas>元素,允许通过JavaScript动态绘制图形。

示例:使用Canvas绘制一个简单的图形

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-UTF-8">
    <title>Canvas绘图</title>
    <style>
        canvas {
            border: 1px solid #ccc;
            display: block;
            margin: 20px auto;
        }
    </style>
</head>
<body>
    <h1>Canvas绘图示例</h1>
    <canvas id="myCanvas" width="400" height="200"></canvas>

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

        // 绘制矩形
        ctx.fillStyle = 'blue';
        ctx.fillRect(10, 10, 150, 80);

        // 绘制圆形
        ctx.beginPath();
        ctx.arc(250, 50, 40, 0, 2 * Math.PI);
        ctx.fillStyle = 'red';
        ctx.fill();

        // 绘制文本
        ctx.fillStyle = 'black';
        ctx.font = '20px Arial';
        ctx.fillText('Hello Canvas!', 10, 150);

        // 绘制线条
        ctx.beginPath();
        ctx.moveTo(10, 180);
        ctx.lineTo(390, 180);
        ctx.strokeStyle = 'green';
        ctx.lineWidth = 2;
        ctx.stroke();
    </script>
</body>
</html>

解释

  • <canvas>:定义绘图区域,通过JavaScript的getContext('2d')获取2D绘图上下文。
  • fillRect(x, y, width, height):绘制填充矩形。
  • arc(x, y, radius, startAngle, endAngle):绘制圆弧。
  • fillText(text, x, y):绘制文本。
  • moveTo(x, y)lineTo(x, y):绘制路径线条。

第三部分:实战技巧与最佳实践

3.1 响应式设计基础

响应式设计确保网页在不同设备上都能良好显示。使用HTML5的<meta>标签和CSS媒体查询。

示例:响应式布局基础

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }
        .container {
            width: 100%;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .header {
            background-color: #333;
            color: white;
            padding: 20px;
            text-align: center;
        }
        .main-content {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-top: 20px;
        }
        .sidebar {
            flex: 1;
            min-width: 200px;
            background-color: #f4f4f4;
            padding: 15px;
        }
        .content {
            flex: 3;
            min-width: 300px;
            background-color: #fff;
            padding: 15px;
        }
        .footer {
            background-color: #333;
            color: white;
            padding: 20px;
            text-align: center;
            margin-top: 20px;
        }

        /* 媒体查询:当屏幕宽度小于768px时,调整布局 */
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }
            .sidebar, .content {
                flex: none;
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header class="header">
            <h1>响应式网站标题</h1>
        </header>
        <div class="main-content">
            <aside class="sidebar">
                <h3>侧边栏</h3>
                <p>这里是侧边栏内容。</p>
            </aside>
            <main class="content">
                <h2>主要内容</h2>
                <p>这里是主要内容区域。当屏幕变小时,布局会自动调整。</p>
            </main>
        </div>
        <footer class="footer">
            <p>&copy; 2023 响应式网站示例</p>
        </footer>
    </div>
</body>
</html>

解释

  • <meta name="viewport">:确保移动设备正确缩放。
  • CSS Flexbox:创建灵活的布局。
  • 媒体查询:根据屏幕尺寸应用不同样式。

3.2 表单验证与用户体验

HTML5内置表单验证,但结合JavaScript可以提供更友好的体验。

示例:增强的表单验证

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>增强表单验证</title>
    <style>
        .error {
            color: red;
            font-size: 0.9em;
            display: none;
        }
        input:invalid {
            border-color: red;
        }
        input:valid {
            border-color: green;
        }
    </style>
</head>
<body>
    <h1>用户反馈表单</h1>
    <form id="feedbackForm">
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" required minlength="2">
        <span class="error" id="nameError">姓名至少需要2个字符</span>
        <br><br>

        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" required>
        <span class="error" id="emailError">请输入有效的邮箱地址</span>
        <br><br>

        <label for="message">反馈内容:</label>
        <textarea id="message" name="message" required minlength="10"></textarea>
        <span class="error" id="messageError">反馈内容至少需要10个字符</span>
        <br><br>

        <input type="submit" value="提交反馈">
    </form>

    <script>
        const form = document.getElementById('feedbackForm');
        const nameInput = document.getElementById('name');
        const emailInput = document.getElementById('email');
        const messageInput = document.getElementById('message');
        const nameError = document.getElementById('nameError');
        const emailError = document.getElementById('emailError');
        const messageError = document.getElementById('messageError');

        // 实时验证
        nameInput.addEventListener('input', function() {
            if (nameInput.value.length < 2) {
                nameError.style.display = 'block';
            } else {
                nameError.style.display = 'none';
            }
        });

        emailInput.addEventListener('input', function() {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(emailInput.value)) {
                emailError.style.display = 'block';
            } else {
                emailError.style.display = 'none';
            }
        });

        messageInput.addEventListener('input', function() {
            if (messageInput.value.length < 10) {
                messageError.style.display = 'block';
            } else {
                messageError.style.display = 'none';
            }
        });

        // 表单提交验证
        form.addEventListener('submit', function(e) {
            let isValid = true;

            if (nameInput.value.length < 2) {
                nameError.style.display = 'block';
                isValid = false;
            }

            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(emailInput.value)) {
                emailError.style.display = 'block';
                isValid = false;
            }

            if (messageInput.value.length < 10) {
                messageError.style.display = 'block';
                isValid = false;
            }

            if (!isValid) {
                e.preventDefault(); // 阻止表单提交
                alert('请修正表单错误后再提交。');
            }
        });
    </script>
</body>
</html>

解释

  • requiredminlength等HTML5属性提供基本验证。
  • CSS伪类:invalid:valid提供视觉反馈。
  • JavaScript添加实时验证和自定义错误消息。

3.3 本地存储与离线应用

HTML5提供了Web Storage(localStorage和sessionStorage)和IndexedDB,用于在客户端存储数据。

示例:使用localStorage保存用户偏好

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>本地存储示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
        }
        .theme-selector {
            margin-bottom: 20px;
        }
        .content {
            padding: 20px;
            border: 1px solid #ccc;
            transition: background-color 0.3s, color 0.3s;
        }
        .light-theme {
            background-color: #fff;
            color: #000;
        }
        .dark-theme {
            background-color: #333;
            color: #fff;
        }
    </style>
</head>
<body>
    <h1>本地存储示例</h1>
    <div class="theme-selector">
        <label>选择主题:</label>
        <select id="themeSelect">
            <option value="light">浅色主题</option>
            <option value="dark">深色主题</option>
        </select>
        <button id="saveTheme">保存主题</button>
        <button id="clearStorage">清除存储</button>
    </div>

    <div class="content light-theme" id="content">
        <h2>示例内容</h2>
        <p>这个页面的主题偏好会保存在本地存储中,即使刷新页面也会保持。</p>
        <p>点击“保存主题”按钮将当前选择保存到localStorage。</p>
    </div>

    <script>
        const themeSelect = document.getElementById('themeSelect');
        const saveButton = document.getElementById('saveTheme');
        const clearButton = document.getElementById('clearStorage');
        const content = document.getElementById('content');

        // 页面加载时,从localStorage读取主题
        window.addEventListener('DOMContentLoaded', function() {
            const savedTheme = localStorage.getItem('theme');
            if (savedTheme) {
                themeSelect.value = savedTheme;
                applyTheme(savedTheme);
            }
        });

        // 保存主题
        saveButton.addEventListener('click', function() {
            const selectedTheme = themeSelect.value;
            localStorage.setItem('theme', selectedTheme);
            applyTheme(selectedTheme);
            alert('主题已保存!');
        });

        // 清除存储
        clearButton.addEventListener('click', function() {
            localStorage.removeItem('theme');
            themeSelect.value = 'light';
            applyTheme('light');
            alert('存储已清除!');
        });

        // 应用主题
        function applyTheme(theme) {
            content.className = 'content ' + theme + '-theme';
        }
    </script>
</body>
</html>

解释

  • localStorage.setItem(key, value):存储数据,数据在浏览器关闭后仍保留。
  • localStorage.getItem(key):读取数据。
  • localStorage.removeItem(key):删除特定数据。
  • localStorage.clear():清除所有数据(本例未使用)。

3.4 无障碍访问(Accessibility)

确保网页对所有人(包括残障人士)都可访问。

示例:添加ARIA属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>无障碍访问示例</title>
    <style>
        .sr-only {
            position: absolute;
            width: 1px;
            height: 1px;
            padding: 0;
            margin: -1px;
            overflow: hidden;
            clip: rect(0, 0, 0, 0);
            white-space: nowrap;
            border: 0;
        }
        .nav-menu {
            list-style: none;
            padding: 0;
            display: flex;
            gap: 10px;
        }
        .nav-menu li a {
            padding: 10px;
            background-color: #f0f0f0;
            text-decoration: none;
            color: #333;
        }
        .nav-menu li a:focus {
            outline: 2px solid blue;
            background-color: #e0e0e0;
        }
        .button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            cursor: pointer;
        }
        .button:focus {
            outline: 2px solid orange;
        }
    </style>
</head>
<body>
    <h1>无障碍访问示例</h1>

    <!-- 使用ARIA属性的导航 -->
    <nav aria-label="主导航">
        <ul class="nav-menu">
            <li><a href="#home" aria-current="page">首页</a></li>
            <li><a href="#about">关于</a></li>
            <li><a href="#services">服务</a></li>
            <li><a href="#contact">联系</a></li>
        </ul>
    </nav>

    <!-- 使用ARIA属性的按钮 -->
    <button class="button" aria-label="关闭弹窗" onclick="alert('按钮被点击')">
        <span aria-hidden="true">✕</span>
        <span class="sr-only">关闭</span>
    </button>

    <!-- 使用ARIA属性的表单 -->
    <form aria-labelledby="formTitle">
        <h2 id="formTitle">联系表单</h2>
        <div>
            <label for="name">姓名:</label>
            <input type="text" id="name" name="name" aria-required="true" aria-describedby="nameDesc">
            <span id="nameDesc" class="sr-only">请输入您的全名</span>
        </div>
        <div>
            <label for="email">邮箱:</label>
            <input type="email" id="email" name="email" aria-required="true" aria-describedby="emailDesc">
            <span id="emailDesc" class="sr-only">我们将通过此邮箱与您联系</span>
        </div>
        <button type="submit" class="button">提交</button>
    </form>

    <!-- 使用ARIA属性的动态内容 -->
    <div id="status" role="status" aria-live="polite" aria-atomic="true">
        <!-- 动态消息将在这里显示 -->
    </div>

    <script>
        // 模拟动态更新状态消息
        const statusDiv = document.getElementById('status');
        setTimeout(() => {
            statusDiv.textContent = '表单提交成功!感谢您的反馈。';
        }, 2000);
    </script>
</body>
</html>

解释

  • aria-label:为元素提供可访问的名称。
  • aria-current="page":指示当前页面。
  • aria-hidden="true":隐藏装饰性元素。
  • sr-only类:视觉隐藏但屏幕阅读器可读。
  • aria-required:指示必填字段。
  • aria-describedby:关联描述文本。
  • role="status"aria-live="polite":动态内容更新时通知屏幕阅读器。

第四部分:项目实战

4.1 项目1:个人简历页面

目标:创建一个响应式的个人简历页面,展示个人信息、教育背景、工作经验和技能。

步骤

  1. 规划结构:使用语义化标签组织内容。
  2. 编写HTML:创建基本结构。
  3. 添加CSS:实现响应式布局和样式。
  4. 测试:在不同设备上测试。

示例代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>张三的简历</title>
    <style>
        /* 基础样式 */
        body {
            font-family: 'Arial', sans-serif;
            line-height: 1.6;
            color: #333;
            margin: 0;
            padding: 0;
            background-color: #f9f9f9;
        }
        .container {
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            background: white;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        header {
            text-align: center;
            border-bottom: 2px solid #007bff;
            padding-bottom: 20px;
            margin-bottom: 20px;
        }
        h1 {
            color: #007bff;
            margin: 0;
        }
        .contact-info {
            margin-top: 10px;
            font-size: 0.9em;
            color: #666;
        }
        section {
            margin-bottom: 25px;
        }
        h2 {
            color: #007bff;
            border-bottom: 1px solid #eee;
            padding-bottom: 5px;
        }
        .skill-bar {
            background-color: #eee;
            border-radius: 5px;
            margin: 5px 0;
            overflow: hidden;
        }
        .skill-level {
            height: 20px;
            background-color: #007bff;
            text-align: center;
            color: white;
            font-size: 0.8em;
            line-height: 20px;
        }
        .experience-item, .education-item {
            margin-bottom: 15px;
        }
        .experience-item h3, .education-item h3 {
            margin: 0;
            color: #333;
        }
        .experience-item p, .education-item p {
            margin: 5px 0;
            color: #666;
            font-size: 0.9em;
        }

        /* 响应式设计 */
        @media (max-width: 600px) {
            .container {
                margin: 10px;
                padding: 15px;
            }
            header {
                padding-bottom: 15px;
            }
            h1 {
                font-size: 1.5em;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>张三</h1>
            <div class="contact-info">
                <p>电话:138-0000-0000 | 邮箱:zhangsan@example.com | 地址:北京市朝阳区</p>
            </div>
        </header>

        <main>
            <section id="summary">
                <h2>个人简介</h2>
                <p>我是一名充满热情的前端开发者,拥有3年的Web开发经验。擅长HTML5、CSS3和JavaScript,对响应式设计和用户体验有深入理解。目前正在学习Vue.js和React框架。</p>
            </section>

            <section id="skills">
                <h2>专业技能</h2>
                <div class="skill-item">
                    <p>HTML5/CSS3</p>
                    <div class="skill-bar">
                        <div class="skill-level" style="width: 90%;">90%</div>
                    </div>
                </div>
                <div class="skill-item">
                    <p>JavaScript</p>
                    <div class="skill-bar">
                        <div class="skill-level" style="width: 85%;">85%</div>
                    </div>
                </div>
                <div class="skill-item">
                    <p>响应式设计</p>
                    <div class="skill-bar">
                        <div class="skill-level" style="width: 80%;">80%</div>
                    </div>
                </div>
                <div class="skill-item">
                    <p>Git版本控制</p>
                    <div class="skill-bar">
                        <div class="skill-level" style="width: 75%;">75%</div>
                    </div>
                </div>
            </section>

            <section id="experience">
                <h2>工作经验</h2>
                <div class="experience-item">
                    <h3>前端开发工程师 - ABC科技有限公司</h3>
                    <p>2021年6月 - 至今</p>
                    <ul>
                        <li>负责公司官网的前端开发和维护</li>
                        <li>使用HTML5、CSS3和JavaScript开发响应式页面</li>
                        <li>与设计师和后端工程师协作,确保项目按时交付</li>
                    </ul>
                </div>
                <div class="experience-item">
                    <h3>Web开发实习生 - XYZ互联网公司</h3>
                    <p>2020年7月 - 2021年5月</p>
                    <ul>
                        <li>参与内部管理系统的前端开发</li>
                        <li>学习并应用Vue.js框架</li>
                        <li>编写技术文档和用户手册</li>
                    </ul>
                </div>
            </section>

            <section id="education">
                <h2>教育背景</h2>
                <div class="education-item">
                    <h3>计算机科学与技术 - 本科</h3>
                    <p>北京大学 | 2016年9月 - 2020年6月</p>
                    <p>主修课程:数据结构、算法、Web开发、数据库系统</p>
                </div>
            </section>
        </main>

        <footer>
            <p style="text-align: center; color: #666; font-size: 0.8em; margin-top: 30px;">
                &copy; 2023 张三. 保留所有权利。
            </p>
        </footer>
    </div>
</body>
</html>

4.2 项目2:交互式待办事项列表

目标:创建一个简单的待办事项列表,使用HTML5、CSS和JavaScript实现添加、删除和标记完成的功能。

步骤

  1. HTML结构:创建表单和列表容器。
  2. CSS样式:美化界面。
  3. JavaScript逻辑:处理用户交互和数据存储。

示例代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>待办事项列表</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f5f5f5;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        .todo-container {
            background: white;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            width: 100%;
            max-width: 500px;
            padding: 25px;
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 20px;
        }
        .input-section {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }
        #todoInput {
            flex: 1;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 5px;
            font-size: 16px;
            transition: border-color 0.3s;
        }
        #todoInput:focus {
            outline: none;
            border-color: #007bff;
        }
        #addBtn {
            padding: 12px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        #addBtn:hover {
            background-color: #0056b3;
        }
        #todoList {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        .todo-item {
            display: flex;
            align-items: center;
            padding: 12px;
            background-color: #f9f9f9;
            border-radius: 5px;
            margin-bottom: 8px;
            transition: background-color 0.3s;
        }
        .todo-item:hover {
            background-color: #e9e9e9;
        }
        .todo-item.completed {
            background-color: #e8f5e9;
            text-decoration: line-through;
            color: #666;
        }
        .todo-item input[type="checkbox"] {
            margin-right: 12px;
            width: 18px;
            height: 18px;
            cursor: pointer;
        }
        .todo-text {
            flex: 1;
            font-size: 16px;
            cursor: pointer;
        }
        .delete-btn {
            background-color: #ff4d4d;
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }
        .delete-btn:hover {
            background-color: #e60000;
        }
        .empty-message {
            text-align: center;
            color: #999;
            padding: 20px;
            font-style: italic;
        }
        .stats {
            display: flex;
            justify-content: space-between;
            margin-top: 20px;
            padding-top: 15px;
            border-top: 1px solid #eee;
            color: #666;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="todo-container">
        <h1>待办事项列表</h1>
        
        <div class="input-section">
            <input type="text" id="todoInput" placeholder="添加新任务..." maxlength="100">
            <button id="addBtn">添加</button>
        </div>
        
        <ul id="todoList"></ul>
        
        <div class="stats">
            <span id="totalTasks">总任务: 0</span>
            <span id="completedTasks">已完成: 0</span>
            <span id="pendingTasks">待完成: 0</span>
        </div>
    </div>

    <script>
        // 获取DOM元素
        const todoInput = document.getElementById('todoInput');
        const addBtn = document.getElementById('addBtn');
        const todoList = document.getElementById('todoList');
        const totalTasks = document.getElementById('totalTasks');
        const completedTasks = document.getElementById('completedTasks');
        const pendingTasks = document.getElementById('pendingTasks');

        // 从localStorage加载任务
        let todos = JSON.parse(localStorage.getItem('todos')) || [];

        // 初始化
        function init() {
            renderTodos();
            updateStats();
        }

        // 渲染任务列表
        function renderTodos() {
            todoList.innerHTML = '';
            
            if (todos.length === 0) {
                todoList.innerHTML = '<div class="empty-message">暂无任务,添加一个吧!</div>';
                return;
            }

            todos.forEach((todo, index) => {
                const li = document.createElement('li');
                li.className = `todo-item ${todo.completed ? 'completed' : ''}`;
                
                li.innerHTML = `
                    <input type="checkbox" ${todo.completed ? 'checked' : ''} 
                           onchange="toggleComplete(${index})">
                    <span class="todo-text" onclick="toggleComplete(${index})">${todo.text}</span>
                    <button class="delete-btn" onclick="deleteTodo(${index})">删除</button>
                `;
                
                todoList.appendChild(li);
            });
        }

        // 更新统计信息
        function updateStats() {
            const total = todos.length;
            const completed = todos.filter(todo => todo.completed).length;
            const pending = total - completed;
            
            totalTasks.textContent = `总任务: ${total}`;
            completedTasks.textContent = `已完成: ${completed}`;
            pendingTasks.textContent = `待完成: ${pending}`;
        }

        // 保存到localStorage
        function saveToStorage() {
            localStorage.setItem('todos', JSON.stringify(todos));
        }

        // 添加新任务
        function addTodo() {
            const text = todoInput.value.trim();
            
            if (text === '') {
                alert('请输入任务内容!');
                return;
            }
            
            const newTodo = {
                text: text,
                completed: false,
                createdAt: new Date().toISOString()
            };
            
            todos.push(newTodo);
            saveToStorage();
            renderTodos();
            updateStats();
            
            todoInput.value = '';
            todoInput.focus();
        }

        // 切换完成状态
        function toggleComplete(index) {
            todos[index].completed = !todos[index].completed;
            saveToStorage();
            renderTodos();
            updateStats();
        }

        // 删除任务
        function deleteTodo(index) {
            if (confirm('确定要删除这个任务吗?')) {
                todos.splice(index, 1);
                saveToStorage();
                renderTodos();
                updateStats();
            }
        }

        // 事件监听
        addBtn.addEventListener('click', addTodo);
        
        todoInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                addTodo();
            }
        });

        // 初始化应用
        init();
    </script>
</body>
</html>

第五部分:学习资源与进阶路径

5.1 推荐学习资源

  1. 官方文档

  2. 在线课程

  3. 书籍推荐

    • 《HTML5与CSS3权威指南》
    • 《深入理解HTML5:语义、标准与样式》
    • 《JavaScript高级程序设计》
  4. 工具与编辑器

    • Visual Studio Code (推荐)
    • Sublime Text
    • Chrome开发者工具

5.2 进阶学习路径

  1. CSS深入学习

    • Flexbox和Grid布局
    • CSS动画和过渡
    • 预处理器(Sass/Less)
  2. JavaScript基础

    • ES6+新特性
    • DOM操作和事件处理
    • 异步编程(Promise, async/await)
  3. 前端框架

    • React.js
    • Vue.js
    • Angular
  4. 工具链

    • 包管理器(npm/yarn)
    • 构建工具(Webpack/Vite)
    • 版本控制(Git)
  5. 项目实践

    • 个人项目(博客、电商网站)
    • 开源项目贡献
    • 参加编程挑战(如LeetCode前端题目)

5.3 常见问题与解决方案

问题1:HTML5标签在旧浏览器中不显示

  • 解决方案:使用Polyfill或提供降级方案。例如,对于<canvas>,可以提供备用内容。

问题2:表单验证不工作

  • 解决方案:确保浏览器支持HTML5验证,或使用JavaScript进行自定义验证。

问题3:响应式设计在移动设备上显示异常

  • 解决方案:检查viewport meta标签,使用媒体查询测试不同设备。

问题4:本地存储数据丢失

  • 解决方案:检查浏览器隐私设置,确保未启用无痕模式或清除数据。

结语

通过本指南,你已经从零开始学习了HTML5的核心概念、语法和实战技巧。记住,编程是一个持续学习的过程,实践是最好的老师。建议你从简单的项目开始,逐步挑战更复杂的应用。

下一步行动

  1. 创建一个个人项目(如个人网站或博客)
  2. 学习CSS和JavaScript以增强你的网页
  3. 加入开发者社区(如GitHub、Stack Overflow)
  4. 持续练习和构建项目

祝你在网页开发的旅程中取得成功!