
简介这是一份面向网页设计初学者与K12教学场景的期末作业级前端项目源码以仿小米商城为实战案例帮助学习者把HTML、CSS与JavaScript三件套从零散知识点串联为完整页面。压缩包共1062个文件约33.81MB其中png、jpg、webp、gif等图片资源占主体用于商品图与页面素材21个css文件与16个html页面构成整体布局与视觉样式14个js文件负责轮播、点击交互与数据加载另含字体文件与项目配置结构接近真实站点。已有212人学习下载。读者可借此研究头部、导航、商品展示区与底部的组织方式理解盒模型、Flex布局与响应式设计并参考事件监听、DOM选取等交互实现适合作为课程作业模板、教学案例或前端入门练手素材。1. 仿小米商城项目到底在练什么从一张首页截图到能跑的三件套很多人搜「网页设计期末作业基于Htmlcssjs的仿小米商城项目源代码」心里想的其实是同一件事我手里只有一份作业要求或者只有一张小米商城的首页截图怎么把它变成能交、能演示、还能讲清楚原理的完整项目。这个标题拆开看核心不是「小米商城」四个字而是 Html、css、js 三件套怎么在一个真实电商首页里各司其职。Html 负责结构骨架css 负责视觉还原js 负责交互和动态数据。它适合两类人一类是刚学完基础语法、需要一个大作业把知识串起来的学生另一类是工作里偶尔要写活动页、后台管理页想找个完整案例补一补前端工程感的从业者。我见过太多人卡在第一步打开编辑器新建 index.html然后盯着空白页面发呆。问题不在技术在于没有把「仿」这个字拆成可执行的模块。仿小米商城不是让你复刻它的后端和数据库而是用静态三件套把首页的导航、轮播、商品卡片、购物车角标这些看得见的部分做出来。你真正要练的是布局能力、样式组织能力和 DOM 操作能力。这三样练熟了期末作业能交面试时也能拿出手。下面我按「先立结构、再调样式、后加交互」的顺序把整个项目从零到能演示的路径讲清楚中间会给出可直接抄的代码和参数。2. 先把首页骨架搭对Html 结构决定后面 css 和 js 好不好写2.1 仿小米商城首页的五个必备区块小米商城首页看着复杂拆开其实就五块顶部导航栏、搜索区、轮播图、商品分类侧栏、商品卡片列表。很多人一上来就写 div 套 div写到后面自己都找不到哪个容器对应哪块。我的习惯是先画一张区块图用注释把每个大块标出来再往里填内容。这样后面写 css 时选择器有明确目标写 js 时也能快速定位到要操作的节点。下面是最小可运行的结构直接复制到 index.html 里就能看到骨架!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title仿小米商城/title link relstylesheet hrefcss/style.css /head body !-- 顶部导航 -- header classtop-bar div classcontainer nav classnav-left a href#小米商城/a a href#MIUI/a a href#云服务/a /nav nav classnav-right a href#登录/a a href#注册/a a href# classcart购物车span classbadge0/span/a /nav /div /header !-- 搜索区 -- section classsearch-area div classcontainer div classlogoMi/div div classsearch-box input typetext placeholder搜索商品 button搜索/button /div /div /section !-- 轮播图 -- section classbanner div classcontainer div classcarousel idcarousel img srcimages/banner1.jpg altbanner1 classactive img srcimages/banner2.jpg altbanner2 img srcimages/banner3.jpg altbanner3 button classprev idprevBtn‹/button button classnext idnextBtn›/button div classdots iddots/div /div /div /section !-- 商品列表 -- section classgoods div classcontainer h2热门商品/h2 div classgoods-list idgoodsList/div /div /section script srcjs/main.js/script /body /html这段结构里container是统一的内容宽度容器后面 css 里给它设width: 1226px; margin: 0 auto;这是小米商城实际用的内容宽度也是很多电商页面的常见值。carousel里的三张图默认只显示.active那张其余用 css 隐藏。goodsList留空商品卡片由 js 动态生成这样你改数据不用动 Html。badge是购物车角标初始为 0后面 js 会更新它。提示图片路径先随便放几张本地图尺寸建议 1226×460和轮播容器一致避免拉伸变形。2.2 用语义化标签替代满屏 div 的取舍上面代码里我用了header、section、nav没有全用 div。这不是为了好看而是有实际好处一是代码可读性高你隔一周再看还能找到轮播区在哪二是对搜索引擎和屏幕阅读器友好虽然期末作业不查这个但养成习惯没坏处。不过也别走极端商品卡片内部该用 div 还是用 div因为卡片是重复生成的语义化标签在这里收益不大。常见做法是页面级大块用语义标签组件级小块用 div。你如果拿到的模板全是 div也不用重写只要保证 class 命名清晰就行。class 命名我一般用「区块名-元素名」的格式比如goods-list、search-box避免用box1、left这种改天就忘的名字。2.3 商品卡片的数据结构怎么定商品卡片是 js 动态生成的所以要先定好数据格式。我一般用一个数组每项包含图片、标题、价格、原价、标签四个字段const goodsData [ { img: images/goods1.jpg, title: 小米手机 14, price: 3999, oldPrice: 4299, tag: 新品 }, { img: images/goods2.jpg, title: Redmi Book Pro, price: 4999, oldPrice: 5499, tag: 热销 }, { img: images/goods3.jpg, title: 小米手环 9, price: 249, oldPrice: 299, tag: 优惠 }, { img: images/goods4.jpg, title: 小米平板 6, price: 1899, oldPrice: 2099, tag: } ];字段含义img是图片路径title是商品名price是现价oldPrice是划线价tag是角标文字没有就留空。这个结构后面渲染和排序都用得上。你如果想让作业更出彩可以再加一个sales字段表示销量后面做「按销量排序」的交互。3. css 还原小米商城视觉布局、配色和那几个容易翻车的细节3.1 用 Flex 布局把导航和搜索区一次写对小米商城的顶部导航是左右分栏搜索区是 logo 加搜索框横向排列。这两个用 Flex 是最省事的。下面是我实际用的样式片段/* 通用容器 */ .container { width: 1226px; margin: 0 auto; } /* 顶部导航 */ .top-bar { height: 40px; line-height: 40px; background: #333; color: #b0b0b0; font-size: 12px; } .top-bar .container { display: flex; justify-content: space-between; } .top-bar a { color: #b0b0b0; text-decoration: none; margin: 0 8px; } .top-bar a:hover { color: #fff; } /* 搜索区 */ .search-area { padding: 20px 0; } .search-area .container { display: flex; align-items: center; } .logo { width: 55px; height: 55px; background: #ff6700; color: #fff; font-size: 24px; font-weight: bold; display: flex; align-items: center; justify-content: center; margin-right: 40px; } .search-box { display: flex; border: 1px solid #e0e0e0; } .search-box input { width: 240px; height: 50px; border: none; padding: 0 15px; outline: none; } .search-box button { width: 60px; height: 50px; border: none; background: #ff6700; color: #fff; cursor: pointer; }这里的关键参数container宽度 1226px 是小米商城的内容区宽度你如果做响应式可以改成max-width: 1226px; width: 100%;。导航栏高度 40px、搜索框高度 50px、logo 55×55这些数值照着截图量一下就行不用一模一样但比例要对。#ff6700是小米的标志性橙色直接用在 logo 背景和搜索按钮上整个页面的品牌感就出来了。注意line-height和height设成一样可以让单行文字垂直居中这是老办法但在导航栏这种固定高度场景里比 Flex 更省代码。3.2 轮播图的定位与层级为什么你的按钮总被图片盖住轮播图翻车最多的地方是按钮和圆点被图片盖住或者图片溢出容器。原因是定位和z-index没设对。轮播容器要设position: relative图片绝对定位铺满按钮和圆点设position: absolute并给一个比图片高的z-index。下面是我用的写法.banner { margin-bottom: 20px; } .carousel { position: relative; width: 1226px; height: 460px; overflow: hidden; } .carousel img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s; } .carousel img.active { opacity: 1; } .carousel .prev, .carousel .next { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 60px; background: rgba(0, 0, 0, 0.3); color: #fff; border: none; font-size: 24px; cursor: pointer; z-index: 10; } .carousel .prev { left: 10px; } .carousel .next { right: 10px; } .dots { position: absolute; bottom: 15px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; z-index: 10; } .dots span { width: 10px; height: 10px; border-radius: 50%; background: rgba(255, 255, 255, 0.5); cursor: pointer; } .dots span.active { background: #fff; }参数说明overflow: hidden裁掉超出容器的部分object-fit: cover保证图片填满且不变形opacity过渡做淡入淡出比display切换更平滑按钮的z-index: 10确保在图片之上。圆点用transform: translateX(-50%)水平居中这是比margin-left负值更稳的做法。3.3 商品卡片的网格布局与 hover 效果商品列表用 Grid 布局最省心四列等宽间距 14px。卡片 hover 时加阴影和上浮这是电商页面的标配.goods-list { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; } .goods-item { background: #fff; padding: 20px; text-align: center; transition: all 0.3s; cursor: pointer; } .goods-item:hover { box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); transform: translateY(-4px); } .goods-item img { width: 160px; height: 160px; object-fit: contain; } .goods-item .title { font-size: 14px; color: #333; margin: 10px 0; } .goods-item .price { color: #ff6700; font-size: 16px; font-weight: bold; } .goods-item .old-price { color: #b0b0b0; text-decoration: line-through; font-size: 12px; margin-left: 6px; } .goods-item .tag { display: inline-block; background: #ff6700; color: #fff; font-size: 12px; padding: 2px 6px; border-radius: 2px; margin-bottom: 6px; }grid-template-columns: repeat(4, 1fr)表示四列等宽gap: 14px是列间距。卡片 hover 的translateY(-4px)配合阴影视觉上就是「浮起来」的效果。价格用橙色加粗原价用灰色加删除线这是电商页面通用的价格表达方式。4. js 让页面动起来轮播、渲染和购物车角标三个核心交互4.1 轮播图的自动播放与手动切换轮播的 js 逻辑不复杂核心是维护一个currentIndex每次切换时把当前图片的active类去掉给下一张加上。自动播放用setInterval手动点击时先清除定时器再重新开始避免冲突const carousel document.getElementById(carousel); const images carousel.querySelectorAll(img); const prevBtn document.getElementById(prevBtn); const nextBtn document.getElementById(nextBtn); const dotsContainer document.getElementById(dots); let currentIndex 0; let timer null; // 生成圆点 images.forEach((_, i) { const dot document.createElement(span); if (i 0) dot.classList.add(active); dot.addEventListener(click, () goTo(i)); dotsContainer.appendChild(dot); }); const dots dotsContainer.querySelectorAll(span); function goTo(index) { images[currentIndex].classList.remove(active); dots[currentIndex].classList.remove(active); currentIndex (index images.length) % images.length; images[currentIndex].classList.add(active); dots[currentIndex].classList.add(active); } function next() { goTo(currentIndex 1); } function prev() { goTo(currentIndex - 1); } function startAuto() { timer setInterval(next, 3000); } function stopAuto() { clearInterval(timer); } nextBtn.addEventListener(click, () { stopAuto(); next(); startAuto(); }); prevBtn.addEventListener(click, () { stopAuto(); prev(); startAuto(); }); carousel.addEventListener(mouseenter, stopAuto); carousel.addEventListener(mouseleave, startAuto); startAuto();逻辑说明goTo里用(index images.length) % images.length处理边界点到最后一张再点下一张会回到第一张。stopAuto和startAuto配合手动操作后重新计时避免自动播放和手动操作打架。鼠标移入暂停、移出继续这是轮播的常见交互。参数3000是切换间隔单位毫秒你可以改成 2000 或 5000看演示节奏。4.2 用 js 渲染商品列表并绑定点击事件商品列表由 js 根据goodsData生成这样你改数据不用动 Html。渲染完再给每个卡片绑定点击事件点击后更新购物车角标const goodsList document.getElementById(goodsList); const badge document.querySelector(.badge); let cartCount 0; function renderGoods() { goodsList.innerHTML goodsData.map((item, index) div classgoods-item>const searchInput document.querySelector(.search-box input); searchInput.addEventListener(input, (e) { const keyword e.target.value.trim().toLowerCase(); const filtered goodsData.filter(item item.title.toLowerCase().includes(keyword) ); renderFiltered(filtered); }); function renderFiltered(list) { goodsList.innerHTML list.map((item, index) div classgoods-item>// 页面加载时读取购物车数量 const savedCount localStorage.getItem(cartCount); if (savedCount) { cartCount parseInt(savedCount, 10); badge.textContent cartCount; } // 每次更新角标时同步存储 function updateBadge() { badge.textContent cartCount; localStorage.setItem(cartCount, cartCount); }把原来直接改badge.textContent的地方换成updateBadge()刷新页面后数量就不会丢了。这个技巧在答辩时很加分因为评委通常会刷新页面看数据是否持久化。进阶功能关键 API演示价值购物车持久化localStorage刷新不丢数据显得完整键盘切换轮播keydown 事件演示流畅不用找鼠标返回顶部scrollTo smooth长页面体验好代码量小最后说个我自己的习惯每次交作业前我会把项目拷到一个全新目录用浏览器直接打开 index.html不依赖任何本地服务器确认所有路径都是相对路径、所有资源都能加载。这一步能筛掉八成「在我电脑上好好的」问题。仿小米商城这个项目技术难度不高但细节多能把细节都照顾到作业就不会差。希望帮到你。本文还有配套的精品资源点击获取