简介:面向大学生Web前端课程期末作业的场景,这套“我的书屋”个人网站模版包含5个完整HTML页面,并使用HTML5+CSS3+JavaScript实现。全站围绕书屋主题设计,涵盖首页、个人介绍、摄影爱好等模块,风格统一、结构清晰,适合作为网页制作课程设计或前端入门练习的参考成品。压缩包共70个文件,其中HTML与CSS分别5个和7个,另有45张JPG和12张PNG图片素材以及1张JPEG图片,6.31MB的体积便于直接下载和部署,图片素材已按页面分区命名,能帮助初学者快速理解网页结构与样式配合方式。目前已有136人学习/下载,说明该模版对同类作业需求具有较高参考价值。通过阅读源码和替换图片文字,可以学会多页面站点导航设计、CSS布局样式组织以及图片素材的管理方法,在此基础上改造出属于自己的个人网站,较适合具备初步HTML/CSS知识、希望快速完成期末作品的大学生。
1. 一份期末作业,藏着一个静态站点该有的完整骨架
拆完这份「我的书屋」网页设计包,第一反应是它远比“大学生期末作业”这个标签更有参考价值:五个独立页面、六张拆分清晰的CSS样式表、五十多张配图素材,构成了一个没有依赖任何框架的纯HTML5+CSS3静态站点。对正在做Web前端课程设计的人来说,这是一份能直接改版复用的模板;对已经写了几年业务代码的开发者来说,它反而是观察“多页面站点如何用最朴素的方式组织公共样式、处理跨页跳转、管理图片资源”的绝佳样本。
整个项目走的是经典的个人网站路线:首页、个人介绍、兴趣爱好、相册图集,再加一个承载内容的二级页面。视觉上围绕“书屋”主题铺开,古风与现代素材混搭,整体调性统一。这类项目的核心不在于用了多前沿的技术,而在于页面结构是否合理、样式是否模块化、路径是否在换环境后依然可用。下面直接拆页面和代码。
2. 五个页面的信息架构与导航跳转实现
2.1 从文件清单反推页面规划
拿到压缩包先别急着双击,先看文件结构。压缩包里有五个HTML文件——first.html、personal.html、hobby.html、photo.html、second.html。从命名和图片资源交叉验证,可以还原出这个站点的信息架构:
| 文件 | 栏目定位 | 对应图片素材特征 |
|---|---|---|
first.html | 网站首页 | welcome.jpeg、begin.jpg、logo.png等引导类图片 |
personal.html | 个人简介 | person.png、chenqingling.jpg等人物/标签类图片 |
hobby.html | 兴趣爱好 | novel/小说1-4.jpg、文学1-4.jpg、古典1-4.jpg等分类素材 |
photo.html | 相册图集 | winter1-2.jpg、aespa1-2.jpg、ning1.jpg等展示类图片 |
second.html | 二级内容页 | book.png、book1.png等书籍相关配图 |
值得注意的细节是:首页不叫index.html而叫first.html。这个命名习惯在课程设计里非常常见,但放到生产环境就有问题——部署到Nginx或Apache后,默认首页会尝试加载index.html,不会自动认识first.html。如果直接把这个文件夹丢到服务器根目录,访问域名会得到403或目录列表。这一点在第五节会给出具体的改造方法。
2.2 跨页面导航的公共区处理方式
五个页面之间通过顶部导航和底部版权区连接。静态多页面站点与传统单页应用的最大区别在于:每个页面都需要完整书写头部和底部结构,CSS也要重复加载。这个项目把头部导航抽成了统一的DOM结构,每个HTML文件里的header部分基本一致,结构类似:
<header id="header"> <div class="container"> <div class="logo"> <img src="小书屋logo.jpg" alt="我的书屋"> </div> <nav class="navbar"> <ul> <li><a href="first.html">首页</a></li> <li><a href="personal.html">个人介绍</a></li> <li><a href="hobby.html">兴趣爱好</a></li> <li><a href="photo.html">相册展示</a></li> <li><a href="second.html">更多内容</a></li> </ul> </nav> </div> </header>逻辑说明:这个结构把Logo和导航栏放进.container容器里,通过外层header标签限定页头区域。.container在container.css中统一定义了最大宽度和水平居中,这样所有页面的内容区宽度保持一致。
参数调优时注意两个点:
第一,nav ul li a的跳转全部使用相对路径。相对路径换目录结构时必须同步调整,比如把HTML文件移到子目录,所有href和img src都要加一级../。这个项目HTML文件都在根目录,图片也在根目录,属于最简单的平铺结构,搬动时要格外小心。
第二,当前页面的导航项没有高亮标识。生产环境通常会给当前页的<a>加一个.active类,或者给<body>加页面名class来驱动样式。这个项目没做,但评审时常被问到,建议抄作业时补上。
2.3 图片路径的三种写法对比
这个项目的图片资源全部平铺在根目录,所以HTML里引用图片都是单文件名形式,例如<img src="winter1.jpg">。这种做法在小规模静态站里能跑,但是一旦图片数量过百,根目录会失控。正式一点的写法按资源归属分目录放置:
<!-- 当前项目的写法:平铺根目录 --> <img src="chenqingling.jpg" alt="人物图片"> <!-- 重构后的写法一:按文件类型分目录 --> <img src="images/person/chenqingling.jpg" alt="人物图片"> <!-- 重构后的写法二:按栏目分目录 --> <img src="assets/hobby/novel/小说1.jpg" alt="小说封面">逻辑说明:第二种写法把图片按栏目目录归类,href和src都以images/开头。相比平铺写法,目录归类的优势在两点:一是避免同名文件的命名冲突,二是浏览器请求资源时路径语义化,配合CDN分发时可以更精细地设置缓存策略。
参数差异注意:HTML文件在根目录时,images/...是从当前HTML所在目录向下找;如果HTML文件挪到pages/子目录,就得改成../images/...。所以路径怎么写,完全取决于文件之间的相对位置,而不是取决于“项目看起来该怎么组织”。本地双击打开HTML时用file://协议访问,所有相对路径照常工作;但部署到服务器后用http://访问,如果遇到404,优先检查路径大小写——Linux服务器对文件名大小写敏感,Winter1.jpg和winter1.jpg是两个不同的文件。
3. CSS 模块拆分与 flex 布局的公共样式边界
3.1 六张 CSS 文件的职责分工
压缩包里CSS文件的组织方式比HTML更有看头。没有把所有样式堆进一个style.css,而是拆成了header.css、footer.css、first.css、second.css、personal.css、photo.css,外加一个container.css。这个拆分策略本身就是一个值得学习的点:
| CSS 文件 | 职责范围 | 复用性 |
|---|---|---|
container.css | 定义内容容器宽度、居中方式、基础重置 | 所有页面复用 |
header.css | 顶部导航、Logo、菜单悬浮态 | 所有页面复用 |
footer.css | 页脚版权区、备案信息布局 | 所有页面复用 |
first.css | 首页专属组件,如欢迎横幅、文章卡片 | 仅首页使用 |
second.css | 二级内容页的列表、文案排版 | 仅内容页使用 |
personal.css | 个人介绍页的图文混排样式 | 仅个人页使用 |
photo.css | 相册网格布局、图片悬浮效果 | 仅相册页使用 |
逻辑说明:这个拆法相当于“公共组件样式 + 页面私有样式”的混合模式。header.css和footer.css负责站点级复用,first.css、photo.css这类只服务单一页面。好处是公共样式改一次全站生效,页面私有样式不会污染别处;代价是每个页面要手动引入多张CSS,请求数增加。
引入方式通常是每个页面都挂载公共部分:
<link rel="stylesheet" href="container.css"> <link rel="stylesheet" href="header.css"> <link rel="stylesheet" href="footer.css"> <link rel="stylesheet" href="photo.css">这里有个容易被忽略的细节:CSS的加载顺序决定了层叠优先级。container.css先声明容器的width,photo.css后声明.grid的grid-template-columns,因为选择器不同不会冲突;但如果两个文件里定义了同名的类,后加载的文件会覆盖先加载的。多人协作时,公共样式表最好约定放在页面私有样式表之前,避免私有样式被意外覆盖。
3.2 头部导航的 flex 布局与响应式边界
header.css要解决的核心问题是Logo和导航栏的横向排列。经典的实现方式是给.container或header外层设置display: flex:
.container { width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; height: 80px; } .navbar ul { display: flex; gap: 32px; list-style: none; } .navbar ul li a { font-size: 16px; color: #333; text-decoration: none; transition: color 0.3s ease; } .navbar ul li a:hover { color: #c9a063; }逻辑说明:外层.container用justify-content: space-between把Logo和导航分别推到左右两端,align-items: center保证二者垂直居中。导航内部的ul也用 flex 排列,gap: 32px控制菜单项间距,替代传统margin写法,避免首尾多余边距。
参数调整建议:
1200px是桌面端常见的内容宽度,改成960px则整体内容区收窄,更接近阅读型站点;height: 80px同时作用于容器,等于固定了页头高度,如果Logo图片更高,这里要同步调大;transition: color 0.3s ease只对颜色做过渡,速度0.3s是交互反馈比较舒服的中间值——太快则生硬,太慢则拖沓。
这段代码对应热搜里“css 鼠标移入事件”和“css伪类选择器怎么用”的检索意图:hover就是最常见的伪类,JS事件完全不需要。把这个办法记牢,绝大多数导航悬浮效果都靠它解决。
3.3 伪类选择器在个人站里的高性价比用法
个人网站最容易出彩的地方就在交互反馈。这个项目的CSS里大量使用了:hover,应用最集中的是首页的文章卡片和相册页的图片。这里示范一组典型的图片悬浮效果:
.photo-grid img { width: 100%; height: 250px; object-fit: cover; transition: transform 0.4s ease, box-shadow 0.4s ease; } .photo-grid img:hover { transform: scale(1.05); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); }逻辑说明:object-fit: cover保证图片在固定高度下不变形,多余部分裁掉,这在相册网格里是标准操作。transition同时作用于transform和box-shadow,让悬浮放大和阴影过渡保持同步。:hover本身不是事件,它直接映射元素的鼠标悬停状态,比JavaScript的mouseenter更轻量——不需要监听、不需要移除、刷新即生效。
参数含义:scale(1.05)是放大1.05倍,视觉上“轻轻浮起”的效果。想更明显可以调到1.08,但超过1.15就会有溢出感,要配合overflow: hidden控制容器边界。
3.4 用浏览器开发者工具反向阅读陌生 CSS
拿到别人写好的CSS,最有效的起步方式是在浏览器里读而不是在编辑器里读。用Chrome打开first.html,按 F12 打开开发者工具,点击左上角的选择器图标,再页面直接点想看的区块,右侧Styles面板会列出命中该元素的所有CSS规则,并且标注来源文件和行号:
# 伪代码演示,实际在浏览器DevTools中操作 选中导航栏 -> Styles 面板显示 header.css:24 的 .navbar ul li a 规则 勾选/去掉某条规则 -> 页面实时刷新,快速定位影响元素的关键属性逻辑说明:这种方式比通读源码效率高得多,尤其适合从零开始研究一份陌生模板。先锁定要改的目标元素,再看它当前被哪些规则影响,反向理清依赖关系。很多期末作业出问题,根源在于“改了CSS没生效”,用这个路径能立刻查清是被优先级更高的选择器覆盖,还是引入顺序不对。排查时优先看Computed面板,那里会告诉你最终生效的是哪一条规则。
4. 相册页 grid 布局与图片资源的组织策略
4.1 从图片素材反推栏目设计思路
这个压缩包里有五十多张图片,命名跨度从aespa、wanning、chenqingling到各类小说封面、古典纹样和育儿素材。这些命名透露出站点主人的真实兴趣标签。做个人网站的常规思路是先定栏目再找素材;反过来,也可以先把手头素材分类,再反推栏目结构。这个项目的栏目设计正是后一种思路的产物。
| 素材分组 | 栏目落位 | 视觉风格 |
|---|---|---|
小说1-4.jpg、文学1-4.jpg、古典1-4.jpg | 兴趣爱好页阅读分类 | 书籍封面,风格偏写实 |
winter1-2.jpg、aespa1-2.jpg、ning1.jpg | 相册页个人展示 | 照片类,色调偏冷 |
育儿1-4.jpg | 兴趣爱好页知识分区 | 插画风,颜色温和 |
hui1-2.jpg、blood1.png、peach.png | 首页装饰与品牌元素 | 纹理、图案类素材 |
逻辑说明:这些素材不是同一时期拍的,风格也不统一,但通过分散到不同页面、不同区块,降低了“素材打架”的感觉。个人站不需要追求全部素材风格统一,真正要做的是给每张图片一个明确的展示位置,让素材服务于内容,而不是单纯堆砌。
参数与设计要点:页面内图片的视觉权重排序也很关键。首页横幅位置用的是welcome.jpeg这类横向大图,适合铺满容器宽度;栏目预览卡片用的是小说1.jpg这类竖向封面图,适合卡在固定宽高比容器里;相册页则有横有竖,需要grid配合object-fit统一约束。
4.2 相册页 grid 响应式布局的参数细节
photo.html对应的photo.css是整份CSS里最值得细读的部分。相册页如果用手写浮动的传统写法,行高、间距都很难对齐。CSS Grid 在这个场景下的优势是天然对齐行列、控制间隙:
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; padding: 20px 0; } .photo-grid img { width: 100%; height: 220px; object-fit: cover; border-radius: 8px; transition: transform 0.3s ease, opacity 0.3s ease; } .photo-grid img:hover { transform: translateY(-6px); opacity: 0.9; }逻辑说明:repeat(auto-fill, minmax(240px, 1fr))是响应式网格的关键。浏览器计算出容器能放下多少个不小于240px的列,然后均分剩余空间。窗口缩小时列数自动减少,图片不会挤变形,也省去了写媒体查询的工作量。gap: 16px统一控制行列间距,比在每张图上设置margin干净得多。
参数调整建议:
240px是最小列宽。相册图偏小可以降到200px,偏大就提至260px,这决定了手机竖屏时一列还是两列;220px是图片固定高度,配合object-fit: cover,纵向大图会被裁掉上下边,横向大图则裁左右边——如果你更想保留图片的完整性,需要换成object-fit: contain并加背景色;translateY(-6px)是向上位移6像素,比scale更克制,适合大量图片并排时避免视觉拥挤。
4.3 五十张图片平铺根目录的隐患与重构方案
这个项目最大的工程化短板不是技术选型,而是资源管理。所有图片直接放在根目录,导致HTML文件和图片混在一起,目录可读性差。更严重的是图片没有经过压缩,welcome.jpeg、scenery.jpg这种大尺寸照片动辄几百KB,五张页面累计图片请求体积可能超过2MB。对期末作业来说无所谓,但放到线上访问就会明显拖慢加载。
重构方向是目录分组加批量压缩。目录结构从平铺改为按功能拆分:
project/ ├── index.html ├── pages/ │ ├── personal.html │ ├── hobby.html │ ├── photo.html │ └── second.html ├── css/ │ ├── container.css │ ├── header.css │ ├── footer.css │ ├── first.css │ ├── personal.css │ ├── photo.css │ └── second.css ├── images/ │ ├── banner/ # 横幅与背景大图 │ ├── books/ # 小说、文学、古典封面 │ ├── personal/ # 个人介绍相关 │ ├── gallery/ # 相册展示图 │ └── icons/ # logo、icon类小图逻辑说明:图片按功能拆分后,每个目录规模控制在十张以内,查找和替换成本大幅降低。对应的HTML引用路径同步改变:pages/photo.html里引用根目录图片要写成../images/gallery/winter1.jpg,CSS文件里引用图片同样基于CSS文件所在位置计算相对路径。
图片压缩用命令行工具最省事,以macOS/Linux环境为例:
# 批量压缩 jpg 图片,质量压缩到 80% find ./images -name "*.jpg" -exec sips -s format jpeg -s formatOptions 80 {} --out {} \; # 压缩前查看图片体积分布 du -sh ./images/* # 也可以用 npx 调用 sharp 做无损压缩(需要在有 Node 环境的机器上) npx sharp-cli -i ./images/gallery -o ./images/compressed --quality 80逻辑说明:sips是macOS自带工具,find遍历目录下所有jpg执行压缩,-s formatOptions 80表示质量80%,肉眼几乎无差别,体积可以减少一半以上。npx sharp-cli适合有Node环境的工程化流水线,它还会剥离图片的元数据信息,进一步缩小体积。压缩完成后用du对比前后体积,能直观看到优化收益。
5. 发布前的自检清单与轻量级工程化改造
作业交上去之前,或者把一个静态模板改造成可部署站点之前,按下面的清单过一遍,能规避百分之八十的常见问题。
第一项,目录结构改造成“可部署形态”。当前根目录没有index.html,需要把first.html重命名为index.html,或者新建一个空的index.html做301跳转。Nginx配置里指定默认首页也可以,但直接重命名最省事。改完后原来指向first.html的href都要同步成index.html,注意别漏掉header公共区里的导航链接。
第二项,跑一个本地静态服务器验证路径。直接双击HTML文件用的是file://协议,很多浏览器对本地文件访问有安全限制,且部分CSS特性在file://下表现与线上不一致。更稳妥的验证方式是起一个本地HTTP服务:
# Python 3 自带简易静态服务器 cd project python3 -m http.server 8080 # 浏览器访问 http://localhost:8080逻辑说明:http.server会把当前目录作为站点根目录,所有相对路径从根目录开始解析,和真实服务器行为一致。这时候再检查每张图片是否加载、每个页面跳转是否正常、CSS引入路径是否错位,得到的结论才有参考价值。Windows上没有Python的话,VSCode插件Live Server是同样的效果。
第三项,用浏览器开发者工具做最终的资源审查。打开Network面板,勾选Disable cache,刷新页面,看有没有红色的404请求。凡是标红的请求都说明路径写错了,这是静态站最常翻车的地方。接着在Console面板看有没有报错信息,DOCTYPE声明缺失或编码不一致会导致中文乱码。
第四项,给站点补齐基础的SEO标签。个人网站也需要被搜索引擎索引。每个页面的<title>要独立,不能全部叫“我的书屋”;meta description要写清楚当前页面的内容定位:
<title>首页 - 我的书屋 | 个人网站</title> <meta name="description" content="我的书屋个人网站首页,展示个人简介、最新动态与阅读推荐。"> <meta name="viewport" content="width=device-width, initial-scale=1.0">逻辑说明:title和description是搜索引擎展示搜索结果时最重要的字段。viewport标签让移动端浏览器按设备宽度渲染页面,没有这行标签时手机打开会像电脑页面缩小一样,文字小、点击区域错位,配合前面grid和flex的响应式设置,才算完成移动端适配。
第五项,把字体和颜色值收敛成CSS变量。个人网站规模不大,但多个CSS文件里反复出现同一个色值,改版时要全局搜索替换,容易遗漏。在container.css顶部定义自定义属性:
:root { --main-color: #c9a063; --text-color: #333333; --bg-color: #f7f4ef; --header-height: 80px; } .navbar ul li a:hover { color: var(--main-color); }逻辑说明::root选择器定义全局CSS变量,任何页面引入container.css后都能用var(--main-color)取到同一个值。想调整整体色调时只需要改文件顶部的定义一处,刷新全站生效。这是静态站点里投入产出比最高的一次重构。
至此,「我的书屋」从文件结构到CSS拆分策略、从grid相册布局到部署前改造都过了一遍。把highlight里提到的手法组合应用,例如用minmax配合object-fit做自适应相册,再结合CSS变量统一设计风格,这份期末作业的代码体量完全可以支撑起一个正式个人站点的前端骨架。现在可以把压缩包解压、起一个本地服务器,逐页改造着试试。
本文还有配套的精品资源,点击获取