手把手教你用HTML+CSS+JS仿写小米商城官网

📅 2026/8/20 13:35:05
手把手教你用HTML+CSS+JS仿写小米商城官网
最近在辅导学生完成期末大作业时发现很多同学对“仿写一个知名电商网站”这个题目感到无从下手。面对复杂的页面布局、交互效果和代码组织常常是东拼西凑最终效果不尽如人意。其实这类项目是系统练习前端三件套HTML、CSS、JavaScript的绝佳机会。本文将以“仿写小米商城官网”为例手把手带你从零开始一步步搭建一个结构清晰、样式美观、具备基础交互功能的静态页面。整个过程不仅会详细讲解核心代码还会分享如何组织项目结构、如何调试CSS布局、如何实现常见的JS交互。文末会提供完整的源码和课件你可以直接下载使用也可以跟随教程一步步敲出来彻底掌握从设计稿到可运行网页的全过程。无论你是为了完成期末作业、课程设计还是想夯实前端基础这篇教程都能给你一个清晰的路径。1. 项目概述与核心目标在开始写代码之前我们需要明确这个项目要做什么以及通过这个项目我们能学到什么。盲目地开始复制粘贴往往事倍功半。1.1 项目功能拆解我们要仿写的是小米商城官网的核心页面通常是首页。一个典型的电商首页包含以下模块顶部导航栏包含Logo、主导航菜单手机、电视、笔记本等、搜索框、用户登录/购物车入口。轮播图Banner展示核心促销活动或主打产品能够自动或手动切换。产品分类展示区以网格或列表形式展示不同品类的热门商品通常包含图片、名称、价格和简短描述。页脚Footer包含网站链接、版权信息、联系方式等。我们的目标是使用纯前端技术HTMLCSSJS实现一个静态版本重点在于视觉还原和基础交互不涉及后端数据交互和复杂的购物流程。1.2 技术栈与学习目标HTML5构建页面的语义化结构。学习如何使用header,nav,section,footer等语义化标签而不是满屏的div。CSS3布局深入理解 Flexbox 和 Grid 布局这是实现现代网页响应式排版的核心。样式掌握盒模型、定位position、过渡transition、动画animation等。响应式使用媒体查询media让页面在不同宽度的设备上都能良好显示。JavaScript (ES6)DOM 操作学习如何选取元素、修改内容/样式、监听事件。基础交互实现轮播图切换、导航栏hover效果、返回顶部按钮等。工程化思维学习如何组织项目文件结构将HTML、CSS、JS分离提高代码的可维护性。2. 环境准备与项目结构搭建工欲善其事必先利其器。我们不需要复杂的开发环境一个浏览器和一个代码编辑器就足够了。2.1 开发工具准备代码编辑器推荐使用Visual Studio Code (VSCode)。它轻量、免费并且拥有强大的前端插件生态如 Live Server, Prettier, Auto Rename Tag 等。浏览器推荐Google Chrome或Microsoft Edge。它们的开发者工具F12打开是调试HTML、CSS和JS的利器。浏览器插件可以安装“Pesticide”或“CSS Peeper”这类插件方便查看页面元素的盒模型。2.2 创建项目文件夹与文件在你的工作目录下创建一个名为mi-store-demo的文件夹并在其中创建如下结构的文件mi-store-demo/ ├── index.html # 主页面文件 ├── css/ │ └── style.css # 样式文件 ├── js/ │ └── main.js # JavaScript 交互文件 ├── images/ # 存放所有图片资源如logo、产品图、轮播图 └── README.md # 项目说明文档可选将你准备好的图片素材如小米Logo、轮播图、产品图放入images文件夹。如果暂时没有素材可以先使用占位图如 placeholder.com 生成的图片链接替代后期再替换。3. HTML 结构搭建构建页面的骨架我们从index.html开始构建一个语义清晰、结构完整的页面骨架。3.1 基础文档结构与元信息首先使用!或html:5快捷键在VSCode中生成HTML5基础模板。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title小米商城 - 仿写练习/title link relstylesheet hrefcss/style.css link relicon hrefimages/favicon.ico typeimage/x-icon !-- 可选引入图标字体库如 Font Awesome -- !-- link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css -- /head body !-- 页面内容将在这里编写 -- script srcjs/main.js/script /body /html关键点解释meta nameviewport...这个标签对于移动端适配至关重要它告诉浏览器按照设备的宽度来渲染页面并禁止初始缩放。link relstylesheet hrefcss/style.css引入我们外部的CSS文件。script srcjs/main.js/script通常将JS文件放在/body标签之前引入这样可以确保HTML DOM加载完毕后再执行JS避免找不到元素的错误。3.2 构建主体模块结构接下来在body标签内我们用语义化标签搭建主要模块。body !-- 1. 顶部导航栏 -- header classsite-header div classcontainer !-- Logo -- a href# classlogo img srcimages/mi-logo.png alt小米商城 /a !-- 主导航 -- nav classmain-nav ul lia href#小米手机/a/li lia href#Redmi 红米/a/li lia href#电视/a/li lia href#笔记本/a/li lia href#家电/a/li lia href#路由器/a/li lia href#服务/a/li lia href#社区/a/li /ul /nav !-- 右侧工具区搜索、用户、购物车 -- div classheader-tools div classsearch-box input typetext placeholder搜索商品 buttoni classfas fa-search/i/button /div a href# classuser-link登录/a a href# classcart-link购物车(0)/a /div /div /header !-- 2. 主内容区 -- main !-- 轮播图区域 -- section classbanner div classslides-container div classslide activeimg srcimages/banner1.jpg alt促销活动1/div div classslideimg srcimages/banner2.jpg alt促销活动2/div div classslideimg srcimages/banner3.jpg alt促销活动3/div /div !-- 轮播图指示器小圆点 -- div classslide-indicators span classindicator active/span span classindicator/span span classindicator/span /div !-- 轮播图左右箭头 -- button classslide-btn prev-btn‹/button button classslide-btn next-btn›/button /section !-- 产品展示区域 -- section classproduct-showcase div classcontainer h2热门推荐/h2 div classproduct-grid !-- 产品卡片1 -- div classproduct-card img srcimages/product1.jpg alt小米13 h3小米13/h3 p classdesc徕卡光学镜头 | 第二代骁龙8/p p classprice¥3999起/p /div !-- 产品卡片2 ... 重复多个 -- div classproduct-card img srcimages/product2.jpg altRedmi K60 h3Redmi K60/h3 p classdesc2K高光屏 | 骁龙8/p p classprice¥2499起/p /div !-- 可以继续添加更多产品卡片 -- /div /div /section /main !-- 3. 页脚 -- footer classsite-footer div classcontainer div classfooter-links div classlink-column h4帮助中心/h4 a href#账户管理/a a href#购物指南/a a href#订单操作/a /div div classlink-column h4服务支持/h4 a href#售后政策/a a href#自助服务/a a href#相关下载/a /div !-- 更多链接列 -- /div div classfooter-copyright p© mi.com 京ICP证110507号 京ICP备10046444号 京公网安备11010802020134号 京网文[2020]0276-042号/p p本页面为前端学习仿写项目非官方页面。/p /div /div /footer !-- 返回顶部按钮 -- button idbackToTop classback-to-top↑/button script srcjs/main.js/script /body /html现在页面的骨架已经搭建完毕。在浏览器中打开这个HTML文件你会看到一个只有文字和原始图片堆叠的页面没有任何样式。接下来就是CSS大显身手的时候了。4. CSS 样式设计为骨架注入灵魂我们将逐步编写css/style.css文件为每个模块添加样式。我们将采用移动端优先的响应式设计思路。4.1 全局样式重置与基础设置首先清除不同浏览器的默认样式并设置一些全局变量和基础样式。/* css/style.css */ /* 1. 全局重置与盒模型 */ * { margin: 0; padding: 0; box-sizing: border-box; /* 重要让元素的宽度和高度包含内边距和边框 */ } html { scroll-behavior: smooth; /* 让锚点滚动更平滑 */ } body { font-family: Helvetica Neue, Helvetica, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; line-height: 1.6; color: #333; background-color: #fff; } a { text-decoration: none; color: inherit; /* 继承父元素颜色 */ } ul, ol { list-style: none; } img { max-width: 100%; /* 图片自适应容器宽度 */ height: auto; display: block; } /* 2. 通用容器类用于限制内容宽度并居中 */ .container { width: 100%; max-width: 1226px; /* 参考小米官网的宽度 */ margin: 0 auto; padding: 0 15px; /* 在移动端留出左右边距 */ } /* 3. 工具类 */ .text-center { text-align: center; } .d-flex { display: flex; } .justify-between { justify-content: space-between; } .align-center { align-items: center; }4.2 顶部导航栏样式导航栏是页面的门面我们使用 Flexbox 来实现水平布局。/* 4. 顶部导航栏样式 */ .site-header { background-color: #333; color: #b0b0b0; font-size: 14px; height: 40px; line-height: 40px; } .site-header .container { display: flex; justify-content: space-between; align-items: center; height: 100%; } /* Logo */ .logo img { height: 40px; /* 控制Logo高度 */ width: auto; } /* 主导航菜单 */ .main-nav ul { display: flex; gap: 20px; /* 菜单项之间的间距 */ } .main-nav a { padding: 0 10px; display: block; transition: color 0.3s; } .main-nav a:hover { color: #fff; } /* 搜索框 */ .search-box { display: flex; align-items: center; background: #fff; border-radius: 4px; overflow: hidden; height: 28px; } .search-box input { border: none; padding: 0 10px; width: 180px; height: 100%; outline: none; font-size: 12px; } .search-box button { border: none; background: #ff6700; /* 小米主题色 */ color: white; height: 100%; padding: 0 12px; cursor: pointer; } /* 用户与购物车链接 */ .header-tools { display: flex; align-items: center; gap: 20px; } .user-link, .cart-link { transition: color 0.3s; } .user-link:hover, .cart-link:hover { color: #ff6700; }4.3 轮播图区域样式轮播图是首页的视觉焦点我们需要使用绝对定位和 Flexbox 来控制图片和按钮。/* 5. 轮播图样式 */ .banner { position: relative; overflow: hidden; /* 隐藏超出容器的部分 */ height: 460px; /* 固定一个高度可根据图片调整 */ background-color: #f5f5f5; } .slides-container { display: flex; height: 100%; transition: transform 0.5s ease-in-out; /* 为滑动切换添加过渡效果 */ } .slide { min-width: 100%; /* 确保每张幻灯片占满容器宽度 */ height: 100%; flex-shrink: 0; /* 防止图片被压缩 */ } .slide img { width: 100%; height: 100%; object-fit: cover; /* 让图片覆盖整个区域可能会裁剪 */ } /* 轮播图指示器小圆点 */ .slide-indicators { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; } .indicator { width: 10px; height: 10px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.5); cursor: pointer; transition: background-color 0.3s; } .indicator.active { background-color: #ff6700; /* 激活状态为小米橙 */ } /* 轮播图左右箭头 */ .slide-btn { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 70px; background-color: rgba(0, 0, 0, 0.2); color: white; border: none; font-size: 24px; cursor: pointer; transition: background-color 0.3s; } .slide-btn:hover { background-color: rgba(0, 0, 0, 0.5); } .prev-btn { left: 0; border-radius: 0 4px 4px 0; } .next-btn { right: 0; border-radius: 4px 0 0 4px; }4.4 产品展示区样式这里我们使用 CSS Grid 布局来创建灵活的产品卡片网格。/* 6. 产品展示区样式 */ .product-showcase { padding: 40px 0; background-color: #f5f5f5; } .product-showcase h2 { text-align: center; margin-bottom: 30px; font-size: 28px; color: #333; } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* 关键自动填充最小250px */ gap: 20px; } .product-card { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); transition: transform 0.3s, box-shadow 0.3s; text-align: center; padding-bottom: 20px; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); } .product-card img { width: 100%; height: 200px; object-fit: cover; margin-bottom: 15px; } .product-card h3 { font-size: 18px; margin-bottom: 8px; color: #333; } .product-card .desc { font-size: 14px; color: #757575; margin-bottom: 12px; padding: 0 10px; } .product-card .price { font-size: 20px; color: #ff6700; font-weight: bold; }4.5 页脚与返回顶部按钮样式/* 7. 页脚样式 */ .site-footer { background-color: #333; color: #b0b0b0; padding: 40px 0 20px; font-size: 14px; } .footer-links { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 30px; margin-bottom: 30px; } .link-column h4 { color: #fff; margin-bottom: 15px; font-size: 16px; } .link-column a { display: block; margin-bottom: 8px; transition: color 0.3s; } .link-column a:hover { color: #ff6700; } .footer-copyright { text-align: center; padding-top: 20px; border-top: 1px solid #424242; font-size: 12px; color: #999; } /* 8. 返回顶部按钮 */ .back-to-top { position: fixed; bottom: 40px; right: 40px; width: 50px; height: 50px; border-radius: 50%; background-color: #ff6700; color: white; border: none; font-size: 20px; cursor: pointer; opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; z-index: 1000; } .back-to-top.show { opacity: 1; visibility: visible; } .back-to-top:hover { background-color: #e65c00; }4.6 响应式设计媒体查询最后我们添加媒体查询让页面在手机等小屏幕设备上也能良好显示。/* 9. 响应式设计 */ /* 平板设备 (宽度小于 992px) */ media (max-width: 991px) { .main-nav { display: none; /* 在小屏幕上隐藏复杂导航可以替换为汉堡菜单 */ } .search-box input { width: 140px; } .banner { height: 300px; } } /* 手机设备 (宽度小于 768px) */ media (max-width: 767px) { .site-header { height: auto; padding: 10px 0; } .site-header .container { flex-direction: column; gap: 15px; } .header-tools { width: 100%; justify-content: space-around; } .search-box { flex-grow: 1; max-width: 200px; } .banner { height: 200px; } .product-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } .footer-links { grid-template-columns: 1fr; /* 单列显示 */ } .back-to-top { bottom: 20px; right: 20px; width: 40px; height: 40px; font-size: 16px; } }至此页面的静态样式已经全部完成。刷新浏览器你应该能看到一个结构清晰、样式美观的小米商城首页了。不过它还缺少灵魂——交互功能。接下来我们用 JavaScript 来实现它。5. JavaScript 交互实现让页面活起来我们将编写js/main.js文件为轮播图和返回顶部按钮添加交互逻辑。5.1 轮播图功能实现轮播图的核心逻辑是每隔一段时间自动切换到下一张图片同时可以通过指示器或左右按钮手动切换。// js/main.js // 等待整个页面的DOM加载完毕 document.addEventListener(DOMContentLoaded, function() { // 1. 轮播图功能 const slideContainer document.querySelector(.slides-container); const slides document.querySelectorAll(.slide); const indicators document.querySelectorAll(.indicator); const prevBtn document.querySelector(.prev-btn); const nextBtn document.querySelector(.next-btn); let currentIndex 0; // 当前显示的幻灯片索引 const totalSlides slides.length; let slideInterval; // 用于存储自动轮播的定时器 // 函数切换到指定索引的幻灯片 function goToSlide(index) { // 确保索引在有效范围内循环 if (index totalSlides) { currentIndex 0; } else if (index 0) { currentIndex totalSlides - 1; } else { currentIndex index; } // 移动 slides-container const offset -currentIndex * 100; // 计算需要移动的百分比 slideContainer.style.transform translateX(${offset}%); // 更新指示器状态 indicators.forEach((indicator, idx) { if (idx currentIndex) { indicator.classList.add(active); } else { indicator.classList.remove(active); } }); } // 函数切换到下一张 function nextSlide() { goToSlide(currentIndex 1); } // 函数切换到上一张 function prevSlide() { goToSlide(currentIndex - 1); } // 启动自动轮播 function startAutoSlide() { slideInterval setInterval(nextSlide, 3000); // 每3秒切换一次 } // 停止自动轮播当用户手动交互时 function stopAutoSlide() { clearInterval(slideInterval); } // 事件监听 nextBtn.addEventListener(click, () { nextSlide(); stopAutoSlide(); // 手动点击后暂停自动轮播可以稍后重启 startAutoSlide(); }); prevBtn.addEventListener(click, () { prevSlide(); stopAutoSlide(); startAutoSlide(); }); // 为每个指示器添加点击事件 indicators.forEach((indicator, index) { indicator.addEventListener(click, () { goToSlide(index); stopAutoSlide(); startAutoSlide(); }); }); // 鼠标悬停在轮播图上时暂停自动轮播 const bannerSection document.querySelector(.banner); bannerSection.addEventListener(mouseenter, stopAutoSlide); bannerSection.addEventListener(mouseleave, startAutoSlide); // 初始化开始自动轮播 startAutoSlide(); // 2. 返回顶部按钮功能 const backToTopBtn document.getElementById(backToTop); // 监听页面滚动事件 window.addEventListener(scroll, function() { // 当页面垂直滚动超过 300 像素时显示按钮 if (window.pageYOffset 300) { backToTopBtn.classList.add(show); } else { backToTopBtn.classList.remove(show); } }); // 点击按钮平滑滚动到顶部 backToTopBtn.addEventListener(click, function() { window.scrollTo({ top: 0, behavior: smooth // 平滑滚动 }); }); // 3. 其他交互示例导航菜单悬停效果CSS已实现此处可扩展 // 例如可以在这里添加更复杂的下拉菜单JS逻辑 // console.log(页面交互已加载); });代码关键点解释DOMContentLoaded事件确保脚本在HTML文档完全加载和解析之后执行避免操作不存在的DOM元素。轮播图原理通过改变slides-container的transform: translateX()属性来实现水平滑动。所有幻灯片横向排列容器宽度为100%每张幻灯片宽度也为100%。切换时移动整个容器。自动轮播与手动控制使用setInterval实现自动播放。当用户点击按钮或指示器时先清除之前的定时器停止自动播放执行手动切换然后重新启动自动播放。这提供了更好的用户体验。返回顶部监听window的scroll事件根据滚动距离控制按钮的显示/隐藏。点击时使用window.scrollTo并设置behavior: smooth实现平滑滚动。现在保存所有文件并刷新浏览器。你的轮播图应该可以自动播放并且可以通过左右箭头和底部小圆点控制。滚动页面当超过一定距离时右下角会出现返回顶部按钮点击可以平滑回到顶部。6. 项目优化与扩展建议一个基础版本已经完成但要让项目更完善、更像一个“作业”或“作品”可以考虑以下优化方向6.1 代码优化CSS 优化将颜色值如#ff6700,#333定义为CSS变量Custom Properties方便统一管理和更换主题。:root { --primary-color: #ff6700; --bg-dark: #333; --text-light: #b0b0b0; } .site-header { background-color: var(--bg-dark); }考虑使用 CSS 预处理器如 Sass/Less来编写更结构化、可维护的样式。JavaScript 优化将轮播图功能封装成一个可复用的类Class提高代码的模块化程度。考虑使用事件委托来管理指示器的点击事件减少事件监听器的数量。6.2 功能扩展响应式导航菜单在移动端max-width: 991px将主导航隐藏替换为一个“汉堡包”菜单按钮点击后以侧边栏或下拉形式显示菜单。图片懒加载对于产品列表等可能有很多图片的区域可以使用loadinglazy属性或Intersection Observer API实现图片懒加载提升页面初始加载速度。购物车数量模拟在JS中模拟一个简单的购物车点击“加入购物车”按钮需要在产品卡片上添加时更新顶部购物车图标旁的数量显示。搜索提示为搜索框添加一个简单的关键词提示列表可以从固定数组获取数据。6.3 部署与分享使用 GitHub Pages 免费部署将你的代码推送到GitHub仓库开启GitHub Pages功能就能获得一个免费的在线访问链接方便展示你的作业。代码压缩与打包在项目最终提交前可以使用工具如 Vite, Webpack 的简单配置或在线工具对HTML、CSS、JS文件进行压缩移除空格、注释减少文件体积。7. 常见问题与排查 (FAQ)在开发过程中你可能会遇到以下问题问题现象可能原因解决方案页面布局混乱元素堆叠或错位1. CSS盒模型问题未设置box-sizing: border-box。2. Flexbox或Grid布局属性使用错误。3. 元素宽度计算超出容器。1. 检查全局重置是否包含* { box-sizing: border-box; }。2. 使用浏览器开发者工具的“元素检查”功能查看元素的盒模型和应用的CSS规则逐步调试布局属性。3. 确保图片设置了max-width: 100%。轮播图不滑动或滑动异常1. JS代码未正确获取DOM元素。2.translateX的计算值错误。3. CSS中slides-container的transition属性未设置或错误。1. 打开浏览器控制台F12检查是否有JS报错。2. 在goToSlide函数中添加console.log(currentIndex, offset)调试输出查看计算值是否正确。3. 确认.slides-container的CSS包含了transition: transform 0.5s ease-in-out;。在手机上样式不对1. 缺少meta nameviewport标签。2. 媒体查询media的断点或样式未生效。3. 某些CSS属性在移动端支持度不同。1. 确保HTML头部有viewport元标签。2. 使用浏览器开发者工具的“设备模拟”功能切换到手机尺寸查看样式并检查媒体查询中的CSS是否被正确应用。3. 使用更兼容的CSS属性避免使用实验性特性。返回顶部按钮不出现1. JS中监听滚动事件的阈值300px不合适。2. 按钮的初始样式opacity: 0; visibility: hidden;未被JS覆盖。3.window.pageYOffset获取值有误。1. 调整window.pageYOffset 300中的数值。2. 检查JS是否成功为按钮添加了.show类。3. 在滚动事件处理函数中添加console.log(window.pageYOffset)查看实际滚动值。图片不显示1. 图片路径错误。2. 图片文件名或扩展名大小写不匹配服务器环境可能区分。3. 图片资源未成功放入images文件夹。1. 检查img标签的src属性路径是否正确。使用相对路径images/xxx.jpg。2. 确保文件名完全一致。3. 在浏览器中直接尝试打开图片链接右键-在新标签页中打开图片看是否能访问。8. 源码与课件获取为了方便大家学习和参考我已经将本项目的完整源代码包含HTML、CSS、JS文件结构、图片占位符和详细的代码注释整理打包。如何获取你可以通过以下方式获取完整的项目文件直接复制本文的代码块按照第2章的文件结构分别创建index.html,css/style.css,js/main.js文件并将对应章节的代码复制进去。使用模拟资源images文件夹内的图片你可以自行准备或使用免费的在线占位图服务如 picsum.photos 在代码中直接替换src为在线图片链接进行测试。项目运行 获取代码后直接用浏览器打开index.html文件即可看到效果。所有交互功能都已内置。通过这个从0到1的项目你不仅完成了一个视觉上过得去的仿站练习更重要的是实践了前端开发的核心工作流结构HTML、表现CSS、行为JS的分离与协作并初步接触了响应式设计和基本的交互逻辑。你可以以此为基础添加更多功能模块如商品详情页、登录模态框或者尝试仿写其他你喜欢的网站。动手实践是学习编程最快的方式希望这个项目能成为你前端学习路上的一块坚实垫脚石。如果在实现过程中遇到任何问题欢迎在评论区交流讨论。