简介这是面向前端初学者的入门教程资源以仿制苹果官网为实战目标帮助掌握HTML页面骨架搭建并结合JavaScript与jQuery实现导航交互、滚动特效等动态效果。资源整体对应静态企业站的前端实现层次适合学完HTML基础后想要进阶交互开发的人群。压缩包共449个文件约8.54MB。主体为图片素材250个png、147个jpg、8个gif辅以12个html演示页面、14个css样式表与18个js脚本。css中包含base.css、nav.css、promos.css、slideshow.css等细分模块便于了解大型站点样式的拆分思路。已有1871人在CSDN学习下载口碑与实用性经过一定验证。通过对照HTML结构与JS/jQ特效代码读者可以理解下拉导航、图片轮播、滚动监听等常见交互的实现方式也能学习到真实项目中如何组织文件与资源目录为后续独立开发响应式营销页面打下扎实基础。1. 防苹果Apple官网这个练习很多人第一反应是「抄一份代码」其实真正的价值在另一面把官网首页的结构拆开、用html基础语义化标签重建、再拿CSSJS基础语法去还原视觉和交互比看一百页教程更能建立页面感。这里不引框架就用一个index.html、一个style.css、一个main.js把最小可用的Apple风格首页跑通。适合刚学完标签想找实战入口的人也适合常年写业务页面、想回头补前端基础的人。整篇按「搭结构、写样式、加交互、查坑」四步推跟着走完能直接拿来当作品集里的第一页。2. 用HTML基础搭出Apple首页骨架四块版面的语义化分工2.1 先拆页面再写结构导航、Hero、卡片与页脚把Apple官网首页从上到下过一遍能看出四个位置稳定的版面模块顶部通栏导航、视觉上压住首屏的Hero区、三到四个并排的产品卡片、以及收尾的页脚。做防Apple官网的页面前拿纸把这四块画出来比打开编辑器更管用因为后面CSS挂选择器和JS绑事件都依赖这棵结构树。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title防Apple官网 · html基础练习/title link relstylesheet hrefstyle.css /head body header classnav-wrap nav classnav a classnav-logo href#Apple/a ul classnav-menu li classnav-itema href#macMac/a/li li classnav-itema href#ipadiPad/a/li li classnav-itema href#iphoneiPhone/a/li /ul button typebutton classnav-toggle aria-label打开菜单 aria-expandedfalse span classtoggle-line/span /button /nav /header main section classhero idiphone h1iPhone 15 Pro/h1 p classsubhead钛金属够硬够轻。/p p classhero-links a href#进一步了解/a a href#购买/a /p /section section classcards article classcard idmacMacBook Pro/article article classcard idipadiPad/article article classcardWatch/article /section /main footer classfooter p classfooter-note这是一个 html基础 CSS JS基础语法练习页面/p /footer /body /html这一份HTML把四类页面角色的归属写得很清楚。header里放导航main里放Hero和卡片footer放在main外侧。需要尤其注意两个地方第一h1在整个页面中只出现一次Apple官网首页的主标语用h1产品配角一律用h2或h3这不是玄学而是让搜索引擎和屏幕阅读器知道哪个是页面主题第二Hero里的「进一步了解」和「购买」用的是a标签不是button因为它们负责页面跳转不负责提交操作而右上角汉堡按钮是button因为它改变菜单开合状态。2.2 非布局性标签的细节内联元素、图片与标题层级仿写Apple官网很多观感差异其实来自内联元素的处理。「进一步了解 」这种链接如果直接在a里写文本和大于号hover时想整体变色没有问题但想单独控制箭头位移就只能包一层。常见做法是给文字包span箭头交给CSS的伪元素这样箭头跟着hover可以多一个20px左右的位移。HTML结构上这一点差别决定了后面CSS能不能精细控制。再配合一张标签对照表方便在防Apple官网练习里查阅标签在防Apple官网里的用途常见误用header顶部导航容器页面里塞第二个headermain当前页面唯一主体把footer也收入mainsection有完整标题的主题区块套在纯装饰div上article独立产品卡片把整页内容包进articlefooter站点信息、版权、链接用div代替footer且无语义语义化不是搜索引擎优化专属工具它直接影响CSS选择器的可读性。.nav-menu和.nav-item命名成前缀相同滚动高亮时querySelectorAll(.nav-item)一次拿全不用再担心哪个标签写错。如果你回头看Apple官网的开发人员工具会发现它同样没有把页脚放进mainbody下的层级非常干净。2.3 本地预览与验证HTML树写完HTML先不急着写CSS用浏览器直接打开检查一下结构树。我用VS Code的Live Server做实时预览没有编辑器插件时Python一行也能起服务cd your-project-folder python3 -m http.server 8080浏览器访问http://localhost:8080。直接在地址栏打开index.html的file://协议也能看到页面但后续如果要加fetch或模块化JS会碰到跨域限制这个练习只做DOM操作file协议其实可以跑通不过养成用http服务预览的习惯更稳。起服务后在浏览器开发者工具里切到Elements面板展开body确认body下面只有三个顶层节点header、main、footer。如果发现多出别的元素多半是HTML标签配对没闭合。这一步只暴露结构问题不暴露样式问题。2.4 为什么不直接抄源码这里要澄清一点「防Apple官网」的意思是肉眼照着线上页面做还原练习不是右键另存为。直接抄源码让你失去的是「从参考站点反推布局结构」的能力。实际工作或做外包时对方不会给你一份Apple源码只会给你一张设计图或一个参考站点你能输出的恰恰是从html基础到CSSJS基础语法的落地判断。看Apple官网页面的Network面板会发现首页加载了大量图片和脚本直接copy下来的文件离了CDN和字体资源根本跑不起来。所以整个练习的关键不是拿到代码而是建立「看到一个区块能说出它由哪几个标签构成」的敏感度。3. 用CSSJS基础语法还原Apple视觉变量、字体与间距定住3.1 CSS变量锁定主色与间距Apple官网视觉上的一致性有很大一部分来自同一个颜色和间距体系反复出现。常见做法是仿写时先在:root里定义一组变量后续所有组件都引用变量而不是直接写具体值。:root { --nav-h: 44px; --bg-page: #ffffff; --bg-section: #f5f5f7; --text-main: #1d1d1f; --text-sub: #6e6e73; --accent-blue: #0066cc; --radius-card: 18px; --space-y: 80px; } body { margin: 0; padding-top: var(--nav-h); font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, sans-serif; background: var(--bg-page); color: var(--text-main); }变量名--text-main和--text-sub是一对主副文字色决定了页面整体对比度主文字用#1d1d1f次要提示用#6e6e73。Apple官网上这类灰色在浅色背景下不刺眼但又足以读出层级。如果你手里的参考页面偏暗色把这两个变量换成对应色值即可后面所有组件自动跟着变。字体栈里先放系统字体再放中文字体回退这样在macOS上渲染接近苹方字形的效果在Windows上也能落到雅黑Apple官网实际有自定义字体但仿写练习用系统字体栈是成本和效果平衡的常见做法。3.2 导航固定与Hero全宽两个最常见的布局参数Apple官网导航固定不跟随滚动Hero区视觉上穿透整个首屏。CSS写法上导航用position: fixed主体内容用padding-top让出空间Hero区用flex做水平垂直居中。.nav-wrap { position: fixed; top: 0; left: 0; right: 0; height: var(--nav-h); background: rgba(255, 255, 255, 0.85); backdrop-filter: saturate(180%) blur(20px); z-index: 100; } .nav { max-width: 1024px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; height: 100%; padding: 0 20px; box-sizing: border-box; } .hero { min-height: 480px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }padding: 0 20px给导航左右留出安全边距box-sizing: border-box防止padding把元素总宽撑破。Apple官网在窄屏上也不会让导航文字顶着屏幕边缘这个20px并不大但配合max-width在宽屏上会自动居中。Hero区请留意flex-direction设为column后align-items控制水平方向居中justify-content控制垂直方向居中方向一变两个属性换位这是html基础里flex布局最容易搞混的地方。3.3 大标题用clamp和负字距别写死一个字号Apple官网的大标题是整页记忆点。仿写时如果写死font-size: 72px在窄屏上会把Hero撑出横向滚动条如果只用百分比又很难控制极值。常见做法是用clamp函数把最小、推荐、最大三个参数一并写在font-size里。.hero h1 { font-size: clamp(40px, 8vw, 88px); font-weight: 700; letter-spacing: -0.03em; margin: 0; } .hero .subhead { font-size: clamp(20px, 3vw, 32px); color: var(--text-sub); margin-top: 12px; }clamp(40px, 8vw, 88px)的含义是字号下限40px、上限88px中间值按视口宽度8%计算。屏幕宽度600px时8vw是48px取48px屏幕宽度1200px时8vw是96px超上限取88px屏幕宽度400px时8vw是32px低于下限取40px。这个写法在响应式里几乎是默认首选。letter-spacing: -0.03em是通过负字距让大标题看起来更紧凑Apple官网标题的字符间距明显比普通正文密这一点容易漏补上后标题质感立刻不一样。3.4 卡片网格与hover动效一组可以复用的模板首页下半部分的卡片区用grid排三列是比较稳的仿写方式。关键参数是minmax和gap这两个值能让卡片在不同宽度下自动换列且间距恒定。.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; max-width: 1024px; margin: 0 auto; padding: var(--space-y) 20px; } .card { border-radius: var(--radius-card); background: var(--bg-section); padding: 40px 24px; box-sizing: border-box; transition: transform 0.3s ease; } .card:hover { transform: scale(1.02); }auto-fit与minmax(280px, 1fr)组合以后容器宽度每增加约300px就会自动多挤出一列卡片本身不用写媒体查询就会自适应。transform: scale(1.02)比用font-size或width做hover更省性能它只触发合成层不触发重排在卡片数量不多时体感流畅。如果你还想在Apple官网常见的大图卡片上加图片给img加object-fit: cover并让卡片overflow: hidden就能把不规则图片裁剪成统一比例而不是把整张图拉伸变形。3.5 响应式断点与减弱动效补上你能想到的边界Apple官网的响应式不止改一两个媒体查询。常见断点逻辑是宽度小于768px时隐藏导航菜单、显示汉堡按钮大于768px时反过来。配合这个逻辑CSS里加一条media (max-width: 768px) { .nav-menu { display: none; } .nav-menu.is-open { display: block; } .nav-toggle { display: block; } }前面章节里的JS toggle已经在click事件里通过classList去加is-open这里CSS只负责在断点内切换显示。断点数值的选取可以参照Apple官网的移动端阈值实用主义者取768px并不是唯一标准你可以按自己内容尺寸改成900px但测试时至少要看375px、768px、1024px三档。最后再加一条动效降级media (prefers-reduced-motion: reduce) { .card { transition: none; } }这是给操作系统里开启「减弱动态效果」的用户准备的不少用户在iOS辅助功能里打开了这一项Apple官网本身也会尊重这个系统设置。仿写时顺手写上成本一行体验边界却宽很多。4. 用JS基础语法补上交互短板菜单开关、滚动变色与Hero轮播4.1 汉堡菜单classList是最短的开关方式移动端菜单在Apple官网里点开后是一整块下拉面板。最简单的做法是用button切换菜单的is-open类配合前面的媒体查询来控制显示。HTML结构里button和ul是兄弟关系所以JS里querySelector先拿到两个节点再加监听。const toggle document.querySelector(.nav-toggle); const menu document.querySelector(.nav-menu); toggle.addEventListener(click, function () { const isOpen menu.classList.toggle(is-open); toggle.setAttribute(aria-expanded, String(isOpen)); });classList.toggle返回布尔值菜单从无到有时返回true从有到无时返回false这个返回值直接塞给aria-expanded让辅助技术用户也能感知菜单状态。比if (menu.style.display none)这种写法干净得多。汉堡按钮的图标也用一个纯装饰span来画三条线不引入图片资源.nav-toggle { display: none; width: 44px; height: 44px; border: 0; background: transparent; } .nav-toggle .toggle-line { display: block; width: 18px; height: 2px; background: currentColor; box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor; } media (max-width: 768px) { .nav-toggle { display: block; } }box-shadow用两条偏移值在同一元素下叠加出上中下三条横线currentColor取导航文字颜色这样导航变色时图标也跟着变。如果你在防Apple官网练习时开着开发者工具的Console点击汉堡按钮后观察class变化这一行代码足够把「状态即class」这个思路说明白。4.2 滚动导航与高亮scroll事件的正确姿势Apple官网导航在页面往下滚之后会从透明背景逐渐变成半透明实色。常见做法是在scroll事件里给nav-wrap加一个is-scrolled类样式层做背景加深。window.addEventListener(scroll, function () { const nav document.querySelector(.nav-wrap); nav.classList.toggle(is-scrolled, window.scrollY 60); }, { passive: true });这里有两个JS基础语法要点。第一classList.toggle第二个参数是强制状态scrollY大于60时加类否则移除如果你不想要这种强制语义不要只写一个参数。第二passive: true告诉浏览器滚动监听里不会调用preventDefault浏览器可以不等JS处理直接继续滚动避免在低端机上出现滚动卡顿。CSS侧补一条.nav-wrap.is-scrolled { background: rgba(255, 255, 255, 0.95); box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08); }4.3 轻量轮播Array.from、setInterval与状态取模Hero区如果不想只是一张静态大图可以做一个自动切换的轮播。不引第三方插件纯JS基础语法就能实现。结构上轮播容器常见的做法是下面这样拆成HTML、CSS、JS三段来看。div classcarousel div classcarousel-track section classcarousel-slide标语一/section section classcarousel-slide标语二/section section classcarousel-slide标语三/section /div /div.carousel { overflow: hidden; } .carousel-track { display: flex; width: 300%; transition: transform 0.5s ease; } .carousel-slide { width: 33.333%; flex-shrink: 0; }const track document.querySelector(.carousel-track); const slides Array.from(document.querySelectorAll(.carousel-slide)); let index 0; function goTo(next) { index (next slides.length) % slides.length; track.style.transform translateX( (-index * 100) %); } setInterval(function () { goTo(index 1); }, 4000);轮播里最容易踩的坑是「到了最后一张跳回第一张时往回滚一大段」。这里用(next slides.length) % slides.length做取模让下标永远落在0到N-1之间索引从3再点下一步时变回0视觉上是无缝循环而不是反向滑回去。Array.from把NodeList转成真正的数组是为了后面可以安全调用数组方法虽然这个例子里只用了length但转换后语义更明确。transition的0.5s放在track上切换时才有滑动动画如果你想要「没有动画直接跳」就把transition临时置为none。4.4 事件委托菜单里的导航点击怎么做才不乱一个常见需求是点击导航菜单里的链接后自动关闭移动端展开的菜单。如果给每个nav-item都绑一个监听代码会冗余而且未来新增菜单项还得再绑。事件委托是更好的方案。document.querySelector(.nav-menu).addEventListener(click, function (event) { const item event.target.closest(.nav-item); if (!item) return; menu.classList.remove(is-open); toggle.setAttribute(aria-expanded, false); });event.target.closest(.nav-item)会从被点击元素向上找最接近的.nav-item祖先找不到返回null用if (!item) return提前结束。这样即使点的是菜单里的a元素事件也会冒泡到ul再由closest找到所属菜单项。这段代码同时演示了html基础里事件冒泡的实际用法不需要在每个子元素上挂事件交给父容器统一处理即可。到这里JS基础语法里「查询、监听、改class、同步视图、事件委托」五个习惯都覆盖了。5. 防Apple官网避坑清单五个最容易让页面「一眼假」的细节5.1 固定导航盖住锚点标题加了fixed却忘了预留高度现象做防Apple官网练习时点击菜单里的Mac、iPad锚点页面滚过去了但目标区块标题的上半部分被固定导航挡住看起来像标题被切了一刀。原因position: fixed让导航脱离文档流浏览器滚动到锚点时按元素原始位置计算不会把fixed元素的高度算进去。Apple官网导航高约44px你的Hero标题如果距顶部刚好一段padding就会被覆盖。解决给所有带id的区块统一设置scroll-margin-top值略大于导航高度section[id] { scroll-margin-top: 64px; }这样点击锚点时目标区上边距会多留64px再停。64px里的44px是导航高剩余20px是视觉呼吸感。注意要选section而不是所有带id的元素否则副作用会扩散到不该有的位置。5.2 加了图片后卡片全部挤变形img没有自适应约束现象卡片区文字布局看起来没问题一旦插入产品图某一张卡明显比旁边的卡高出一截图比较大的时候甚至撑破卡片边界出现横向滚动条。原因img的默认尺寸是图片原始像素宽高不会自动跟随容器宽度。grid列宽被minmax限制后图片只会在溢出时撑破布局而不是主动收缩。解决给img一个全局兜底规则img { max-width: 100%; height: auto; display: block; }max-width: 100%约束图片最大等于容器宽度height: auto保持原比例display: block消除行内元素底部的几像素空隙。Apple官网的卡片里图片通常完整展示但如果你想让图片裁剪成充满卡片而不是留出底部空隙把img放进一个固定比例容器并给容器加object-fit: cover。注意全局img规则会影响导航里的logo小图logo通常需要保留原始宽高。如果遇到logo被放大的情况用.nav-logo img单独覆盖即可。5.3 移动端数字链接被识别成电话HTML里出现电话号就变色现象页面在手机上预览卡片上写「400-800-8888」之类的客服数字Safari自动把这段文字变成蓝色可点击链接点一下就跳去拨号。原因iOS的Safari会对看起来像电话号码的连续数字做超链接化属于浏览器内置行为不需要写a标签。防Apple官网如果是仿产品页经常会在页脚放客服电话容易触发。解决在head里加一行metameta nameformat-detection contenttelephoneno这行让Safari不再自动识别页面里的电话串。Apple官网这类大厂页面也会用元信息管理自己的可拨号区域。仿写页加这一行能避免很多「为什么我的文字变蓝了」的玄学问题。5.4 backdrop-filter在部分浏览器里不生效导航变成白板现象导航栏写好了backdrop-filter磨砂效果Chrome里正常换到某个旧版Firefox或部分Android浏览器打开背景变成半透明白一片文字滚动到导航下时也看不到模糊遮盖视觉严重打折。原因backdrop-filter需要浏览器合成器支持旧版浏览器不认识这段CSS时会连background一起忽略导致只留下半透明底色叠加内容层次全无。解决把background和backdrop-filter分开设置再用supports兜底.nav-wrap { background: rgba(255, 255, 255, 0.85); backdrop-filter: saturate(180%) blur(20px); } supports not (backdrop-filter: blur(20px)) { .nav-wrap { background: #fbfbfd; } }这样支持磨砂的浏览器用半透明背景不支持的浏览器回退成纯色背景。检查兼容性时不用断开设备直接在开发者工具里临时删掉backdrop-filter声明观察页面能不能继续正常读就能模拟那个回退状态。5.5 移动端Hero高度每次变化vh单位被地址栏支配现象Hero区设置了min-height: 100vh在手机上滚动时Hero高度随着地址栏收起而变大变小底部内容一会儿露出、一会儿藏住键盘弹出时跳得更离谱。原因移动端浏览器的100vh按「视口元区域」计算的地址栏占据一块动态高度。Apple官网页面在移动端并不依赖100vh撑首屏而是给Hero一个合理的固定高度。解决放弃纯vh改用min()函数把上限压成一屏的90%同时给一个固定下限.hero { min-height: min(480px, 90vh); }min(480px, 90vh)的意思是在480px和90vh里取较小的值。当视口高度900px时90vh是810px比480大取480px当视口高度500px时90vh是450px比480小取450px。这样Hero既不会在超高屏上过长也不会在低矮视口里超出屏幕。如果你有条件对比Apple官网手机版会发现它各区块高度几乎都用内容撑开而不是「占满首屏」这个思路更稳。6. 最后校准开着浏览器开发者工具逐块核对像素与状态验证防Apple官网还原度时我一般不用截图软件对比而是把真实官网和本地练习页分别放在浏览器左右两个窗口用开发者工具逐一读取参数。先打开本地页面的Elements面板选中导航栏读取height、padding、background再切到Apple官网窗口选中同样节点读取同一组参数。这时最容易发现的是padding差异而不是颜色差异。Apple官网的导航高度约44pxHero区的h1字号在桌面端接近88px卡片圆角约18px这些值都不需要背按照真实页面的CSS数值抄进自己的变量表即可。其次验证交互边界。把开发者工具的设备模拟模式打开依次切到375px、768px、1024px三档看三件事导航菜单是否在768px以下变成汉堡、Hero标题是否随宽度缩放、卡片列数是否按预期变化。如果发现某个断点下文字先溢出后换行通常不是CSS错了而是clamp下限设太高需要下调最小字号。最后用Console跑一段统计代码确认页面里没有残留的重复id或空链接const ids Array.from(document.querySelectorAll([id])).map(el el.id); const dupIds ids.filter((id, i) ids.indexOf(id) ! i); console.log(dupIds.length ? 重复 id: dupIds.join(, ) : id 无重复);ids.indexOf(id) ! i的意思是「这个id在数组里第一次出现的位置不是当前位置」说明它重复了。重复id会让锚点跳转和CSS选择器都出现不可预期表现防Apple官网结构和交互都依赖id做锚点这一步值得跑一次。我自己的习惯是每次改完布局先跑这段再回到页面手点一轮导航、菜单和轮播确认aria-expanded和is-open状态都符合预期。这样一套下来剩下的就是纯体力把每一块的字号、间距、圆角对着Apple官网抄准然后删掉参考页面靠记忆重新还原一遍。希望这个html基础练手项目能帮到你。本文还有配套的精品资源点击获取
