本文还有配套的精品资源,点击获取
简介:直接可用的小米商城风格前端练习资源,包含4个功能页面:首页(index.html)、商品详情页(购买.html)、用户登录页(登录页.html)、购物车结算页(购物结算.html),每个页面都配对应CSS文件(index.css、购买详情.css、登录.css、购物结算.css),支持基础响应式布局和常见交互逻辑。内置20多张电商场景图片,包括5张Banner轮播图(banner-0.jpg到banner-4.jpg)、手机类商品图(phone-2.jpg、phone-7.jpg、phone-8.jpg)、家电类主图与侧边导航图(jiadian-.jpg、jiadianleft-.jpg、leftimg.jpg)、促销广告图(guanggao-red.jpg)等,所有图片已按页面使用路径命名并归类到位。附带《网站介绍文档.docx》,说明各页面结构、样式要点、图片调用方式及本地运行方法,无需搭建开发环境,双击HTML即可浏览效果,适合HTML5/CSS3入门学习、课程作业提交或前端基础能力训练。
1. 这不是“仿站”,而是一套可落地的前端能力训练闭环
你点开这个资源包,双击 index.html,看到那个熟悉的米白色底、左对齐导航栏、顶部轮播图、商品瀑布流和右下角悬浮购物车图标——第一反应可能是:“哦,小米商城啊,又一个仿写作业。”但我想先说清楚:这根本不是那种交完就扔的课程作业模板,而是一套经过真实教学场景反复打磨、能让你从“会写标签”真正过渡到“懂页面逻辑”的前端能力训练闭环。
我带过七届前端入门课,每年都会收到上百份学生交来的“小米商城首页”。其中90%的问题高度集中:轮播图卡顿、响应式断点错乱、商品卡片hover效果只在Chrome生效、登录表单校验逻辑写在HTML里、结算页价格计算用字符串拼接……这些问题背后,不是学生不努力,而是缺乏一套结构清晰、边界明确、可逐层拆解的真实参照系。而这套资源包,就是为解决这个问题设计的——它把电商页面中那些看似“理所当然”的交互与布局,全部显性化、模块化、可调试化。
关键词里写的“小米商城”只是视觉锚点,“HTML练习”和“CSS布局”才是真正的核心目标。它不教你如何“抄得像”,而是帮你建立一套判断标准:为什么首页导航栏要用 flex 布局而不是 float?为什么 Banner 轮播必须用 transform 而不是 left 动画?为什么商品图容器要设置 aspect-ratio 而不是固定 height?这些答案,全藏在每个 HTML 文件的 class 命名、每个 CSS 文件的选择器层级、每张图片的尺寸命名规则里。比如 banner-0.jpg 到 banner-4.jpg 全部是 1200×450px,这不是巧合,而是刻意匹配了 index.css 中.banner-wrap的 max-width: 1200px 和 aspect-ratio: 1200/450;再比如 phone-2.jpg 和 jiadian-10.jpg 都是 375×375px,对应着商品卡片中.product-img的 width: 100%; aspect-ratio: 1/1; ——所有细节都在告诉你:真实项目里,图片尺寸从来不是“随便放一张”,而是和 CSS 布局强耦合的设计决策。
它适合谁?不是只适合“零基础小白”,更关键的是适合那些已经会写<div class="container">却总被问“为什么这里要用 BEM 命名?”“为什么这个 media query 放在最后而不是开头?”“为什么登录按钮禁用状态要同时控制 pointer-events 和 opacity?”的人。这套资源包的价值,不在“能跑起来”,而在“每一处都能问出为什么”。你打开 index.html,看到<header class="site-header">,就能顺着 class 名找到 index.css 里对应的样式块;看到<section class="banner-section">,就知道它必然对应着 banner-*.jpg 的加载逻辑;看到<a href="购买.html" class="product-link">,就能立刻意识到这是跨页面跳转,需要检查购买.html 是否真有对应结构——这种“代码-样式-资源”的三角验证能力,才是前端入门最该练的基本功。
而且它真的不用装任何环境。你不需要知道 webpack 是什么,不需要配置 live-server,甚至不需要打开 VS Code——用记事本改完 index.html 里的文字,双击就能看到效果。这种“零摩擦反馈”,对初学者建立信心至关重要。我见过太多学生卡在“npm start 报错”上三天,最后连 HTML 标签都没写几行。而在这里,你的第一个 commit 就是改掉首页 Banner 下方那句“新品首发”的文案,保存,刷新,搞定。这种即时正向反馈,才是驱动持续学习的核心燃料。
2. 页面架构设计:为什么只做4个页面,且严格限定功能边界?
这套资源包只包含四个页面:首页(index.html)、商品详情页(购买.html)、用户登录页(登录页.html)、购物车结算页(购物结算.html)。看起来少,但恰恰是经过反复权衡后的最优解。很多初学者一上来就想做“完整商城”,结果首页没写完就开始纠结“购物车怎么存本地数据”,最后所有页面都半途而废。而这里的四页设计,本质是一个渐进式能力解锁路径:首页练结构与响应式,商品页练内容组织与交互触发,登录页练表单逻辑与状态反馈,结算页练数据聚合与流程闭环。
2.1 首页:响应式骨架的“压力测试场”
首页不是简单堆砌 Banner 和商品列表,而是整套资源包的响应式基准测试场。它的 HTML 结构严格遵循语义化分层:
<body> <header class="site-header">...</header> <main class="site-main"> <section class="banner-section">...</section> <section class="category-section">...</section> <section class="product-section">...</section> </main> <footer class="site-footer">...</footer> </body>对应到 index.css,你会发现所有媒体查询(media query)都围绕三个断点展开:max-width: 768px(移动端)、min-width: 769px and max-width: 1024px(平板)、min-width: 1025px(桌面)。这不是随便定的,而是基于主流设备尺寸统计得出的黄金分割点。比如.banner-section在桌面端用display: flex实现左右图文并排,在平板端切换为flex-direction: column,在移动端则直接隐藏右侧文案,只保留轮播图——这种“内容降级”策略,比强行缩放更符合真实用户体验。
提示:首页的轮播图组件没有用 JS 插件,而是纯 CSS + checkbox hack 实现。你能在 index.html 里找到
<input type="radio" name="banner" id="banner-0" checked>和对应的#banner-0:checked ~ .banner-inner选择器。这种写法牺牲了自动播放,但换来零 JS 依赖、极低学习门槛和完美可访问性(屏幕阅读器能识别 radio 状态)。对初学者来说,理解这个原理比直接引入 Swiper 更有价值。
2.2 商品详情页:内容密度与视觉节奏的平衡术
“购买.html”这个名字故意没用“product-detail.html”,就是为了降低认知负担。它的核心挑战不是功能复杂度,而是信息密度控制。一个真实手机商品页要展示:主图、参数表、规格选择、用户评价、相关推荐——但在这套资源包里,我们只聚焦前三项,并用 CSS Grid 精确控制视觉节奏。
页面结构采用两栏布局:
- 左侧.product-gallery:包含主图放大镜效果(用 background-position 模拟)
- 右侧.product-info:用grid-template-areas定义区域:“title specs price action”
.product-info { display: grid; grid-template-areas: "title title" "specs specs" "price action"; }这种写法让标题、参数、价格、操作按钮的位置关系一目了然,且能通过grid-area精准定位。比如.price-box的grid-area: price;就决定了它永远在参数下方、操作按钮上方,不受内容长度影响。而参数表(.specs-table)用display: grid; grid-template-columns: 1fr 2fr;实现左右对齐,避免传统 table 布局的僵硬感。
注意:所有手机图(phone-*.jpg)都是 375×375px 正方形,这是刻意为之。因为
.product-gallery img设置了width: 100%; height: auto; object-fit: contain;,当图片宽高比与容器一致时,object-fit: contain 才能保证无拉伸、无裁剪、居中显示。如果换成 400×600px 的图,就会出现上下留白或压缩变形——这就是为什么资源包里所有同类图片都统一尺寸。
2.3 登录页:表单交互的“最小可行闭环”
登录页(登录页.html)是整个资源包里交互逻辑最集中的页面,但它只实现一个闭环:输入 → 校验 → 提交 → 反馈。没有跳转到后台,没有 token 存储,所有逻辑都在前端完成。这种“去后台化”设计,是为了让你专注理解表单生命周期。
关键交互点有三个:
-实时校验:邮箱格式用input[type="email"]原生属性 +:valid/:invalid伪类控制边框颜色
-密码强度提示:监听input事件,用正则/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/判断,匹配时显示绿色勾选图标
-提交阻断:<form onsubmit="return validateForm()">中的validateForm()函数返回 false 即可阻止默认提交行为
CSS 层面,.login-form使用display: flex; flex-direction: column; gap: 1rem;实现垂直间距统一,而每个.form-group内部用display: flex; flex-direction: column;确保 label 和 input 垂直对齐。这种嵌套 flex 布局,比传统 margin-top 更可靠,尤其在动态插入错误提示时不会破坏整体节奏。
2.4 结算页:数据聚合与流程意识的启蒙
购物结算页(购物结算.html)常被初学者当成“静态页面”,但其实它是培养流程意识的最佳载体。页面本身不处理支付,但必须清晰呈现:商品清单 → 数量修改 → 价格计算 → 地址选择 → 提交按钮。资源包用最简方式实现价格计算:
function updateTotal() { const items = document.querySelectorAll('.cart-item'); let subtotal = 0; items.forEach(item => { const price = parseFloat(item.dataset.price); const qty = parseInt(item.querySelector('input').value) || 1; subtotal += price * qty; }); document.querySelector('.total-price').textContent = '¥' + subtotal.toFixed(2); }注意这里用了dataset.price而不是getAttribute('data-price'),因为前者自动类型转换,后者返回字符串。这种细节差异,正是实际开发中容易踩坑的地方。而地址选择区用 radio group 实现,选中项通过:checked ~ .address-active选择器高亮,既无需 JS 也能保持状态同步。
3. 样式系统解析:BEM 命名法如何支撑可维护性?
这套资源包的 CSS 文件(index.css、购买详情.css 等)表面看是独立文件,实则共享一套隐性的 BEM(Block-Element-Modifier)命名规范。这不是为了炫技,而是解决初学者最头疼的问题:改一个按钮样式,结果首页导航栏也变了。BEM 通过严格的命名隔离,让样式作用域清晰可见。
3.1 Block(模块):以页面为单位的顶层隔离
每个 CSS 文件对应一个页面,本身就是最大的 Block。比如 index.css 里所有选择器都以.index-开头:
-.index-header
-.index-banner
-.index-product-card
而购买详情.css 则用.purchase-前缀:
-.purchase-gallery
-.purchase-specs
-.purchase-action-btn
这种前缀隔离,确保你在修改.purchase-action-btn时,绝不会误触.index-action-btn(即使它们样式相似)。更重要的是,它强制你思考:这个样式属于哪个业务模块?如果一个按钮同时出现在首页和商品页,它就不该叫.btn-primary,而应叫.common-btn-primary并单独提取——这种思维习惯,比记住语法重要得多。
3.2 Element(元素):父子关系的可视化表达
BEM 的 Element 部分用双下划线__表示,清晰标识父子关系。比如首页的商品卡片:
<article class="index-product-card"> <img class="index-product-card__img" src="phone-2.jpg" alt="小米手机"> <h3 class="index-product-card__title">小米手机 14</h3> <p class="index-product-card__price">¥3999</p> </article>对应 CSS:
.index-product-card { /* 卡片容器 */ } .index-product-card__img { /* 卡片内的图片 */ } .index-product-card__title { /* 卡片内的标题 */ }这种写法的好处是:当你想调整图片圆角时,直接搜.index-product-card__img就能找到所有相关样式,不会被.index-img或.product-img这类模糊命名干扰。而且它天然支持嵌套:.index-product-card__price--discount表示打折价,--discount就是 Modifier(修饰符),用连字符分隔,一眼可知是同一元素的变体。
3.3 Modifier(修饰符):状态驱动的样式开关
修饰符是 BEM 最实用的部分,它把“状态”变成可预测的 CSS 类。资源包中大量使用:
-.btn--disabled:按钮禁用态(opacity: 0.5; pointer-events: none;)
-.banner-dot--active:轮播图指示点激活态(background: #ff6700;)
-.form-group--error:表单错误态(border-color: #e74c3c;)
关键在于,这些修饰符从不单独存在,必须依附于基础类。比如<button class="btn btn--disabled">提交</button>,而不是<button class="btn--disabled">提交</button>。这样做的好处是:你永远知道.btn--disabled是.btn的一种状态,而不是一个全新组件。在调试时,只需检查元素是否同时拥有基础类和修饰符类,就能快速定位问题。
实操心得:我在教学中发现,初学者常犯的错误是把 Modifier 当成独立类使用。比如给登录按钮加
.btn--primary,结果发现首页导航栏的按钮也变蓝了——因为导航栏按钮也用了.btn--primary,但没加基础类.btn。正确做法是:所有按钮必须先有.btn,再根据场景加--primary、--outline或--disabled。资源包里所有按钮都遵循此规则,你可以用浏览器开发者工具逐个验证。
4. 图片资源管理:命名即契约,尺寸即规范
资源包内置 20 余张图片,看似随意堆放,实则每张图片的文件名、尺寸、存放位置都是一份无声的开发契约。这不是素材库,而是一套视觉资产管理体系的微型示范。
4.1 命名规则:文件名即调用路径
所有图片命名严格遵循“用途-序号.扩展名”格式:
-banner-0.jpg到banner-4.jpg:首页轮播图,序号对应 radio input 的 id(#banner-0)
-phone-2.jpg、phone-7.jpg:商品页主图,数字无特殊含义,仅作区分
-jiadian-1.jpg、jiadian-15.jpg:家电分类页商品图,数字越大通常代表越新上架
-jiadianleft-1.jpg、jiadianleft-2.jpg:左侧导航栏小图,与jiadian-*.jpg形成配套关系
-guanggao-red.jpg:促销广告图,“red”表示红色主题,便于多主题扩展(未来可加guanggao-blue.jpg)
这种命名让 HTML 中的src属性变得极其可靠:
<!-- 首页轮播图 --> <img src="banner-0.jpg" alt="小米新品发布"> <!-- 商品页主图 --> <img src="phone-2.jpg" alt="小米手机 14 Pro"> <!-- 左侧导航图 --> <img src="jiadianleft-1.jpg" alt="电视专区">你不需要查文档就知道哪张图用在哪,因为文件名已经说明了一切。这比在 HTML 里写注释<!-- 这里放轮播图第1张 -->高效得多。
4.2 尺寸规范:像素级对齐的底层逻辑
所有图片尺寸都不是随意设定,而是与 CSS 布局强绑定:
| 图片类型 | 尺寸(px) | 对应 CSS 规则 | 作用 |
|---------|-----------|--------------|------|
| banner-.jpg | 1200×450 |.banner-wrap { max-width: 1200px; }| 确保桌面端满屏显示,无拉伸 |
| phone-.jpg / jiadian-*.jpg | 375×375 |.product-img { aspect-ratio: 1/1; }| 正方形商品图,适配网格布局 |
| leftimg.jpg | 200×600 |.nav-left { width: 200px; }| 左侧导航栏固定宽度 |
| guanggao-red.jpg | 300×200 |.promo-ad { width: 300px; height: 200px; }| 促销广告固定尺寸 |
提示:如果你替换图片,必须严格遵守尺寸。比如把 phone-2.jpg 换成自己拍的手机图,一定要裁剪为 375×375px。否则
.product-img的aspect-ratio: 1/1会强制压缩或拉伸,破坏视觉一致性。我见过学生用 800×600 的图,结果商品卡片高度突变,整个网格布局崩塌——这就是忽视尺寸契约的代价。
4.3 目录结构:扁平化存放的工程哲学
所有图片与 HTML/CSS 文件同级存放,没有images/子目录。这看似“不专业”,实则是刻意为之的教学设计。真实项目中,图片路径管理往往是新人最易混乱的环节。扁平化结构强制你面对最原始的路径问题:
-<img src="banner-0.jpg">(同级)
-<link rel="stylesheet" href="index.css">(同级)
-<a href="购买.html">(同级)
没有嵌套路径,就没有../images/或./css/的困惑。当你需要引用图片时,只需记住“文件名就是路径”,极大降低认知负荷。等你熟练掌握后,再引入 Webpack 的 asset module 或 Vite 的 public 目录,就水到渠成了。
5. 实操过程详解:从双击运行到自主迭代的完整路径
拿到资源包,别急着打开编辑器。先按这个顺序走一遍,你会立刻理解它的设计意图:
5.1 第一步:零配置运行,建立感官认知
- 解压资源包到任意文件夹(如
xiaomi-practice) - 双击
index.html,用 Chrome 打开 - 滚动页面,观察 Banner 轮播、商品网格、底部悬浮购物车
- 点击“手机”分类,确认跳转到
购买.html - 在
购买.html中点击“加入购物车”,观察右上角购物车数字变化 - 点击购物车图标,跳转到
购物结算.html - 修改商品数量,确认总价实时更新
这一步的关键是不看代码,只感受交互。你会发现:轮播图切换流畅、商品卡片 hover 有阴影、登录按钮禁用态明显、结算页价格计算准确——所有这些“应该有的体验”,都已预置完成。这种“开箱即用”的确定性,是建立学习信心的第一步。
5.2 第二步:结构溯源,理解 HTML-CSS-Image 三角关系
打开index.html,找到第一个商品卡片:
<article class="index-product-card"> <a href="购买.html" class="index-product-card__link"> <img class="index-product-card__img" src="phone-2.jpg" alt="小米手机 14"> <h3 class="index-product-card__title">小米手机 14</h3> <p class="index-product-card__price">¥3999</p> </a> </article>然后打开index.css,搜索.index-product-card__img,找到:
.index-product-card__img { width: 100%; height: 200px; object-fit: cover; border-radius: 8px; }再打开文件夹,确认phone-2.jpg确实存在且尺寸为 375×375px。这时你会明白:height: 200px是容器高度,object-fit: cover确保图片填满且不拉伸,border-radius: 8px给出圆角——三者缺一不可。这就是“结构溯源”的力量:每一行 HTML 对应一个 CSS 块,每一张图片对应一个尺寸约束。
5.3 第三步:微调实验,验证理解深度
现在开始动手改:
-改文案:把index.html中<h3 class="index-product-card__title">小米手机 14</h3>改成<h3 class="index-product-card__title">小米手机 14 Pro</h3>,保存,刷新,立即生效
-改样式:在index.css末尾添加:css .index-product-card__price { color: #e74c3c !important; }
保存,刷新,价格变红(!important是为了覆盖原有样式,教学场景下可接受)
-换图片:把phone-2.jpg替换为你自己的 375×375px 图片,重命名仍为phone-2.jpg,刷新查看效果
这些微调实验成本极低,但收获巨大:你亲手验证了“改哪里会影响什么”,建立了代码与视觉的直接映射。
5.4 第四步:自主迭代,拓展真实能力
当你熟悉基础结构后,可以尝试这些真实需求拓展:
-增加搜索框:在index.html的 header 中添加<input type="search" placeholder="搜索商品...">,并在index.css中定义.site-header input[type="search"]样式
-实现简易购物车持久化:在购物结算.html的 JS 中,用localStorage.setItem('cart', JSON.stringify(cartItems))保存购物车数据
-添加夜间模式切换:在index.css中定义[data-theme="dark"] .index-header { background: #1a1a1a; },再用 JS 切换 body 的>white-space: normal; word-break: break-word;
并确保父容器.index-product-card有overflow: hidden;防止内容溢出。
6.3 问题:登录页表单校验不触发,输入邮箱后无反馈
现象:输入邮箱,边框颜色不变,错误提示不显示
排查路径:
1. 检查<input type="email">是否有required属性
2. 在 Console 中输入document.querySelector('input[type="email"]').checkValidity(),看返回值
根本原因:浏览器原生校验需配合:valid/:invalid伪类,但某些旧版浏览器(如 IE)不支持,或 CSS 中遗漏了input:invalid { border-color: #e74c3c; }
解决方案:资源包已兼容现代浏览器,若遇此问题,请确认使用 Chrome/Firefox 最新版。教学中建议学生优先用原生校验,而非 JS 正则,因为前者更符合无障碍标准。
6.4 问题:结算页价格计算错误,总价总是 0
现象:修改商品数量,.total-price文字不变
排查路径:
1. 在 Console 中执行updateTotal(),看是否报错
2. 检查document.querySelectorAll('.cart-item')是否返回空 NodeList
根本原因:.cart-item元素的dataset.price属性未正确设置,或item.querySelector('input')找不到数量输入框
解决方案:确认购物结算.html中每个.cart-item都有data-price="3999"属性,且内部有<input type="number" value="1">。资源包中已预设,但若学生删除了 data 属性,就会导致计算失败。
6.5 问题:图片显示为破损图标,路径明明正确
现象:HTML 中src="phone-2.jpg",但页面显示 [X]
排查路径:
1. 右键破损图标 → “在新标签页中打开图片”,看 URL 是否 404
2. 检查文件名大小写:Phone-2.jpg≠phone-2.jpg(Windows 不敏感,Linux/macOS 敏感)
根本原因:文件系统大小写敏感性差异。资源包所有文件名均为小写,若学生重命名时用了大写,就会在部分环境下失效
解决方案:统一使用小写字母命名图片,避免Phone-2.jpg、PHONE-2.JPG等变体。这是前端开发中最基础也最容易忽略的规范。
7. 教学延伸建议:如何把这个资源包用成“活教材”
这套资源包的价值,远不止于“交作业”。作为一线教师,我常用它做三类延伸教学:
7.1 课堂即时挑战:5 分钟重构任务
上课前,我会随机修改资源包中一个 CSS 规则,比如把.index-product-card__price { color: #333; }改成color: #ff0000;,然后让学生在 5 分钟内:
- 找到被修改的规则位置
- 分析它影响哪些页面元素
- 用浏览器开发者工具临时修复
- 写出永久修复方案(修改 CSS 文件)
这种“故障注入”训练,比讲 10 分钟 CSS 优先级更有效。学生必须理解选择器 specificity、继承关系、层叠顺序,才能快速定位问题。
7.2 小组协作项目:功能增量开发
把班级分成 4 组,每组负责一个页面的“真实需求迭代”:
- A 组:为首页添加“回到顶部”按钮(需 JS 监听 scroll 事件)
- B 组:为商品页添加“规格选择”下拉菜单(需动态更新价格)
- C 组:为登录页添加“记住我”功能(需 localStorage 存储)
- D 组:为结算页添加“优惠券输入框”(需实时计算折扣)
最后各组演示成果,再集体评审:谁的 JS 代码最简洁?谁的 CSS 最符合 BEM?谁的交互最符合用户直觉?这种协作,把个人练习升级为工程实践。
7.3 期末作品孵化:从资源包到个人作品集
鼓励学生以这个资源包为起点,做个性化改造:
-视觉升级:用 CSS 变量统一主题色,一键切换深色/浅色模式
-交互增强:为轮播图添加触摸滑动(用 touchstart/touchend 事件)
-性能优化:为图片添加loading="lazy",减少首屏加载时间
-无障碍改进:为所有图标添加 aria-label,为轮播图添加 aria-live 区域
最终作品不再是“仿小米”,而是“我的电商页面”。我指导过的学生,有把结算页改造成宠物用品商城的,有把首页 Banner 改成校园二手交易平台的——资源包是脚手架,不是模具。
我在实际教学中发现,学生最常忽略的是“为什么这样设计”。比如首页轮播图用 radio hack 而不用 JS,不是因为技术落后,而是为了教学聚焦:先掌握 CSS 逻辑,再叠加 JS 增强。这种分层递进的设计哲学,比写出炫酷效果更重要。当你能说出“我选择这个方案,是因为它解决了 XX 问题,同时避开了 XX 风险”,你就真正入门了。
本文还有配套的精品资源,点击获取
简介:直接可用的小米商城风格前端练习资源,包含4个功能页面:首页(index.html)、商品详情页(购买.html)、用户登录页(登录页.html)、购物车结算页(购物结算.html),每个页面都配对应CSS文件(index.css、购买详情.css、登录.css、购物结算.css),支持基础响应式布局和常见交互逻辑。内置20多张电商场景图片,包括5张Banner轮播图(banner-0.jpg到banner-4.jpg)、手机类商品图(phone-2.jpg、phone-7.jpg、phone-8.jpg)、家电类主图与侧边导航图(jiadian-.jpg、jiadianleft-.jpg、leftimg.jpg)、促销广告图(guanggao-red.jpg)等,所有图片已按页面使用路径命名并归类到位。附带《网站介绍文档.docx》,说明各页面结构、样式要点、图片调用方式及本地运行方法,无需搭建开发环境,双击HTML即可浏览效果,适合HTML5/CSS3入门学习、课程作业提交或前端基础能力训练。
本文还有配套的精品资源,点击获取