
简介以小米有品为主题的购物网站前端项目适合网页设计课程作业、前端入门实战或希望快速搭建电商静态页面的学习者参考。项目覆盖在线购物常见流程包含首页商品陈列导航、商品分类、购物车、登录注册、个人中心等页面用HTML搭结构、CSS做样式并通过媒体查询与swiper轮播实现响应式布局和图片切换效果。资源共48个文件以HTML、CSS、JS及多张PNG/JPG商品图片为主压缩包仅3.49MB解压即可在浏览器中打开运行便于阅读与合并修改。swiper-bundle库已内置登录、验证码等页面亦有完整样式与素材对应。已有3314人下载学习适合点击资源链接获取完整代码作为电商类页面布局与样式设计的对照模板。1. 这个HTMLCSS购物网站练的不是排版是还原度用纯 HTMLCSS 把小米有品首页做出来看着像“照猫画虎”实际上练的是还原度——盯着设计稿把结构拆对、把间距调准、把 hover 状态做完整。这门功夫不依赖任何框架是所有前端岗位的底层能力也是新手学完 HTML 和 CSS 基础之后最值得投入的第一个完整项目。它适合刚学完语法、缺一个“能拿得出手”的作品的人也适合要交课程设计、想转行前端但简历上只有练习题的人。做这个项目你不需要会 JavaScript 也能完成 90% 的页面效果因为电商首页的骨架和质感本来就应该由 HTML 结构和 CSS 样式撑起来。2. 先拆结构把首页从上到下切成五层打开小米有品官网别急着写代码先做一件很多新手跳过的事把页面当乐高拆开。我一般会把首页拆成顶栏、头部搜索区、导航区、内容主区和底部版权区这五层每一层再往下拆成独立的模块。这个动作决定了后续 CSS 写起来顺不顺也决定了代码能不能维护。2.1 顶栏、搜索区、导航区的结构写法先用语义化标签把大骨架搭出来常见的做法是header包顶栏和搜索区nav放商品分类导航main包主体内容footer放底部信息。注意不要一上来就用div把一切包住语义标签对后续样式挂载和阅读都友好得多。header classsite-header div classtopbar div classcontainer span classtopbar-left小米有品 官网/span span classtopbar-right登录 | 注册/span /div /div div classsearch-area div classcontainer header-flex a href# classlogo小米有品/a form classsearch-form action# input typetext placeholder手机 家电 数码 button typesubmit搜索/button /form a href# classcart-link购物车/a /div /div nav classcategory-nav div classcontainer ul classnav-list lia href#手机/a/li lia href#电视/a/li lia href#笔记本/a/li lia href#智能家居/a/li /ul /div /nav /header这套结构里值得注意的点有三个。一是.container用固定宽度居中页面内容在 1920 宽屏幕下不至于摊成一片二是.header-flex是留给 Flex 排版的类名后面搜索区要横向对齐三是导航列表用ul li而不是散落的div逛过电商页面的都知道频道导航本质上就是一组链接列表列表语义在这里最合适。.topbar是顶栏做电商页的人习惯把登录注册和通栏公告放这这是我见过绝大多数商城项目的标准布局。2.2 商品卡片和主区楼层的语义选择主体内容区是整个项目工作量最大的部分。首先要决定卡片列表用什么标签我一般坚持ul li包商品卡片而不是把一堆div.card平铺。原因很简单ul自带“同样层级的内容集合”语义而且用 CSS 选择器控制子项时.goods-list li比.goods-list div的意图明确得多不容易误伤内部嵌套的元素。main classsite-main section classbanner-section div classbanner-item主视觉横幅/div /section section classcategory-grid div classsection-title热门分类/div ul classgoods-list li classgoods-item a href# img srcimages/product-1.webp alt商品名称 h3商品标题这里放两行/h3 p classpricespan classsale-price1999元/span/p p classtags标签一 标签二/p /a /li li classgoods-item !-- 重复N项 -- /li /ul /section section classpromo-floor !-- 楼层模块 -- /section /main这段代码里有个细节常被忽略img的alt属性要和商品名对应而不是写“图片”。搜索引擎看这个爬虫看这个如果你后面做性能排查空alt还会造成干扰。另一个细节是每个楼层模块用section包一层里面写一个.section-title后面用 CSS 统一控制标题字号和底线距离就不需要逐个调。楼层之间如果需要区分背景色给section加不同背景类即可。2.3 骨架搭完别急着写样式先做一次“无CSS方言检查”这一步是很多速成教程不会带你做的但实战里特别有用。骨架写好之后把 CSS 文件先不引入在浏览器里看一眼裸的 HTML 页面。此时页面没有任何颜色和定位唯一的信息传达方式就是标题层级、列表结构和文字顺序。检查三件事第一从上往下滚一遍确认页面内容的阅读顺序和真实站点的楼层顺序一致第二看h1、h2、h3是否按层级出现——电商首页常见的翻车是h1用在商品卡片的标题上一页出现几十个h1对搜索引擎很不友好第三确认每个链接都有实际的href哪怕是占位的#也行否则 hover 样式在后续调试时会出现“点了没反应”的假象。常见做法是以h1给整站名称或主视觉用一次各楼层标题用h2卡片内部商品名用h3。这样语义树的层级和视觉层级保持一致后续写 CSS 也会自然很多。骨架阶段不需要纠结美观重点是把信息架构定住——这一步稳了后面所有样式代码都是在给已经定好型的建筑做装修而不是敲掉承重墙重砌。3. 让页面像小米有品的三套CSS关键手法骨架搭好之后进入真正的 CSS 主战场。电商首页的观感说到底由三件事决定布局方式、间距与字号的统一性、hover 细节的完整度。这三件事做扎实了页面就算没有配图也能有“商城味”。3.1 用Flex布局解决导航和卡片横排现在的电商页面已经很少有人用浮动做整页布局了主流的做法是 Flex。拿第 2 章的头部结构举例.header-flex要解决“logo 在左、搜索框居中、购物车在右”这个问题一行代码就够。.header-flex { display: flex; align-items: center; justify-content: space-between; } .nav-list { display: flex; gap: 28px; margin: 0; padding: 0; list-style: none; } .goods-list { display: flex; flex-wrap: wrap; gap: 16px; margin: 0; padding: 0; list-style: none; } .goods-item { flex: 0 0 calc(25% - 12px); background: #fff; border-radius: 8px; }这里几个参数不是随便写的值得逐个说清楚。.nav-list的gap: 28px是导航项之间的间距比给每个li设margin-right更省事也避免最后一个子项多出边距.goods-list的flex-wrap: wrap允许卡片在宽度不够时换行这是响应式的基础.goods-item的flex: 0 0 calc(25% - 12px)意思是固定基底宽度为父容器 25% 再减去间距的补偿值让每行四张卡片且刚好填满。如果我不减去这个 12px四张卡片加三个 16px 的 gap 会把容器撑破换行这是新手最容易看半天找不到原因的布局翻车。3.2 间距与字号页面质感的根本来源很多同学从教程里抄来一堆组件拼在一起却总觉得“不够高级”问题往往不在配色而在间距和字号没有体系。小米有品这类商城页面的质感本质是统一的白底、克制的阴影、整齐的间距节奏。我一般用 CSS 变量先把这几个基础令牌定义好。:root { --gap-sm: 8px; --gap-md: 16px; --gap-lg: 24px; --text-title: 18px; --text-body: 14px; --text-price: 16px; --color-text: #333; --color-muted: #999; --color-accent: #ff6700; --radius-sm: 4px; --radius-md: 8px; } .section-title { font-size: var(--text-title); color: var(--color-text); margin-bottom: var(--gap-md); } .price .sale-price { font-size: var(--text-price); color: var(--color-accent); font-weight: 600; }这套 CSS 变量的价值在于全局一致性。标题字号 18、正文字号 14、价格强调 16后面写一二十个模块都复用同一个变量不会出现“这个标题 17px那个标题 18px”的肉眼难察、统一时又痛苦的情况。间距变量同理8、16、24 是电商页面最常用的间隔档位三层递进足够覆盖绝大多数场景。行内还推荐加一条line-height: 1.6给正文尤其是商品描述区域行距太挤会让大批文字显得杂乱。3.3 hover状态设计边框、阴影、位移一套做完这是和“css 鼠标移入事件”最直接相关的一块。很多页面的卡片 hover 只改了一个背景色显得很单薄。小米有品这类商城页面的卡片 hover 通常是“边框颜色变浅、阴影抬起来、卡片轻微上移”三联动作。一次做全套比一个一个加省心。.goods-item { transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease; border: 1px solid #e5e5e5; } .goods-item:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); border-color: #ff6700; } .goods-item img { display: block; width: 100%; transition: transform 0.4s ease; } .goods-item:hover img { transform: scale(1.04); }参数说明translateY(-4px)的 4px 是经过验证的舒适位移太大显得飘太小没反馈box-shadow的0 8px 20px rgba(0,0,0,0.08)意思是垂直方向 8px 的投影、20px 模糊半径、8% 透明度这个透明度是重点——电商页面的阴影一旦超过 12%页面就会显得灰蒙蒙失去清爽感border-color: #ff6700是小米生态最常见的橙色强调色。图片的scale(1.04)是内层放大配合外层的overflow: hidden使用不然图片放大后会顶破卡片的圆角边框。这里有一个关键习惯transition写在默认状态而不是写在:hover里。写在 hover 里时鼠标移入有动画、移出瞬间“啪”地弹回写在默认状态移入移出都有过渡效果观感柔和很多。4. 避坑还原电商首页最容易翻车的5个细节这个项目走到一半几乎所有人都会遇到几个莫名其妙的状况。样式没生效、图片不见、布局塌了、hover 闪烁。下面五条是从各种本地页面和课设项目里反复出现的高频问题按“现象 → 原因 → 解决”写成排查清单。4.1 本地打开页面只有光秃秃的HTMLCSS完全没加载现象双击index.html页面显示的是裸排版所有颜色、布局全部缺失控制台还有一条类似Access to CSS stylesheet at file:///...的报错。原因大多数情况是 CSS 文件的引入路径不对。新手最常犯的错误是把link relstylesheet hrefcss/style.css写在了head里但文件实际放在别的目录或者文件名大小写对不上。另一个隐蔽原因是一个!doctype html文档头缺失导致的怪异盒模型但那是样式“变丑”而不是“全丢”两者要区分。先看控制台报错指向哪个文件再对照相对路径。解决确认你的 CSS 文件和 HTML 是同级的css文件夹时href 应该写成hrefcss/style.css如果是同级目录就写hrefstyle.css。建议所有资源都用相对路径不要用file:///C:/...这种绝对路径换台电脑或者上传到服务器就全断。另外确认 HTML 第一行必须是!doctype html并且html langzh-cn可以加上这对中文页面的解析和搜索引擎识别都有好处。4.2 盒子里外尺寸对不上总宽越改越乱现象设置了一个width: calc(25% - 12px)的卡片加完padding: 16px之后发现四个卡片把容器撑爆了换行后每行只剩三个。原因CSS 默认的box-sizing是content-box也就是说你写的宽度只包含内容区padding 和 border 还要另加。四张卡片每张多出 32px 的 padding加起来就把容器挤爆了。解决在项目最开头写一条全局声明*, *::before, *::after { box-sizing: border-box; }这条规则让所有元素的 width 直接包含 padding 和 border后面你写width: 25%就是实实在在的 25%不会再因为内边距偷偷变胖。这是我见过的几乎所有成型项目的标配越早加后面越省心。4.3 hover时卡片疯狂抖动鼠标还没移到位就开始闪现象鼠标从卡片一端划过卡片边缘忽上忽下地抖动有时候甚至像闪烁。原因过渡效果只写了 transform 和 box-shadow但transition属性里还把border-color也加了进去而且.goods-item默认没有边框宽度而 hover 时加了边框这种“没有边框→有边框”的跳变会触发布局回流的抖动。还有更常见的原因transition写了all鼠标划过任意子元素都会触发重绘。解决给.goods-item设置固定border: 1px solid transparenthover 只改颜色不让宽度变化transition明确列出需要过渡的属性不要写all。还有一个习惯问题不要把 hover 效果作用在子元素上统一在li:hover里通过后代选择器控制避免鼠标移动到文字上时就触发整个卡片的状态变化。把默认边框宽度和 hover 后的边框宽度保持一致是消除抖动最立竿见影的办法。4.4 列表的 margin 和坑垂直外边距塌陷现象给.section-title设置了margin-bottom: 24px但标题和下方商品列表之间几乎没有间距看起来只有几像素。原因这是margin塌陷。父容器.category-grid没有设 padding、没有 border、也没有overflow: hidden此时子元素的垂直margin会“穿透”到父元素外面和父元素外部的 margin 合并最终取两者中的最大值而你不一定算得到这笔账。解决给父容器加任意一个创建 BFC 的属性最省事的是overflow: hidden或者padding-top: 1px也有的人直接用display: flow-root这是专门为此设计的现代属性兼容性已经很好了。另外注意兄弟元素之间不要同时用上下的 margin统一用margin-bottom避免两个 margin 合并导致总间距不可控。4.5 选择器优先级失控为什么我的样式不生效现象某个li想要白色背景但无论写background: #fff还是带!important页面展示的仍是灰色或其他颜色。原因前面某处写了更高优先级的选择器比如.goods-list .goods-item或#content .goods-itemID 选择器的特殊性太高class 根本盖不过去。新手还容易把样式写在直接在 HTML 标签上的style属性里那玩意的优先级高于任何选择器导致你在 CSS 里根本改不动。解决先按 F12 打开控制台选中该元素右侧 Styles 面板里能直接看到“被划掉”的样式和实际生效的规则找到胜出的那条规则是谁写的再决定怎么调整。生产上的一般做法是不要用 ID 写样式保持类选择器的层级尽量浅比如.goods-item就够了不需要.category-grid .goods-list .goods-item。如果一行类名写三层以上说明结构已经过度嵌套考虑把样式直接挂在目标类上。!important不是后悔药它是下一任维护者的噩梦尽量少用。5. 进阶玩法用纯CSS把静态页面做出“动态感”用户留在页面上的前几秒视觉反馈占了很大权重。HTMLCSS 项目里不带 JavaScript 也能做出相当有质感的动态效果下面三种是电商页面最常见也最容易出彩的纯 CSS 手段。5.1 主视觉横幅的渐变与光效小米有品首页上方通常是全宽主视觉图图片没到位时可以用 CSS 渐变先撑住场景并且加一个缓动的光晕扫过效果。.banner-item { min-height: 260px; background: linear-gradient(120deg, #ff6700, #ff9500); position: relative; overflow: hidden; border-radius: 12px; } .banner-item::before { content: ; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); animation: scan 3.5s ease-in-out infinite; } keyframes scan { 0% { left: -100%; } 100% { left: 200%; } }这段代码的思路是用::before伪元素做一条透明的白色渐变带animation控制它从左往右周期性扫过这就是被检索圈里常说的“涟漪光圈扩散”类效果在电商横幅里的变体。left从一个负值扫到正值注意动画要配合overflow: hidden不然光带扫出边框后会撑出横向滚动条。做这类装饰动效时克制是第一原则——一条横幅一个扫光就够全都动起来页面会显得很廉价。5.2 商品图里的伪三维旋转展示热词里有transform: rotateY(60deg) translateZ(300px)这类写法做轮播或展示区时确实能让主推商品转起来。理解它的核心规则其实不复杂rotateY 是绕竖直轴旋转正负决定转动的方向先转还是先移动顺序不同结果也不同。.promo-item:hover { transform: perspective(800px) rotateY(-12deg) translateZ(30px); }这段 CSS 加在鼠标悬停时能让商品块产生一点“从货架上探出头”的立体感。perspective: 800px是透视距离数值越小变形越夸张800 是比较自然的范围rotateY(-12deg)负值表示向右偏转配合translateZ(30px)把元素朝眼睛方向拉近。如果你前面哪一步写出了rotateY(60deg) translateZ(300px)然后发现商品转得看不见了不用慌——那是因为垂直翻转角度过大元素几乎转到了侧面。把角度降到 12 到 20 度同时把位移控制在 20 到 40px就能得到肉眼舒适的伪 3D 手感。这种写法的正负判断经验之谈是先写正角度看效果不对再改负角度比空算坐标更快。5.3 购物车角标的小圆点动效购物车链接旁边常见红色数字角标很多同学会想用 JS 去改实际上纯 CSS 也能完成“出现 抖动”的反馈。div classcart-box a href# classcart-link购物车/a span classcart-badge3/span /div.cart-box { position: relative; } .cart-badge { position: absolute; top: -8px; right: -14px; min-width: 18px; height: 18px; padding: 0 4px; background: #ff6700; color: #fff; font-size: 12px; line-height: 18px; text-align: center; border-radius: 9px; animation: pop 0.4s ease; } keyframes pop { 0% { transform: scale(0); } 60% { transform: scale(1.3); } 100% { transform: scale(1); } }这里的圆角值是高度的一半border-radius: 9px配height: 18px出来的就是胶囊形这是“n/2 规则”里最快出效果的一个。角标位置用position: absolute相对于.cart-box所以父级要有position: relative忘了这个角标会飘到页面左上角。pop动画在元素首次渲染时执行做课程设计展示时也能唬唬人不用 JS刷新页面就能看到弹跳效果。这种小动效的细节恰恰是电商页面“完成度”和普通静态练习页拉开差距的地方。6. 页面做完了怎么验证它真的能扛住使用项目合上之前我习惯做三轮验证每一轮都能发现前面没注意到的问题。第一轮是窄屏测试。打开浏览器开发者工具把页面切到 390px 宽度模拟手机从上往下滚一遍。重点看三件事导航栏有没有横向溢出的滚动条商品卡片的calc(25% - 12px)是否变成三列或两列搜索框是否被压缩得只剩下一个按钮。如果你希望手机端也整齐给.goods-item加一条min-width: 140px防止分数宽度算出来的卡片窄到没法看。第二轮是无样式检查。把 CSS 文件从link里暂时注释掉再滚一遍页面。如果这时信息顺序仍然完整说明你的 HTML 结构经得起“皮肤被扒掉”的考验。这个习惯来自一次线上事故排查——某个页面上线后样式文件挂了整个页面乱成一团从那以后我做的每个页面都要确认裸结构能读通。第三轮是控制台清零。打开控制台看有没有样式层级的红色警告、资源加载失败和图片 404。图片加载失败在本地目录里很常见路径写成/images/xxx.webp的绝对根路径在本地直接打不开改成相对的images/xxx.webp就正常。另外把页面打包或发送给别人时整个项目文件夹一起打包不要只发一个 HTML 单文件否则对方看到的就是缺图少样式的“半成品”。做这个项目的最后阶段我还会顺手做一件小事把文件目录整理干净css文件夹里放样式images文件夹里放图片HTML 文件按页面对应命名。这不算技术含量但面试官打开压缩包的那一刻“印象分”就在这些细节里。我当年的第一个完整页面做得一团糟——卡片间距不统一、hover 效果闪烁、发出去给同学打开全是样式丢失。后来养成一个习惯每写完一个模块立刻切到窄屏和控制台各看一眼别攒到全部做完再一起查。希望这个习惯也能帮到你。本文还有配套的精品资源点击获取