引言:为什么选择HTML5前端开发?

在当今数字化时代,前端开发已成为互联网行业的核心技能之一。HTML5作为现代Web开发的基石,不仅提供了丰富的语义化标签,还集成了强大的多媒体、图形和本地存储功能。从零基础开始学习HTML5前端开发,不仅能让你掌握构建现代网站和应用的能力,还能为后续学习CSS、JavaScript及各种前端框架打下坚实基础。

本攻略将带你从最基础的HTML标签开始,逐步深入到CSS样式、JavaScript交互,最终通过实战项目巩固所学知识。无论你是完全的编程新手,还是希望系统提升前端技能的开发者,都能在这里找到适合自己的学习路径。

第一部分:HTML5基础入门

1.1 HTML5简介与开发环境搭建

HTML5是HTML的第五次重大修订,它引入了大量新特性,如语义化标签、表单增强、Canvas绘图、Web Storage等。首先,我们需要搭建一个简单的开发环境。

开发工具推荐:

  • 文本编辑器:VS Code(推荐)、Sublime Text、Atom
  • 浏览器:Chrome(开发者工具强大)、Firefox
  • 本地服务器:Live Server(VS Code插件)或Python内置服务器

创建第一个HTML文件:

<!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>
    <h1>欢迎来到HTML5世界!</h1>
    <p>这是一个简单的段落。</p>
</body>
</html>

代码解析:

  • <!DOCTYPE html>:声明文档类型为HTML5
  • <html lang="zh-CN">:根元素,指定语言为中文
  • <head>:包含文档的元数据
  • <meta charset="UTF-8">:指定字符编码
  • <meta name="viewport">:移动端视口设置
  • <body>:页面可见内容

1.2 HTML5语义化标签

HTML5引入了大量语义化标签,使代码结构更清晰,对SEO和可访问性更友好。

常用语义化标签:

<header>
    <nav>
        <ul>
            <li><a href="#home">首页</a></li>
            <li><a href="#about">关于</a></li>
        </ul>
    </nav>
</header>

<main>
    <article>
        <h2>文章标题</h2>
        <p>文章内容...</p>
        <section>
            <h3>章节1</h3>
            <p>章节内容...</p>
        </section>
    </article>
    
    <aside>
        <h3>侧边栏</h3>
        <p>相关链接...</p>
    </aside>
</main>

<footer>
    <p>&copy; 2023 我的网站</p>
</footer>

语义化标签的优势:

  1. SEO优化:搜索引擎更容易理解页面结构
  2. 可访问性:屏幕阅读器能更好地解析页面
  3. 代码可读性:开发者能快速理解页面布局

1.3 HTML5表单增强

HTML5为表单元素带来了许多新特性和输入类型。

新输入类型示例:

<form>
    <!-- 邮箱验证 -->
    <label for="email">邮箱:</label>
    <input type="email" id="email" required>
    
    <!-- 日期选择器 -->
    <label for="birthdate">出生日期:</label>
    <input type="date" id="birthdate">
    
    <!-- 颜色选择器 -->
    <label for="color">选择颜色:</label>
    <input type="color" id="color">
    
    <!-- 滑块 -->
    <label for="volume">音量:</label>
    <input type="range" id="volume" min="0" max="100" value="50">
    
    <!-- 搜索框 -->
    <label for="search">搜索:</label>
    <input type="search" id="search" placeholder="输入关键词...">
    
    <!-- 数字输入 -->
    <label for="quantity">数量:</label>
    <input type="number" id="quantity" min="1" max="10" step="1">
    
    <!-- 提交按钮 -->
    <button type="submit">提交</button>
</form>

HTML5表单验证:

<form>
    <label for="username">用户名(必填,至少3个字符):</label>
    <input type="text" id="username" required minlength="3">
    
    <label for="password">密码(必填,至少8个字符):</label>
    <input type="password" id="password" required minlength="8">
    
    <label for="phone">电话(格式验证):</label>
    <input type="tel" id="phone" pattern="[0-9]{11}" placeholder="11位手机号">
    
    <button type="submit">注册</button>
</form>

第二部分:CSS3样式设计

2.1 CSS基础语法与选择器

CSS用于控制HTML元素的样式。我们可以通过多种方式引入CSS:

内联样式:

<p style="color: red; font-size: 16px;">这是一个段落</p>

内部样式表:

<head>
    <style>
        p {
            color: blue;
            font-size: 18px;
        }
    </style>
</head>

外部样式表(推荐):

<head>
    <link rel="stylesheet" href="styles.css">
</head>

CSS选择器示例:

/* 元素选择器 */
p {
    color: #333;
    line-height: 1.6;
}

/* 类选择器 */
.highlight {
    background-color: yellow;
    padding: 5px;
}

/* ID选择器 */
#header {
    background-color: #2c3e50;
    color: white;
    padding: 20px;
}

/* 后代选择器 */
nav ul li {
    list-style: none;
    display: inline-block;
}

/* 伪类选择器 */
a:hover {
    color: #e74c3c;
    text-decoration: underline;
}

/* 属性选择器 */
input[type="text"] {
    border: 1px solid #ccc;
    padding: 8px;
}

2.2 盒模型与布局

CSS盒模型是理解布局的基础,包括内容(content)、内边距(padding)、边框(border)和外边距(margin)。

盒模型示例:

.box {
    width: 200px;
    height: 100px;
    padding: 20px;
    border: 2px solid #333;
    margin: 30px;
    background-color: #f0f0f0;
    /* 标准盒模型:width只包含内容宽度 */
    box-sizing: content-box; /* 默认值 */
    /* 总宽度 = 200 + 20*2 + 2*2 + 30*2 = 284px */
}

.box-border-box {
    /* 怪异盒模型:width包含内容、padding和border */
    box-sizing: border-box;
    width: 200px; /* 总宽度就是200px */
}

Flexbox布局(弹性盒子):

.container {
    display: flex;
    justify-content: space-between; /* 主轴对齐 */
    align-items: center; /* 交叉轴对齐 */
    flex-wrap: wrap; /* 允许换行 */
    gap: 20px; /* 元素间距 */
}

.item {
    flex: 1; /* 等分空间 */
    min-width: 150px;
    background-color: #3498db;
    padding: 20px;
    color: white;
    text-align: center;
}

Grid布局(网格布局):

.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 3列,等宽 */
    grid-template-rows: auto;
    gap: 15px;
    padding: 20px;
}

.grid-item {
    background-color: #2ecc71;
    padding: 30px;
    text-align: center;
    color: white;
}

/* 响应式网格 */
@media (max-width: 768px) {
    .grid-container {
        grid-template-columns: 1fr; /* 移动端单列 */
    }
}

2.3 CSS3动画与过渡

CSS3提供了强大的动画和过渡效果。

过渡效果示例:

.button {
    background-color: #3498db;
    color: white;
    padding: 12px 24px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s ease; /* 所有属性过渡,0.3秒,缓动函数 */
}

.button:hover {
    background-color: #2980b9;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

关键帧动画示例:

/* 定义动画 */
@keyframes slideIn {
    0% {
        transform: translateX(-100%);
        opacity: 0;
    }
    100% {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.1);
    }
}

/* 应用动画 */
.animated-box {
    width: 200px;
    height: 100px;
    background-color: #e74c3c;
    margin: 20px;
    animation: slideIn 1s ease-out, pulse 2s infinite 1s;
    /* 第一个动画:slideIn,持续1秒,缓动函数ease-out */
    /* 第二个动画:pulse,持续2秒,无限循环,延迟1秒开始 */
}

第三部分:JavaScript交互编程

3.1 JavaScript基础语法

JavaScript是前端开发的核心语言,用于实现页面交互。

变量与数据类型:

// 变量声明
let name = "张三"; // 块级作用域
const age = 25; // 常量,不可重新赋值
var oldVar = "旧变量"; // 函数作用域(不推荐使用)

// 数据类型
const str = "字符串";
const num = 42;
const bool = true;
const obj = { key: "value" };
const arr = [1, 2, 3];
const nullValue = null;
const undefinedValue = undefined;

// 模板字符串
const message = `你好,${name}!今年${age}岁。`;
console.log(message); // 你好,张三!今年25岁。

函数与箭头函数:

// 传统函数
function greet(name) {
    return `你好,${name}!`;
}

// 箭头函数
const greetArrow = (name) => `你好,${name}!`;

// 高阶函数
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(num => num % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15

3.2 DOM操作与事件处理

DOM(文档对象模型)是JavaScript操作HTML页面的接口。

DOM查询与修改:

// 获取元素
const header = document.getElementById('header');
const paragraphs = document.getElementsByTagName('p');
const items = document.querySelectorAll('.item');

// 修改内容
header.textContent = "新的标题";
header.innerHTML = "<strong>加粗的标题</strong>";

// 修改样式
header.style.color = "red";
header.style.backgroundColor = "#f0f0f0";
header.style.padding = "20px";

// 添加/删除类
header.classList.add('active');
header.classList.remove('inactive');
header.classList.toggle('highlight');

// 创建和添加元素
const newDiv = document.createElement('div');
newDiv.textContent = "新创建的div";
newDiv.className = "new-element";
document.body.appendChild(newDiv);

事件处理:

// 事件监听器
const button = document.getElementById('myButton');

// 点击事件
button.addEventListener('click', function(event) {
    console.log('按钮被点击了!');
    console.log('事件对象:', event);
});

// 鼠标事件
button.addEventListener('mouseenter', function() {
    this.style.backgroundColor = '#2ecc71';
});

button.addEventListener('mouseleave', function() {
    this.style.backgroundColor = '#3498db';
});

// 表单事件
const input = document.getElementById('username');
input.addEventListener('input', function(event) {
    console.log('当前输入值:', event.target.value);
});

// 键盘事件
document.addEventListener('keydown', function(event) {
    if (event.key === 'Enter') {
        console.log('回车键被按下');
    }
});

// 事件委托(高效处理动态元素)
document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
        console.log('点击了列表项:', event.target.textContent);
    }
});

3.3 异步编程与AJAX

现代Web应用离不开异步操作和数据请求。

Promise与async/await:

// Promise示例
function fetchData(url) {
    return new Promise((resolve, reject) => {
        fetch(url)
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络响应不正常');
                }
                return response.json();
            })
            .then(data => resolve(data))
            .catch(error => reject(error));
    });
}

// 使用async/await
async function getUserData() {
    try {
        const response = await fetch('https://api.example.com/users');
        const users = await response.json();
        console.log('用户数据:', users);
        return users;
    } catch (error) {
        console.error('获取数据失败:', error);
        return [];
    }
}

// 并行请求
async function fetchMultipleData() {
    const [users, posts] = await Promise.all([
        fetch('https://api.example.com/users').then(r => r.json()),
        fetch('https://api.example.com/posts').then(r => r.json())
    ]);
    console.log('用户:', users);
    console.log('文章:', posts);
}

AJAX请求示例:

// 使用fetch API
function loadUsers() {
    fetch('https://jsonplaceholder.typicode.com/users')
        .then(response => response.json())
        .then(users => {
            const userList = document.getElementById('user-list');
            userList.innerHTML = ''; // 清空列表
            
            users.forEach(user => {
                const li = document.createElement('li');
                li.textContent = `${user.name} (${user.email})`;
                userList.appendChild(li);
            });
        })
        .catch(error => {
            console.error('加载用户失败:', error);
            document.getElementById('user-list').innerHTML = '<li>加载失败</li>';
        });
}

// 带参数的POST请求
async function createUser(userData) {
    try {
        const response = await fetch('https://api.example.com/users', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(userData)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const newUser = await response.json();
        console.log('创建用户成功:', newUser);
        return newUser;
    } catch (error) {
        console.error('创建用户失败:', error);
        throw error;
    }
}

第四部分:响应式设计与移动端适配

4.1 媒体查询与响应式布局

响应式设计确保网站在不同设备上都能良好显示。

媒体查询示例:

/* 基础样式(移动优先) */
.container {
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
}

/* 平板设备(768px及以上) */
@media (min-width: 768px) {
    .container {
        width: 750px;
        margin: 0 auto;
        padding: 20px;
    }
    
    .sidebar {
        width: 30%;
        float: left;
    }
    
    .main-content {
        width: 70%;
        float: right;
    }
}

/* 桌面设备(1024px及以上) */
@media (min-width: 1024px) {
    .container {
        width: 960px;
        padding: 30px;
    }
    
    .sidebar {
        width: 25%;
    }
    
    .main-content {
        width: 75%;
    }
}

/* 大屏幕设备(1200px及以上) */
@media (min-width: 1200px) {
    .container {
        width: 1140px;
    }
}

响应式图片:

<!-- 使用picture元素 -->
<picture>
    <source media="(min-width: 1024px)" srcset="large.jpg">
    <source media="(min-width: 768px)" srcset="medium.jpg">
    <img src="small.jpg" alt="响应式图片" style="width: 100%;">
</picture>

<!-- 使用srcset属性 -->
<img src="small.jpg" 
     srcset="medium.jpg 1024w, large.jpg 2048w" 
     sizes="(max-width: 1024px) 100vw, 1024px"
     alt="响应式图片">

4.2 移动端交互优化

触摸事件处理:

// 触摸事件
const touchArea = document.getElementById('touch-area');

touchArea.addEventListener('touchstart', function(event) {
    event.preventDefault(); // 防止默认行为
    console.log('触摸开始', event.touches[0].clientX, event.touches[0].clientY);
});

touchArea.addEventListener('touchmove', function(event) {
    event.preventDefault();
    console.log('触摸移动');
});

touchArea.addEventListener('touchend', function(event) {
    console.log('触摸结束');
});

// 防止双击缩放
document.addEventListener('touchstart', function(event) {
    if (event.touches.length > 1) {
        event.preventDefault();
    }
});

// 防止页面滚动
document.body.addEventListener('touchmove', function(event) {
    if (!event.target.closest('.scrollable')) {
        event.preventDefault();
    }
}, { passive: false });

移动端性能优化:

// 使用requestAnimationFrame优化动画
function animate(element) {
    let start = null;
    const duration = 1000;
    
    function step(timestamp) {
        if (!start) start = timestamp;
        const progress = timestamp - start;
        const percentage = Math.min(progress / duration, 1);
        
        // 更新元素位置
        element.style.transform = `translateX(${percentage * 300}px)`;
        
        if (percentage < 1) {
            requestAnimationFrame(step);
        }
    }
    
    requestAnimationFrame(step);
}

// 使用Intersection Observer懒加载
const lazyImages = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            img.removeAttribute('data-src');
            observer.unobserve(img);
        }
    });
});

lazyImages.forEach(img => imageObserver.observe(img));

第五部分:实战项目开发

5.1 项目一:个人博客网站

项目目标: 创建一个响应式的个人博客网站,包含首页、文章列表、文章详情页。

HTML结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的博客</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header class="header">
        <div class="container">
            <h1 class="logo">我的博客</h1>
            <nav class="nav">
                <ul>
                    <li><a href="#home">首页</a></li>
                    <li><a href="#articles">文章</a></li>
                    <li><a href="#about">关于</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <main class="main container">
        <section class="hero">
            <h2>欢迎来到我的博客</h2>
            <p>分享技术与生活</p>
        </section>

        <section class="articles">
            <h3>最新文章</h3>
            <div class="article-list">
                <!-- 文章列表将通过JavaScript动态生成 -->
            </div>
        </section>
    </main>

    <footer class="footer">
        <div class="container">
            <p>&copy; 2023 我的博客</p>
        </div>
    </footer>

    <script src="script.js"></script>
</body>
</html>

CSS样式(style.css):

/* 重置样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.6;
    color: #333;
    background-color: #f9f9f9;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

/* 头部样式 */
.header {
    background-color: #2c3e50;
    color: white;
    padding: 15px 0;
    position: sticky;
    top: 0;
    z-index: 100;
}

.header .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    font-size: 1.5rem;
    font-weight: bold;
}

.nav ul {
    display: flex;
    list-style: none;
    gap: 20px;
}

.nav a {
    color: white;
    text-decoration: none;
    transition: color 0.3s;
}

.nav a:hover {
    color: #3498db;
}

/* 主要内容 */
.main {
    padding: 40px 0;
}

.hero {
    text-align: center;
    padding: 60px 20px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border-radius: 8px;
    margin-bottom: 40px;
}

.hero h2 {
    font-size: 2.5rem;
    margin-bottom: 15px;
}

/* 文章列表 */
.articles h3 {
    margin-bottom: 20px;
    font-size: 1.8rem;
    border-bottom: 2px solid #3498db;
    padding-bottom: 10px;
}

.article-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 25px;
}

.article-card {
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    transition: transform 0.3s, box-shadow 0.3s;
}

.article-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 5px 20px rgba(0,0,0,0.15);
}

.article-card img {
    width: 100%;
    height: 180px;
    object-fit: cover;
}

.article-card-content {
    padding: 20px;
}

.article-card h4 {
    margin-bottom: 10px;
    font-size: 1.2rem;
}

.article-card p {
    color: #666;
    font-size: 0.9rem;
    margin-bottom: 15px;
}

.article-card .meta {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: #999;
}

/* 页脚 */
.footer {
    background-color: #2c3e50;
    color: white;
    text-align: center;
    padding: 20px 0;
    margin-top: 40px;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .header .container {
        flex-direction: column;
        gap: 15px;
    }
    
    .nav ul {
        justify-content: center;
        flex-wrap: wrap;
    }
    
    .hero h2 {
        font-size: 1.8rem;
    }
    
    .article-list {
        grid-template-columns: 1fr;
    }
}

JavaScript功能(script.js):

// 模拟文章数据
const articles = [
    {
        id: 1,
        title: "HTML5新特性详解",
        excerpt: "探索HTML5带来的语义化标签、表单增强和多媒体支持...",
        date: "2023-10-15",
        author: "张三",
        image: "https://via.placeholder.com/400x200?text=HTML5"
    },
    {
        id: 2,
        title: "CSS3动画实战技巧",
        excerpt: "学习如何使用CSS3创建流畅的动画效果...",
        date: "2023-10-10",
        author: "李四",
        image: "https://via.placeholder.com/400x200?text=CSS3"
    },
    {
        id: 3,
        title: "JavaScript异步编程",
        excerpt: "深入理解Promise、async/await和异步编程模式...",
        date: "2023-10-05",
        author: "王五",
        image: "https://via.placeholder.com/400x200?text=JavaScript"
    }
];

// 渲染文章列表
function renderArticles() {
    const articleList = document.querySelector('.article-list');
    
    articles.forEach(article => {
        const articleCard = document.createElement('article');
        articleCard.className = 'article-card';
        articleCard.innerHTML = `
            <img src="${article.image}" alt="${article.title}">
            <div class="article-card-content">
                <h4>${article.title}</h4>
                <p>${article.excerpt}</p>
                <div class="meta">
                    <span>${article.date}</span>
                    <span>${article.author}</span>
                </div>
            </div>
        `;
        
        // 添加点击事件
        articleCard.addEventListener('click', () => {
            showArticleDetail(article);
        });
        
        articleList.appendChild(articleCard);
    });
}

// 显示文章详情
function showArticleDetail(article) {
    // 创建模态框
    const modal = document.createElement('div');
    modal.className = 'modal';
    modal.innerHTML = `
        <div class="modal-content">
            <span class="close">&times;</span>
            <h2>${article.title}</h2>
            <p class="meta">${article.date} | ${article.author}</p>
            <img src="${article.image}" alt="${article.title}" style="width:100%; margin: 20px 0;">
            <p>${article.excerpt}</p>
            <p>这里是文章的完整内容...</p>
        </div>
    `;
    
    document.body.appendChild(modal);
    
    // 关闭模态框
    modal.querySelector('.close').addEventListener('click', () => {
        document.body.removeChild(modal);
    });
    
    modal.addEventListener('click', (e) => {
        if (e.target === modal) {
            document.body.removeChild(modal);
        }
    });
}

// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', () => {
    renderArticles();
    
    // 平滑滚动
    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function(e) {
            e.preventDefault();
            const target = document.querySelector(this.getAttribute('href'));
            if (target) {
                target.scrollIntoView({
                    behavior: 'smooth'
                });
            }
        });
    });
});

5.2 项目二:任务管理器(Todo List)

项目目标: 创建一个功能完整的任务管理器,支持添加、删除、标记完成和筛选任务。

HTML结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>任务管理器</title>
    <link rel="stylesheet" href="todo.css">
</head>
<body>
    <div class="todo-app">
        <header class="app-header">
            <h1>任务管理器</h1>
            <div class="stats">
                <span id="total">总任务:0</span>
                <span id="completed">已完成:0</span>
                <span id="pending">待完成:0</span>
            </div>
        </header>

        <div class="todo-form">
            <input type="text" id="taskInput" placeholder="输入新任务..." autocomplete="off">
            <button id="addBtn">添加任务</button>
        </div>

        <div class="filter-buttons">
            <button class="filter-btn active" data-filter="all">全部</button>
            <button class="filter-btn" data-filter="active">待完成</button>
            <button class="filter-btn" data-filter="completed">已完成</button>
        </div>

        <ul id="taskList" class="task-list">
            <!-- 任务列表将通过JavaScript动态生成 -->
        </ul>
    </div>

    <script src="todo.js"></script>
</body>
</html>

CSS样式(todo.css):

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
}

.todo-app {
    background: white;
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
    width: 100%;
    max-width: 500px;
    overflow: hidden;
}

.app-header {
    background: #2c3e50;
    color: white;
    padding: 20px;
    text-align: center;
}

.app-header h1 {
    font-size: 1.8rem;
    margin-bottom: 10px;
}

.stats {
    display: flex;
    justify-content: space-around;
    font-size: 0.9rem;
    opacity: 0.9;
}

.todo-form {
    display: flex;
    padding: 20px;
    gap: 10px;
    border-bottom: 1px solid #eee;
}

#taskInput {
    flex: 1;
    padding: 12px 15px;
    border: 2px solid #ddd;
    border-radius: 6px;
    font-size: 1rem;
    transition: border-color 0.3s;
}

#taskInput:focus {
    outline: none;
    border-color: #3498db;
}

#addBtn {
    background: #3498db;
    color: white;
    border: none;
    padding: 12px 20px;
    border-radius: 6px;
    cursor: pointer;
    font-weight: bold;
    transition: background 0.3s;
}

#addBtn:hover {
    background: #2980b9;
}

.filter-buttons {
    display: flex;
    padding: 10px 20px;
    gap: 10px;
    background: #f8f9fa;
}

.filter-btn {
    flex: 1;
    padding: 8px;
    border: 1px solid #ddd;
    background: white;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s;
}

.filter-btn.active {
    background: #3498db;
    color: white;
    border-color: #3498db;
}

.task-list {
    list-style: none;
    max-height: 400px;
    overflow-y: auto;
}

.task-item {
    display: flex;
    align-items: center;
    padding: 15px 20px;
    border-bottom: 1px solid #eee;
    transition: background 0.2s;
}

.task-item:hover {
    background: #f8f9fa;
}

.task-item.completed {
    opacity: 0.6;
}

.task-checkbox {
    margin-right: 15px;
    width: 20px;
    height: 20px;
    cursor: pointer;
}

.task-text {
    flex: 1;
    font-size: 1rem;
    word-break: break-word;
}

.task-item.completed .task-text {
    text-decoration: line-through;
    color: #999;
}

.task-delete {
    background: #e74c3c;
    color: white;
    border: none;
    padding: 6px 12px;
    border-radius: 4px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.3s;
}

.task-item:hover .task-delete {
    opacity: 1;
}

.task-delete:hover {
    background: #c0392b;
}

/* 空状态 */
.empty-state {
    text-align: center;
    padding: 40px 20px;
    color: #999;
}

.empty-state p {
    margin-top: 10px;
}

/* 动画效果 */
@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.task-item {
    animation: slideIn 0.3s ease-out;
}

/* 响应式设计 */
@media (max-width: 480px) {
    .todo-app {
        border-radius: 0;
        height: 100vh;
        max-width: none;
    }
    
    .filter-buttons {
        flex-wrap: wrap;
    }
    
    .filter-btn {
        flex: 0 0 calc(50% - 5px);
    }
}

JavaScript功能(todo.js):

class TodoManager {
    constructor() {
        this.tasks = JSON.parse(localStorage.getItem('tasks')) || [];
        this.currentFilter = 'all';
        this.init();
    }

    init() {
        this.bindEvents();
        this.render();
        this.updateStats();
    }

    bindEvents() {
        // 添加任务
        const addBtn = document.getElementById('addBtn');
        const taskInput = document.getElementById('taskInput');
        
        addBtn.addEventListener('click', () => this.addTask());
        taskInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') this.addTask();
        });

        // 筛选按钮
        document.querySelectorAll('.filter-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
                e.target.classList.add('active');
                this.currentFilter = e.target.dataset.filter;
                this.render();
            });
        });
    }

    addTask() {
        const input = document.getElementById('taskInput');
        const text = input.value.trim();
        
        if (!text) {
            alert('请输入任务内容!');
            return;
        }

        const task = {
            id: Date.now(),
            text: text,
            completed: false,
            createdAt: new Date().toISOString()
        };

        this.tasks.push(task);
        this.saveToStorage();
        this.render();
        this.updateStats();
        
        input.value = '';
        input.focus();
    }

    deleteTask(id) {
        this.tasks = this.tasks.filter(task => task.id !== id);
        this.saveToStorage();
        this.render();
        this.updateStats();
    }

    toggleTask(id) {
        const task = this.tasks.find(task => task.id === id);
        if (task) {
            task.completed = !task.completed;
            this.saveToStorage();
            this.render();
            this.updateStats();
        }
    }

    getFilteredTasks() {
        switch (this.currentFilter) {
            case 'active':
                return this.tasks.filter(task => !task.completed);
            case 'completed':
                return this.tasks.filter(task => task.completed);
            default:
                return this.tasks;
        }
    }

    render() {
        const taskList = document.getElementById('taskList');
        const filteredTasks = this.getFilteredTasks();

        if (filteredTasks.length === 0) {
            taskList.innerHTML = `
                <li class="empty-state">
                    <p>暂无任务</p>
                    <p>添加一个新任务开始吧!</p>
                </li>
            `;
            return;
        }

        taskList.innerHTML = filteredTasks.map(task => `
            <li class="task-item ${task.completed ? 'completed' : ''}" data-id="${task.id}">
                <input type="checkbox" class="task-checkbox" 
                    ${task.completed ? 'checked' : ''} 
                    onchange="todoManager.toggleTask(${task.id})">
                <span class="task-text">${this.escapeHtml(task.text)}</span>
                <button class="task-delete" onclick="todoManager.deleteTask(${task.id})">删除</button>
            </li>
        `).join('');
    }

    updateStats() {
        const total = this.tasks.length;
        const completed = this.tasks.filter(task => task.completed).length;
        const pending = total - completed;

        document.getElementById('total').textContent = `总任务:${total}`;
        document.getElementById('completed').textContent = `已完成:${completed}`;
        document.getElementById('pending').textContent = `待完成:${pending}`;
    }

    saveToStorage() {
        localStorage.setItem('tasks', JSON.stringify(this.tasks));
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
}

// 初始化应用
const todoManager = new TodoManager();

第六部分:进阶学习与资源推荐

6.1 前端框架入门

Vue.js基础示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue.js示例</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <style>
        .app {
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
            font-family: Arial, sans-serif;
        }
        .todo-input {
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        .todo-item {
            padding: 10px;
            border-bottom: 1px solid #eee;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .completed {
            text-decoration: line-through;
            color: #999;
        }
        .btn {
            padding: 5px 10px;
            background: #e74c3c;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="app" class="app">
        <h2>Vue.js Todo List</h2>
        <input 
            type="text" 
            class="todo-input" 
            v-model="newTodo" 
            @keyup.enter="addTodo"
            placeholder="添加新任务..."
        >
        <div v-for="todo in todos" :key="todo.id" class="todo-item">
            <span :class="{ completed: todo.completed }" @click="toggleTodo(todo)">
                {{ todo.text }}
            </span>
            <button class="btn" @click="removeTodo(todo)">删除</button>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                newTodo: '',
                todos: [
                    { id: 1, text: '学习Vue.js', completed: false },
                    { id: 2, text: '完成项目', completed: true }
                ]
            },
            methods: {
                addTodo() {
                    if (this.newTodo.trim()) {
                        this.todos.push({
                            id: Date.now(),
                            text: this.newTodo,
                            completed: false
                        });
                        this.newTodo = '';
                    }
                },
                removeTodo(todo) {
                    this.todos = this.todos.filter(t => t.id !== todo.id);
                },
                toggleTodo(todo) {
                    todo.completed = !todo.completed;
                }
            }
        });
    </script>
</body>
</html>

6.2 学习资源推荐

在线学习平台:

  1. MDN Web Docs - 最权威的Web技术文档
  2. freeCodeCamp - 免费的交互式编程课程
  3. Codecademy - 交互式编程学习平台
  4. W3Schools - 简明的Web技术教程

视频教程:

  1. YouTube频道:Traversy Media、The Net Ninja、Academind
  2. B站中文教程:黑马程序员、尚硅谷、慕课网

书籍推荐:

  1. 《JavaScript高级程序设计》(第4版)
  2. 《CSS世界》
  3. 《深入浅出Vue.js》
  4. 《你不知道的JavaScript》系列

实战项目资源:

  1. GitHub:搜索”HTML5 project”、”frontend project”
  2. CodePen:查看和学习前端创意作品
  3. Frontend Mentor:提供设计稿的实战项目

6.3 开发工具与调试技巧

浏览器开发者工具:

  • Elements:检查和修改DOM元素
  • Console:执行JavaScript代码和查看日志
  • Network:监控网络请求
  • Performance:分析页面性能
  • Lighthouse:评估页面质量

VS Code插件推荐:

  1. Live Server - 实时预览
  2. Prettier - 代码格式化
  3. ESLint - 代码检查
  4. Auto Rename Tag - 自动重命名标签
  5. CSS Peek - CSS跳转

性能优化技巧:

  1. 图片优化:使用WebP格式,懒加载
  2. 代码压缩:使用Webpack、Vite等工具
  3. 缓存策略:合理使用浏览器缓存
  4. 减少HTTP请求:合并文件,使用CDN

结语

通过本攻略的学习,你已经从HTML5的基础知识开始,逐步掌握了CSS样式设计、JavaScript交互编程、响应式设计等核心技能,并通过两个实战项目巩固了所学知识。前端开发是一个持续学习的领域,新技术和新工具层出不穷。

下一步建议:

  1. 深入学习JavaScript:掌握ES6+特性,理解原型链、闭包、异步编程
  2. 学习前端框架:选择一个主流框架(React、Vue、Angular)深入学习
  3. 构建工具:学习Webpack、Vite等现代构建工具
  4. 版本控制:熟练使用Git和GitHub
  5. 持续实践:参与开源项目,构建个人作品集

记住,编程是一门实践的艺术。多写代码,多做项目,多思考问题,你一定能成为一名优秀的前端开发者!

祝你学习顺利,编程愉快!