资讯详情

用HTML和CSS复刻小米官网:从零搭建企业级页面布局

📅 2026/9/20 4:39:13 | 华诺云谱 👁 阅读
用HTML和CSS复刻小米官网:从零搭建企业级页面布局
1. 为什么要拿官网页面当练手项目1.1 官网页面的技术含量与训练价值很多人在学完HTML和CSS基础之后都会卡在同一个问题上标签和属性都认识但真要独立做一个完整页面脑子里却一片空白。《HTML5网页设计基础》《CSS权威指南》这类书从头翻到尾理论都知道可一打开编辑器就不知道从哪下手。这时候拿一个真实存在的官网页面来复刻是性价比最高的训练方式。小米官网是前端圈子里公认适合练手的项目原因很直接它的视觉层次清晰、模块化程度高、交互类型覆盖广但整体技术难度又没有高到劝退新手的程度。导航栏、轮播图、商品卡片、页脚信息区这些都是实际工作中天天要写的东西。把一个官网“解剖”成几十个独立的HTML模块和CSS样式规则比你对着教程做十个毫无关联的登录页面有用得多。这个项目的另一个价值在于它不是纯“照抄”而是逼着你去思考布局背后的逻辑。比如为什么小米导航栏的文字间距是那样分配的为什么商品卡片在鼠标悬停时只做一个小小的位移和阴影加深这类细节都是设计语言的一部分。用HTML和CSS实现小米官网的过程本质上是在用代码理解视觉设计这种体验是任何刷题软件都给不了你的。1.2 实现前的准备素材与工具清单动手之前先把东西备齐。首先是素材。小米商城官网的产品图和Banner图都有自己的版权你只需要拿来当练习素材就行不要用来做商业用途。最稳的做法是访问官网用浏览器的开发者工具选中图片元素拿到图片直链后另存到本地。特别注意要建一个images目录所有图片统一放进去路径用相对路径否则页面一换目录就全挂了。其次是代码工具。推荐用VS Code装上三个插件就够了Live Server实时刷新、Prettier代码格式化、HTML CSS Support智能提示。Live Server能让你改完CSS立刻在浏览器看到效果省去手动刷新的过程体验感完全不同。还有个容易被忽略的准备打开浏览器的开发者工具CtrlShiftC进入元素选择模式把小米官网的导航栏、轮播图、商品区块的HTML结构大致看一遍。不要求完全复制但要理解它的结构层次。比如导航栏是ul嵌套li还是div嵌套div商品卡片是列表结构还是卡片容器这些结构决定你后面写CSS的方式。看完之后关掉官网凭记忆和截图去复刻效果最好。2. 页面结构拆解与整体设计思路2.1 从导航栏入手布局为王大多数人的第一反应是从顶部开始做先写导航栏。这个思路没问题但要注意导航栏绝不是header里放几个超链接那么简单。小米官网的导航栏一眼看去东西很多但拆开就是四层结构最顶部的纯色快捷导航购物车、消息通知那一条、主Logo区、搜索框和商品分类导航。主导航里还有下拉菜单——鼠标移到“手机”上会弹出具体型号列表。作为新手练习第一版可以先把下拉菜单做出来但不用做得多复杂因为它的核心难点就两个布局方式和显隐控制。布局方面我建议直接用flex布局。老教程里大量用float实现水平导航float本身没错但它是为图文混排设计的用来做导航布局时稍不注意就会碰到高度塌陷的问题。flex解决这类布局的问题是降维打击一行flex子项自动水平排列空间分配用justify-content控制对齐用align-items控制代码简洁且不容易出bug。显隐控制方面经典写法是父级li设置position:relative下拉菜单设置position:absolute配合display:none和:hover状态切换。这里最关键的细节是菜单和触发元素之间不能有视觉断档否则鼠标移动过程中菜单会消失。所以下拉菜单的top值不宜过大或者干脆不给它留间隙用padding撑开视觉距离。2.2 内容区模块划分与主次关系从导航往下整个页面可以分为首屏Banner区、主推商品区、分类商品区、服务保障区和页脚。新手最常见的错误是一路顺着写下来从header一路铺到footer写到哪算哪。这种做法不是完全不行但你会发现页面改起来非常痛苦——改一个模块的字体大小可能因为CSS选择器相互冲突导致整个页面样式错乱。正确的做法是先做模块划分再为每个模块赋予独立的class名。我给这套页面规划的是四个主容器.header、.banner、.main、.footer。其中.main里面再细分不同的区块比如.main .product-grid是商品列表.main .promo-grid是活动入口。写样式的时候尽量用后代选择器限定作用范围比如.main .product-grid .card { }这样各个模块之间互不干扰后期扩展和调整都舒服。主次关系的视觉呈现主要靠字号和颜色层级。小米官网用了一号字到四号字几个跨度大标题用28px左右商品名用14-16px辅助说明和价格用12px。颜色上主文字用#333或者#000辅助文字用#999或者#aaa。这种“越重要越大越深”的层级关系比单纯靠加粗更能体现出设计的秩序感。2.3 选色与字体抓住小米的标志性视觉小米官网的视觉语言其实很克制大面积白底、橙色高亮、灰色辅助。具体来说主品牌色接近#ff6700链接默认是#333悬停后变成#ff6700按钮的主背景色也是#ff6700。这个橙色就是全场的视觉焦点用的时候不要滥用只要出现在主导航的hover、按钮、价格或者促销标签这几个关键位置就够了其他地方保持黑白灰。字体的选择上小米官网的中文字体栈大致是“Helvetica Neue, Helvetica, Arial, Microsoft YaHei”。你直接照搬这个字体栈没问题因为微软雅黑在Windows上体验不错macOS上会走Helvetica整体观感比较干净。文字的间距和行高也很讲究导航栏的行高一般设为50px到60px这样鼠标点击的区域更大视觉上也更协调正文的行高建议1.5到1.8倍读起来不费劲。还有一个细节容易被忽略——圆角的使用。小米官网的按钮和卡片大多带2px到4px的圆角非常轻微只是为了让边缘不那么生硬。新手容易把圆角加得过大导致整个页面看起来“偏玩具”。记住一个原则越是商务科技风圆角越要克制。3. 核心模块的HTML与CSS实现细节3.1 导航栏Flex布局与下拉菜单的配合导航栏HTML的基本结构长这样header classheader div classheader-top div classcontainer a href#小米商城/a a href#MIUI/a a href#云服务/a span classcart购物车/span /div /div div classheader-main div classcontainer div classlogoMI/div nav classnav ul li classnav-item a href#手机/a ul classdropdown lia href#小米15 Pro/a/li lia href#小米15/a/li /ul /li li classnav-itema href#电视/a/li li classnav-itema href#家电/a/li /ul /nav input typetext classsearch placeholder搜索商品 /div /div /headerCSS这边我建议基于flex实现主布局同时把下拉菜单设定为绝对定位。注意在绝对定位定位到父元素li下父元素必须相对定位。另一个关键点是z-index问题因为下拉菜单会覆盖Banner区域必须给它设置一个合理的层级比如z-index: 100不然会被后面的元素用背景色遮住。搜索框部分值得一提。小米的搜索框是圆角矩形的带放大镜图标。图标可以用Unicode字符或伪元素实现也可以用字体图标库。不推荐新手一上来就引入Font Awesome因为加载一个完整图标库只是为了几个图标性能和代码洁癖都过不去。直接用背景图片放一个放大镜SVG或者用伪元素加边框旋转45度模拟放大镜形状都是不错的选择。3.2 商品卡片结构、阴影与悬停反馈商品卡片是整站的视觉主体也是最能体现CSS功底的地方。小米官网的商品卡片结构高度统一上方商品图下方商品名、描述和价格。我用的HTML结构是这样的div classproduct-grid a href# classcard div classcard-img img srcimages/xiaomi15.jpg alt小米15 /div h3 classcard-title小米15/h3 p classcard-desc骁龙8至尊版 徕卡光学镜头/p p classcard-price4499元起/p /a a href# classcard!-- 更多商品 --/a /div卡片设计上要注意三个技术点。第一是图片区域的固定比例。商品图片高度不统一如果直接放进卡片卡片高度会变得参差不齐。最稳的做法是给.card-img一个固定高度比如200px再设置图片宽度100%、高度100%、object-fit: cover。object-fit这个属性是解决图片裁切问题的核心它能让图片在指定区域内按比例缩放并自动裁掉多余部分非常适合商品图场景。第二是阴影的使用。卡片默认没什么阴影或者只有非常淡的box-shadow悬停时阴影变大、卡片轻微上移。这个效果的CSS精妙在于transition。我一般这样写.card { background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.08); transition: transform 0.3s ease, box-shadow 0.3s ease; } .card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.12); }这里的问题是transform和box-shadow都要加transition很多人只加了box-shadow结果鼠标移上去时卡片是瞬间跳上去的那种“生硬感”非常明显。好的动效要体现在每一个属性上。第三是价格的颜色。小米的价格通常是橙色用#ff6700但促销价和原价并列时原价用删除线处理CSS里就是text-decoration: line-through同时把原价的颜色改成#bbb。这是官网页面中非常讨巧的小技巧搜索热词里反复出现的“css 删除线”其实就是这个。很多新手不知道删除线不是中划线属性而是text-decoration的line-through值这两个概念容易混淆。3.3 按钮、图标与字体渐变的质感细节首页除了导航和商品卡还会出现各种按钮比如“立即抢购”“了解详情”。小米的按钮主要分实心橙和描边灰两种。实心按钮的写法很直接a href# classbtn btn-primary立即抢购/a a href# classbtn btn-outline了解详情/a实心按钮背景色为#ff6700文字白色hover时背景变深#e65c00描边按钮是透明背景、1px灰色边框、深色文字hover时边框变橙色、文字也变橙。两者都加一个transition动效0.3秒手感统一。按钮圆角别大2到4px就够了。图标部分最推荐用SVG雪碧图或直接内联一个SVG。比如购物车图标我从网上下载了一个免费的购物车SVG直接用img标签引入。但注意SVG的颜色在img里是不好通过CSS改的如果你需要在鼠标悬停时改变图标的颜色就得把SVG代码直接内嵌到HTML中然后通过fill属性配合hover来调整。CSS字体渐变这个技能在官网里也有用武之地。比如一些大促区块的标题文字会用到从橙色到黄色的渐变效果.gradient-text { background: linear-gradient(to right, #ff6700, #ffa500); -webkit-background-clip: text; background-clip: text; color: transparent; }这个写法的核心是background-clip: text意思是让背景按照文字的形状来裁剪。配合color: transparent文字就能显示背景渐变色。要注意的是background-clip这个属性还需要带上-webkit-前缀才能在大多数现代浏览器里正常工作。这个技巧在普通视觉类项目中非常实用很多新手的误解是“文字渐变”一定要用图片或Canvas其实纯CSS就能做到。4. 实操从零搭建页面到联调4.1 第一步搭建HTML骨架新建一个项目目录结构是这样的xiaomi-clone/ ├── index.html ├── css/ │ └── style.css ├── images/ │ ├── logo.png │ ├── banner1.jpg │ └── product-01.jpg └── js/ └── main.jsindex.html里最基本的就是文档头和DOCTYPE。这个千万别写错DOCTYPE声明要放在第一行不然浏览器会进入怪异模式导致盒模型和CSS的解析出现各种莫名其妙的问题。我习惯写成这样!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 !-- 页面内容 -- /body /htmlviewport这个meta标签不要省它对于移动端适配很重要。虽然练手阶段主要以桌面端为参照但有了这个标签后续在窄屏下调试会方便很多。4.2 第二步全局CSS变量与基础重置CSS开头的全局重置部分直接决定后面样式写的顺手程度。我推荐在页面接入一段最轻量的reset* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Helvetica Neue, Helvetica, Arial, Microsoft YaHei, sans-serif; color: #333; background: #f5f5f5; line-height: 1.5; } a { text-decoration: none; color: #333; } ul { list-style: none; } img { max-width: 100%; display: block; }这里有个值得多说一句的点*选择器在通配重置的应用。搜索热词里专门有“css 样式表中使用*的优缺点”说明很多人纠结。我的建议是通配符重置像margin和padding没问题就算全局统一清掉也很安全性能损耗在普通页面几乎感知不到但不要把box-shadow、transition这类属性也放到*里全局设置因为那样会让所有元素都带同样的动效反而变得不协调。接下来定义CSS变量方便后面统一管理主题色:root { --primary: #ff6700; --primary-dark: #e65c00; --text-main: #333333; --text-sub: #999999; --bg-body: #f5f5f5; --bg-white: #ffffff; --shadow-card: 0 1px 4px rgba(0, 0, 0, 0.08); --shadow-card-hover: 0 8px 20px rgba(0, 0, 0, 0.12); }用变量而不是写死颜色值后期如果想调整主题色只需要改:root里的变量即可不用全局搜索替换。这个习惯建议从练手阶段就开始养成。4.3 第三步分区实现与联调整个页面我建议按四个阶段推进每完成一个阶段都在浏览器里看一下整体效果不要等全部写完再看。阶段一写顶部快捷导航和主导航。先把容器宽度统一比如设置一个最大宽度1200px的.container居中这样无论屏幕多宽内容都会保持在页面的视觉中心。阶段二写Banner和主推商品区。Banner一般就是几张轮播图静态练习可以只放一张静态大图先不写JS轮播逻辑。商品区用CSS Grid或者Flex配合自动换行我比较推荐Grid因为它控制列数和间距非常直接.product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 20px 0; }阶段三写分类商品区和服务保障区。分类商品区的结构和主推区基本一致区别在于标题栏不同。可以用一个.group-head左边标题右边“查看更多”链接下面接一个grid。服务保障区的4个图标条目可以用flexjustify-content: space-between排成一行。阶段四写页脚。页脚通常包含多列链接和底部的版权信息。用flex布局每列宽度不一样也没关系用flex: 1分配空间就行。联调阶段的重点是检查这些交叉点导航下拉菜单是否被Banner遮挡轮播图区域的文字颜色是否在不同背景图上依然可读hover动效是否都统一了0.3s的节奏各区块之间的垂直间距是否一致。我习惯用一个简单的方式检查间距打开开发者工具的Elements面板点选元素后查看margin和padding如果所有区块的间距都用统一变量维护这一步就会非常轻松。5. 常见问题与排查技巧实录5.1 卡片和图片撑破布局做商品卡片时最常见的问题一行四列的商品卡在写完第三、四张图后突然换行或者卡片高度参差不齐。根因基本都是图片尺寸没控制好。图片原始大小可能是800乘600但你的卡片图片区域只有200px高如果不加约束图片会以原始大小渲染把卡片撑破。解决办法就是前面提到的object-fit: cover同时给.card-img定高。但还有一个隐藏问题如果图片还在加载时容器高度是0加载完成后高度突变后面的内容会抖一下。一个稳妥的兜底方案是给.card-img设置一个padding-bottom的百分比占位也就是“aspect ratio box”技巧。比如希望比例为4比3时padding-bottom设置为75%再让图片绝对定位填满整个容器。这个技巧在响应式场景下尤其好用。5.2 下拉菜单鼠标移过去就消失这是基于hover实现下拉菜单的老大难。如果你给ul.dropdown设置了绝对定位后发现鼠标从导航项往下移动到菜单的途中菜单突然消失那几乎可以断定是菜单和导航项之间存在透明间隙。这个间隙来自导航项的padding或者下拉菜单的top值。排查时先在开发者工具里选中这个下拉菜单看它的盒模型和位置把鼠标移到菜单上时观察整个元素的边框区域。如果发现间隙大于0就调整.top或者直接把下拉菜单和导航项之间的间隙去掉让它们紧贴。另一个做法是给下拉菜单和导航项留一个公共的透明区域用伪元素覆盖住间隙但新手理解起来成本略高我建议第一版直接紧贴就好。5.3 hover样式不生效的三种典型原因常见的hover不生效原因一是选择器优先级问题二是拼写问题三是元素确实没被触发。优先级问题最典型的场景是.card a里设置了color: #333而hover规则写成.card a:hover { color: #ff6700; }如果还有第三个规则是.card-box .card a { color: red; }那优先级就会发生竞争。排查优先级的方法很简单在开发者工具的Styles面板里看哪条规则被划掉了就知道是谁赢谁输。拼写问题主要出现在伪类上hover写成了hvoer或者把:hover写成了: hover中间多一个空格。这类问题看得很隐蔽建议写样式时开启Prettier做格式化能减少大部分手滑错误。至于元素没被触发多发生在子元素填充了整个父级区域但父级有半透明背景点击/悬停时似乎没反应。其实不是没反应而是悬停到了子元素上触发了子元素本身的样式。这种情况按优先级规则单独给子元素的hover写样式即可。5.4 定位方式混乱导致页面叠层异常absolute、relative、fixed三种定位练手页面的使用频率都不低但混在一起时特别容易出问题。我的建议是给每个使用定位的元素一个清晰的定位上下文。比如导航栏的header设为relative它下面的下拉菜单设为absolute回到顶部按钮用fixed而Card内的标签角标比如“新品”角标用absolute并让.card设为relative。这样每一个absolute都有明确的“父级参照物”不会出现层级满天飞的场面。如果出现某个元素浮到了其他元素上面又无处安放先别急着改z-index。先检查它的父级是否在正常文档流中再检查是否漏写了position。绝大多数情况都是position没写导致absolute被祖先的非定位元素截获了参照坐标。6. 进阶扩展从静态页面到可维护组件6.1 抽出公共组件样式写完整个页面之后回头看自己的代码你会发现很多样式是重复的。比如商品卡片用了十几次每次复制一整段HTML和CSS修改一个属性要全局搜索替换效率很低。这个阶段适合做“组件抽离”。把商品卡片、按钮、价格标签、区块标题这种重复出现的结构抽成单独的组件类写进一个components.css文件里然后用下面的方式复用div classproduct-grid a href# classcard div classcard-imgimg srcimages/products/phone-1.jpg alt小米15/div h3 classcard-title小米15/h3 p classcard-desc骁龙8至尊版/p p classcard-pricespan classprice-now4499元起/span/p /a /div同时把图片路径等可变内容用占位符或变量控制。这一步做完你就拥有了一个可以交给其他人继续维护的“小型组件库雏形”成就感会很强。6.2 增加微交互与小特效页面基本成型后可以往上加一些让“质感”明显提升的小交互。条件是这些交互不要用到繁重的JavaScript用纯CSS就能实现。比如Banner的文字区域可以在鼠标悬停时产生一个轻微的缩放效果卡片图片在悬停时放大1.05倍用overflow: hidden把超出部分裁掉底部回顶按钮在滚动超过一屏后从右侧滑入这个用CSS的position: sticky或者配合少量JS都能实现。再比如导航的搜索框在获得焦点时边框变成品牌橙色同时外发光用box-shadow: 0 0 0 2px rgba(255, 103, 0, 0.3)实现整个页面的交互反馈会立刻变得“年轻化”。这种细节是真正拉开新手和资深前端差距的地方——不是你会写多少标签而是你知不知道这些“手感”细节怎么搭。6.3 我的个人习惯与后续建议最后说点实在的。我在做这类练手页面时习惯每完成一个模块就git commit一次提交信息写得清楚一点比如“完成导航栏布局”“完成商品卡片组件”。这样如果后面改坏了随时可以回退到上一个正常的版本。刚开始写代码的人总觉得提交是团队合作的事情其实个人练手更需要养成这个习惯你的版本管理能力就是从这里练出来的。还有一个习惯我建议项目全部做完以后关掉浏览器尝试不看源码重写一遍。第二遍会有脱胎换骨的感觉因为你不再“照着画”而是真正理解每个结构为什么这么写。第一遍可能需要四五个小时第二遍可能只需要一个小时但第二遍的收获远大于第一遍。如果还想继续拓展可以给这个页面做响应式适配。用媒体查询把商品卡从四列降为两列导航栏在小屏改成汉堡菜单图片用百分比宽度自适应。这一步做完你会发现自己已经能从“能写页面”跨越到“能写一套页面”HTML和CSS的整体理解又会再上一个台阶。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。