从零完成Web前端第三次作业:HTML+CSS+JS个人主页实操指南

📅 发布时间:2026/10/10 10:03:51
从零完成Web前端第三次作业:HTML+CSS+JS个人主页实操指南
这是我用真实的上课节奏视角帮你把“web前端学习第三次作业”从头到尾拆透的一篇实操记录。很多同学第一次交的是HTML标签练习第二次开始接触CSS到第三次课程一般已经默认你把HTML和CSS基础过完了开始要求“能独立完成一个完整的小页面”最好再带一点JavaScript交互。如果你现在看到作业题目有点懵不知道从哪下手或者写了一半被布局和样式搞到怀疑人生这篇内容应该能帮到你。先说结论第三次作业通常不会让你做多复杂的东西考察的核心就三块——网页结构是否清晰、样式是否稳定、交互是否可用。把它当成一个“完整度优先”的小项目去做而不是当成一道普通练习题你在这次作业里建立起的文件管理意识、调试习惯和结构思维会比作业分数本身值钱得多。1. 作业拆解与方案选型动手前先弄懂这次到底在考什么1.1 第三次作业的课程定位与考察目标前端入门的课程节奏一般前两次作业重点是“认识标签”和“会用选择器”。第一次会让你写一段带标题、段落、图片、链接的页面第二次开始让你用CSS控制颜色、字体、间距可能还要求复刻一个简单布局。到了第三次课程通常会进入“综合应用”阶段很多老师会直接丢一个“个人主页”“产品展示页”或者“博客首页”的题目表面上是交页面实际上是检验三件事第一你有没有建立起“内容、样式、行为分离”的意识。也就是HTML只负责结构、CSS只负责样式、JavaScript只负责交互。很多同学图省事把样式写在标签的style属性里把JS直接inline到按钮上。页面确实能跑但作业交上去有经验的老师一眼就能看出你还没迈过工程化的门槛。第二你的CSS核心基础扎不扎实。浮动、定位、盒模型、flex这些布局手段笔试和练习是一回事放到一个完整页面里是另一回事。第三次作业最容易暴露的问题是单列布局写得飞起一旦要求“左侧导航、右侧内容”或者“三个卡片横向排列”页面就塌了。第三你是否能做到“开箱即用”。老师打开你的HTML文件所有图片本地可见、CSS和JS文件路径正确、没有404、页面在不同宽度下不出现明显错位。这个要求看似基础但每次作业都有相当比例的人栽在上面原因既有路径问题也有浏览器缓存问题。所以你不需要追求酷炫更不要急着上框架。React、Vue在第三阶段出现是给自己挖坑因为一旦上了框架你连HTML和CSS都还没吃透出了问题完全不知道去哪排查。这一次的定位就是用最朴素的技术栈把完整度做到最高。1.2 为什么“个人主页”是第三次作业的最优载体如果作业题目没有强制指定类型我建议你优先选“个人主页”或“个人作品展示页”这种题材。原因很实际数据完全可控。个人简介、技能列表、项目展示、兴趣爱好这些内容你张口就来不需要去外面找素材不会因为图片版权问题折腾半天也不会在复制文字时引入乱码或格式冲突。结构天然清晰。个人主页天然包含“导航区、关于我、作品/技能展示、联系方式/页脚”几个模块。这些模块正好对应HTML的header、nav、main、section、footer标签语义化作业顺手就完成了。视觉主观看得过去。假如你做一个“某某产品官网”内容方不可以看到的东西可能你花了半天时间产出非常精心的页面别人依然觉得没有说服力。而个人主页可以展示自己的真实信息就算布局素一点别人也知道那是一个完整、真实、可以做主的内容。扩展空间大。做完基础版之后你可以在上面继续加轮播图、Tab切换、返回顶部按钮、表单验证。每加一个交互代码量不会失控又能实实在在体现你的JavaScript能力。我见过很多人用“仿某页面布局”来做第三次作业效果其实不好。因为仿站意味着你要跟着别人的内容走你为了对齐一个像素反复调应用到的却是一些碎片化的CSS做完之后你还是不知道自己独立设计页面时该考虑什么。个人主页没有标准答案反而能逼你从信息架构开始思考这才是第三次作业真正的价值。1.3 动工前先画草图与列文件结构这一步不是浪费时间拿到作业题目我建议你先不要打开编辑器先找张纸或者用任意画图工具画出页面的线框图。线框图只标区块不画细节顶部是什么导航中间分几个内容区内容区里是单列还是两列底部放什么。这个过程大概需要20分钟但它能避免你写到一半推翻重来。画完草图后顺手规划一下文件夹结构。第三次作业开始强烈建议你就按“工程化小项目”的标准来组织哪怕只是交一个作业my-project/ ├── index.html ├── css/ │ └── style.css ├── js/ │ └── main.js └── images/ ├── avatar.jpg └── project-demo.png有人说一份作业而已把CSS和JS都写在一个HTML文件里不是更方便交吗单文件提交确实省事但有两个问题一是文件里同时混着几百行CSS和几十行JS老师阅读起来体验很差二是这种写法一旦遇到代码量较大的页面找错误就变成一场噩梦。从这份作业开始养成外部样式表外部脚本的习惯对你后面做项目只有好处。同时注意css、js、images这些文件夹的名字尽量用英文小写不要用“样式”“图片”这种中文文件夹名也不要大小写混用否则部署到服务器或者发给别人用的时候经常因为文件名大小写不匹配碰壁。2. 核心知识点拆解HTML、CSS、JS在这份作业里到底怎么配合2.1 语义化HTML不要一div到底第二次作业你可能还在练习div和span到了第三次作业HTML部分最值得花时间打磨的点就是“语义化”。一句话解释语义化用恰当的标签表达内容本身的含义而不是只为了显示效果。所谓的div是“无语义”的容器适合包裹纯粹的布局区块但如果一份页面里从头到尾都是div嵌套div别人读你代码时完全无法判断哪块是导航、哪块是正文、哪块是独立文章。至少这几个标签你这次作业应该主动用上header页面头部通常放Logo和导航。nav导航区域里面的链接列表用ul/li包裹。main页面的主要内容区一份页面里最好只有一个main。section文档中的章节比如“关于我”“项目作品”就是两个section。article完整的独立内容比如博客列表里的每篇文章。footer页脚放版权信息、联系方式。一个常见误区是为了语义化而语义化。比如把导航的一堆li在外面套了section语义又错了。导航的父元素就是nav不需要再包section。语义化讲究的是“恰到好处”不是“用得越多越好”。另外还有一组容易被忽略的细节图片加alt属性表单控件配labelbutton按钮不要写成div。这些小小的细节在第三次作业里都是加分项。它们背后是“可访问性”思维——你的页面不只有鼠标用户在看还有人用屏幕阅读器听代码里的语义信息就是他们获取内容的通道。2.2 CSS布局主线盒模型、flex、margin合并一个都不能松布局是第三次作业里大家最容易翻车的地方。我见过太多作业页面单看每个局部都还行组合到一起就上下错位、左右溢出。这些问题的根源基本上集中在三个知识点上。盒模型是最底层的东西。每个元素都是一个盒子由内容content、内边距padding、边框border、外边距margin组成。默认情况下你给一个div设置的width指的是content的宽度如果再加上左右padding和border盒子撑到页面外面就一点不奇怪。所以几乎所有现代项目都会在CSS开头重置一下计算方式把它改成border-box让width包含padding和border这样反而更符合直觉。你的作业里可以这样写* { margin: 0; padding: 0; box-sizing: border-box; }这是三行“保命代码”它把默认的8px body外边距清掉也把你后续写布局时可能遇到的宽度意外变大问题一次性解决。第二个重点是flex布局。第三次作业最常用的布局场景不过就几种水平居中的导航栏、多列并排的卡片、上下内容区。flex的优点是只要记住父容器display: flex子项排列方向是主轴方向剩余空间如何分配这几条规则大部分布局都能解决。而且flex天然支持换行你要做三栏卡片父容器flex加上flex-wrap就自动往下排了。第三个坑是margin合并。具体表现是你给一个div设置了margin-bottom: 50px给下一个div设置了margin-top: 30px两兄弟之间你期望的间距是80px实际看见的却是50px因为大的那个margin把小的“吃掉了”。父子之间也容易出这种问题父div上边距和下边距经常被第一个或最后一个子元素带着跑。解决办法不复杂别依赖margin去搞定一切间距给父容器加padding或者用flex布局的gap属性这个属性在一排子元素之间设置间距并且不会出现折叠问题。2.3 JavaScript交互从“看得懂”到“写得出”第三次作业对JavaScript的要求通常很低但“低要求”不等于“不要求”。最理想的起点是做“按钮驱动”的交互点击某个导航项对应内容区块高亮点击一个按钮显示或隐藏某个部分点击“返回顶部”页面平滑滚回顶部。这些交互背后藏着前端初级开发必须吃透的两个能力DOM查找和事件绑定。DOM查找是从页面上找到你想操作的元素。document.querySelector是最常用的方式它接收CSS选择器字符串返回第一个匹配的元素。如果你要找到一组元素比如页面里所有的导航链接那就用document.querySelectorAll它会返回一个NodeList你可以用forEach循环给它逐个绑定事件。事件绑定的写法建议你从一开始就使用addEventListener。有的教材还在教onclick写法比如btn.onclick function() {...}这种写法简单但它有个问题同一个元素的同一个事件只能绑定一个处理函数后面赋值的会覆盖前面的。addEventListener没有这个限制而且它是现代浏览器和实际项目里的标准做法没必要在作业阶段去学一种已经被替代的旧写法。还有一个小细节值得提醒自己JavaScript代码要放在body结束前或者放在window的DOMContentLoaded事件回调里面。因为HTML是从上往下解析的如果脚本放在head里这时候body里的元素还没被解析成DOM对象你立刻去document.querySelector查到的是null事件自然绑不上。很多同学的第一次JS报错就是“Cannot read properties of null (reading addEventListener)”根源就在这里。3. 实操过程全记录手把手做一个完整的个人主页Demo3.1 页面结构搭建先写“骨架”再谈美化我以一份标准到可以交作业的个人主页为例带你把整个过程走一遍。我先写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 div classlogoMy Page/div nav ul lia href#about classactive关于我/a/li lia href#projects项目作品/a/li lia href#contact联系方式/a/li /ul /nav /header main section idabout classabout img srcimages/avatar.jpg alt我的头像 classavatar div classintro h1你好我是某某同学/h1 p一个正在学习前端开发的初学者。这是我用HTML、CSS、JavaScript完成的第一个完整个人主页。/p /div /section section idprojects classprojects h2项目作品/h2 div classcard-list div classcard img srcimages/project-demo.png alt项目一的预览图 h3模拟项目X/h3 p一个用于练习前端基础的个人作品展示页包含响应式布局和交互按钮。/p /div !-- 后续卡片同理 -- /div /section section idcontact classcontact h2联系方式/h2 p邮箱123456example.com/p button idsendBtn给我发邮件/button /section /main footer p© 2024 某某同学的个人主页/p /footer script srcjs/main.js/script /body /html这份结构的几个关键点head里设置了viewport meta标签这会让页面在手机上不直接缩小成桌面宽度三个导航链接通过锚点href#about等点击后滚动到对应sectionmain标签在body里只会出现一次。注意我在footer的版权符号后面使用了“©”来表示年份而不是用真实年份这样也让内容更通用。3.2 样式与布局实现要点让页面“站得住”结构搭好之后接下来是CSS。一份基础但耐看的个人主页样式可以分四块去写全局重置、header导航、about区域、card列表。下面展示关键部分* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: PingFang SC, Microsoft YaHei, sans-serif; line-height: 1.6; color: #333; background-color: #f7f8fa; } header { display: flex; justify-content: space-between; align-items: center; padding: 0 24px; height: 64px; background: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); position: sticky; top: 0; z-index: 100; } nav ul { display: flex; gap: 24px; list-style: none; } nav a { text-decoration: none; color: #666; font-weight: 500; padding: 8px 0; border-bottom: 2px solid transparent; } nav a:hover { color: #0077ff; } nav a.active { color: #0077ff; border-bottom-color: #0077ff; } .about { max-width: 960px; margin: 0 auto; margin-top: 60px; margin-bottom: 60px; padding: 40px; display: flex; align-items: center; gap: 40px; background: #fff; border-radius: 12px; } .avatar { width: 160px; height: 160px; border-radius: 50%; object-fit: cover; } .projects { max-width: 960px; margin: 0 auto; padding: 20px 16px 60px; } .card-list { display: flex; flex-wrap: wrap; gap: 24px; } .card { flex: 1 1 260px; background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); } media (max-width: 640px) { .about { flex-direction: column; text-align: center; } }这段CSS内容里我用flex写了导航的左右分布nav ul里用gap代替了传统的margin给li之间留白避免了margin合并。.about区域用了flex图标和文字左右两列。card-list用flex-wrap和flex: 1 1 260px实现“能放多个就并排放不下就换行”的自适应效果这个组合比写死宽度又加媒体查询要灵巧得多。最后用了一小段媒体查询在窄屏上把about区域改成纵向排列。你别小看这个响应式处理第三次作业如果能保证页面在手机宽度下不横向滚动、不错位就已经超过一半的人了。3.3 交互功能与细节打磨按钮、平滑滚动和状态高亮接下来是JavaScript部分。为了让作业达到“带一点交互”的要求我实现了三个功能点击联系方式按钮弹出提示、导航链接点击后高亮、页面平滑滚动到对应区域。// 1. 给“给我发邮件”按钮绑定点击事件 const sendBtn document.getElementById(sendBtn); if (sendBtn) { sendBtn.addEventListener(click, function () { window.location.href mailto:123456example.com; }); } // 2. 导航链接点击后高亮当前项 const navLinks document.querySelectorAll(nav a); const sections document.querySelectorAll(section); navLinks.forEach(function (link) { link.addEventListener(click, function () { navLinks.forEach(function (item) { item.classList.remove(active); }); link.classList.add(active); }); }); // 3. 平滑滚动到锚点对应位置 document.addEventListener(DOMContentLoaded, function () { document.querySelectorAll(nav a[href^#]).forEach(function (anchor) { anchor.addEventListener(click, function (e) { const targetId anchor.getAttribute(href); const targetSection document.querySelector(targetId); if (targetSection) { e.preventDefault(); targetSection.scrollIntoView({ behavior: smooth }); } }); }); });用addEventListener而不是onclick前面说过了此处重点讲几个代码细节。第一个我在拿到sendBtn后先判断了if (sendBtn)。为什么要判断因为如果HTML里没有这个id的元素getElementById返回nullnull再加addEventListener就会直接报错。作业阶段你经常改HTML代码用这个习惯可以避免“换个页面结构JS就崩掉”的情况。第二个细节导航高亮和锚点滚动其实写了两个click监听。为什么不合并成一个因为它们分别负责“改样式”和“改滚动行为”职责分开后面如果你想调整滚动位置不会误删高亮的逻辑。这是初学者一开始就会用到的代码组织思路。第三个细节关于平滑滚动。默认情况下锚点跳转是没有平滑动画的页面会“咻”一下直接切到目标位置。scrollIntoView配合behavior: smooth可以解决。需要注意的是e.preventDefault()要放在真正需要阻止默认行为的位置我写的是先取出目标id、判断元素存在、再阻止默认行为这样如果目标不存在链接还是会用默认的锚点行为不会完全失效。做完这三部分页面已经具备“静态展示动态反馈”两个维度。一个“响应式布局”加上这三个交互第三次作业的核心要求就全部覆盖了。4. 常见问题与排查技巧实录这些坑我替你踩过了4.1 样式完全没生效先查文件路径和控制台第三次作业最容易出现的第一大事故就是打开页面发现只有文字和图片完全没有任何样式。排查顺序建议从外到内。首先按F12打开开发者工具切到Network网络面板刷新页面。看看有没有红色的请求失败记录。如果有且文件名是style.css十有八九是路径不对。你打开的是index.html而style.css在css文件夹里那么HTML里的写法就应该是css/style.css。如果你把index.html直接打开时是通过file://协议访问的路径基本都是相对路径注意HTML文件和css文件夹的层级关系。一个土办法是把css/style.css从index.html所在目录开始逐级数一遍保证路径里每一层文件夹都有真实文件。如果Network面板显示样式文件请求成功但页面还是没样式可能是CSS文件里出现了语法错误。看Console控制台里有没有报错信息常见的比如“Unexpected token”“Invalid property value”。初学者经常在上一行漏掉分号又或者属性值写错这些都会让浏览器放弃解析后面的规则。一个很实用的排查技巧把CSS文件的内容全选删掉只写一句最简单的“body { background: red; }”如果页面立刻变红说明文件可以被加载问题在具体规则上如果没变红说明根源还是路径或文件名。4.2 图片加载失败alt文字都出来了图却显示一个叉图片图标显示为一个裂开的三角形多半是src路径有问题。检查图片路径的方法和检查CSS是一致的。不过这里有一个特有的坑图片文件名的大小写。有些系统不区分大小写但部署到服务器或发给老师后Linux环境是严格区分大小写的。你在Windows本地写的images/Avatar.jpg文件实际叫avatar.jpg本地可能正常换台电脑打不开。所以在建目录和文件名时一律用小写这是最简单的避免问题的方式。还有一个不太容易被想到的原因图片格式问题。比如你把一张png格式的图片强行改成.jpg后缀部分浏览器也能显示但某些浏览器或某些工具会因数据问题不渲染。确认图片真实格式最好右键查看文件属性或者在编辑器中重新导出一次。4.3 点击按钮没反应事件没绑定上的三个典型原因“按钮点了没反应”是一个劝退无数初学者的经典问题。排查时优先看控制台有没有报错。除了前面提到的null错误之外最常见的还有这三种。第一种JS代码放在head里执行时按钮DOM还没解析出来document.getElementById自然找不到元素。解决办法是把script标签放到body结束前这是最省心的方案。第二种整个页面有多个元素使用了相同id。记住id在同一个页面里必须是唯一的。如果你为了省事给好几个按钮都写了idbtn浏览器只认第一个其余绑定不到。如果确实要处理一组按钮改用class加上querySelectorAll。第三种事件绑定写在了循环里但变量作用域搞错了导致点击任何一个按钮都执行相同的操作。比如用var在for循环里给按钮绑定事件循环结束后i已经变成了最后一个值。解决方法是改用let它的块级作用域会为每次循环保留独立的i值这也算第三次作业里一个很考察JS功底的细节。4.4 布局错乱盒子被撑大和高度塌陷页面布局错乱最常见的两个原因是box-sizing未设置和浮动未被清除。如果你已经用了最前面的“*”重置盒子被撑大的问题基本会被提前消灭。剩下浮动高度塌陷多发生在老式float布局里父元素只包含浮动子元素父元素的高度会变成0下方内容就会贴上来。现代开发里能用flex就不用float卡片并排用flex-wrap实现根本不需要清除浮动。如果你的作业还是被迫使用float比如题目要求传统布局父元素末尾加一行clear: both的空div或者用overflow: hidden可以解决。还有一个小细节很容易让人抓狂明明设置width: 300px但整个元素在页面上看起来占了几百像素。这就要检查是不是margin左右auto造成的居中效果或者父级有flex布局把子项拉伸了。flex子项默认align-self: stretch在垂直方向上会被拉满父容器高度这些视觉上“宽了”或者“高了”的现象本质上都不是bug而是flex布局的默认行为。你在检查布局问题时先把父容器、边框背景临时加出来一目了然。4.5 修改了代码页面没变化浏览器缓存和文件没保存最后一个高频问题不是代码错了而是浏览器显示的是旧文件。修改CSS后刷新页面没变化优先按CtrlF5或CtrlShiftR强制刷新跳过本地缓存。Chrome开发者工具在页面打开状态下会缓存CSS、JS文件普通F5有时候真的无效。另外也检查一下编辑器有没有自动保存如果VSCode的auto save没开启你改完代码但没保存浏览器加载的当然是旧内容。比强制刷新更根治的方法是在Chrome开发者工具的Network面板勾选“Disable cache”并且保持开发者工具打开状态。开发调试期间这样设置基本不会因为缓存问题怀疑人生。5. 提交前的自查清单与加分技巧5.1 功能自查清单交付前逐项打钩写完代码先别急着提交花10分钟按下面这个清单过一遍首页是否有一个完整的导航栏并且有当前区块高亮状态。页面里至少有两到三个内容区域有标题、有正文、有图片。至少有一个交互按钮或事件点击后页面有明显反馈弹窗、跳转、滚动、切换都行。页面底部有footer包含版权或联系方式信息。图片都能正常加载没有一个显示为裂图。页面在电脑浏览器和手机宽度用开发者工具的移动模拟器切换下都不出现横向滚动条。控制台Console没有任何报错。CSS和JS是独立外部文件路径正确。所有标签都正确闭合没有漏掉div或结尾标签。如果一个一个打钩全部通过这份作业的“完成度”就已经到了可以交的水平。我见过很多同学花了大量时间折腾“最后一个小特效”结果连控制台报错都没管最后因为一个低级错误被扣分。自查清单的价值就是防止“因为一个半角括号漏掉而整页崩掉”这种悲剧。5.2 让代码看起来更专业的几个动作前端的作业老师看的不只是页面效果还会看代码本身。以下几个动作能让你交上去的代码显得更专业。第一类的命名语义化。不要用c1、d1、box1这种名字。用header、nav、about、card-list、avatar、intro读代码的人不需要看CSS都能猜到它是干什么的。第二CSS里适当加注释但不是给每个属性都写。在几个大区块之前加一行注释比如“Header导航区域”就够了。注释的作用是让阅读者快速定位代码位置注释太多反而干扰。第三JS里统一用双引号或单引号不要混合用。缩进保持两个或四个空格全篇一致。这些不是硬性规范但一致性本身就体现了编程素养。第四重要图片设置alt文字。前面提到这是可访问性的基础同时也有实际作用图片加载失败时alt里的文字会显示出来页面不至于完全空一块。第五如果作业允许把项目文件夹压缩时不要包含node_modules、.DS_Store这种垃圾文件。别人解压后看到文件夹里干干净净印象分会高不少。5.3 常见扣分点与最后一个避坑建议根据我观察到的经验第三次作业的典型扣分点基本集中在CSS或JS文件路径错误、页面在窄屏下明显错位、控制台存在红色报错、没有任何JavaScript交互、类名随意且无注释、图片使用网络盗链导致加载缓慢或裂图。这几个坑你在提交前专门检查一遍分数就不会差。最后一个建议是第三次作业意味着你已经进入“页面级”开发的阶段从今天开始每一次作业都把“能在公共环境打开”“代码可读”“结构清晰”当成基本标准而不是把“能在我电脑上跑”当成标准。页面最后是给人看的也是要交给一门课程的一个能随时拿给别人看并且不出错的自己生产的页面才是值得花时间打磨到那里的产物。6. 写在作业提交之后我个人在实际操作中见过太多了学到“第三次作业”这个阶段的人前两次作业还在愉快地用记事本写几个标签到这里突然面对一个多文件的小项目最容易的念头就是“我是不是还不行”。其实不是这只是第一次要把“写页面”当“做产品”来对待没有代码经验并不重要因为你在这个过程中学习到文件规划、路径、布局调试和提交检查的每一个经验才都是真实项目里从始至终会用到的能力。还有一些小建议想分享给正在写这份作业的你做完一个页面之后把代码拿给旁边的人看一眼最好是一个不太懂技术的人。如果他能在没有你提示的情况下自己找到三个内容模块、判断出这是一个个人主页你的结构就已经清晰了。如果他说“不知道哪里可以点”那就回去检查你的交互按钮是不是太隐蔽、有没有鼠标hover效果、是不是一根空的无用法未处理的链接。下次作业不只是要“写完”更要让人会发现“这里还可以点”的顺畅感。前端不是一个人自嗨的代码技巧最终它是服务别人的表达方式。第三方板块欢迎微信与我交流你在这个过程中的奇怪报错也许下一个话题就是某一行报错的细致拆解。