
简介面向大学生毕业设计的花店购物网站纯静态源码以div分区和层叠样式表为核心完成30个页面的布局涵盖商品展示、购物车、登录注册、商品列表、收藏与加购等电商基础流程适合前端初学者上手练习或作为毕设选题参考。资源包共140个文件压缩包仅2.62MB主要包含网页文档、样式文件、交互脚本以及大量图片素材图片用于商品展示与页面装饰样式与脚本分工明确目录结构清晰便于按页面模块查阅和二次修改。已有3297人学习下载说明这套素材在同类毕设资源中具有一定参考价值。整体风格清新适合花卉类商品展示页面模块划分清晰能在课程答辩或作品集中直接呈现完整前端实现也可在静态页基础上继续扩展支付、后台管理等动态功能帮助开发者建立电商网站前端组织与布局的整体认知。1. 纯静态花店网站毕设30 页源码要怎么撑起来花店购物网站这类毕业设计题目不算新鲜但恰好是这种「看起来不新颖」的题最容易翻车页面一多很多人就进入复制粘贴模式——首页写得很认真到第 15 页样式开始错乱第 25 页的时候一个背景图路径就让整站崩了一半。html 网页纯静态、divcss、页面预计 30 页这几个关键词放在一起真正考的不是「会不会写 div」而是「能不能在没有框架、没有后端的情况下把 30 个页面的结构、样式和链接组织成一套可见可控的文件系统」。这对答辩来说是件好事老师打开 index.html 就能演示没有环境依赖没有 npm install也正因为没有框架兜底你必须亲手处理导航复用、相对路径、样式冲突这些真实工程问题。下面按我带毕设时走的流程来先规划页面与目录再定 div 骨架和 css 参数接着批量复制出 30 页最后用脚本验证链接、补交互细节保证演示现场不炸。2. 30 页静态站点怎么做页面规划与目录结构2.1 页面清单先压缩成 6 套模板不要一页页硬写纯静态站没有模板引擎可以用但页面结构本身是有规律的。花店站的页面基本逃不出这几类首页、商品列表页按玫瑰、永生花、绿植、礼盒拆分、商品详情页、关于我们/配送说明等品牌页、购物车与结算页、登录注册页。把这 6 类骨架各做一套套上不同内容就能铺满 30 页。页面组复用骨架建议页数每页内容特点首页首页骨架1轮播图、主推花束、配送说明入口商品列表列表骨架810按分类拆分每页 812 张商品卡片商品详情详情骨架1012大图区、花语介绍、价格与加购按钮品牌辅助通用内容骨架46关于我们、配送政策、花语百科、售后服务流程交易流程骨架23购物车、结算页只做静态跳转演示促销专题促销页骨架12节日活动页样式可以做得最花哨这样拆的另一个理由是工作量分布均匀。老师抽查导航里任意一个链接点过去都该落在一个完整页面而不是「该商品详情页开发中」的占位符。把 30 页视为 6 套骨架的内容变体之后剩下的工作就是替换文字、图片和局部模块这比一页一页从头写省下至少一半时间。2.2 目录结构30 页能不能跑通全看这一层写静态多页站点最容易忽略的是一开始就没定目录。等页面数量上了 20images、css和页面文件混在同一个文件夹里相对路径很快就会乱掉。我一般建议按下述结构组织flower-shop/ ├── index.html ├── list/ │ ├── roses.html │ ├── preserved.html │ └── gift-box.html ├── detail/ │ ├── rose-001.html │ ├── rose-002.html │ └── preserved-001.html ├── about/ │ ├── us.html │ └── delivery.html ├── cart/ │ ├── cart.html │ └── checkout.html ├── css/ │ ├── reset.css │ ├── common.css │ └── pages/ │ ├── list.css │ └── detail.css ├── js/ │ └── common.js └── images/ ├── banners/ ├── products/ └── icons/这里的关键是「页面按功能分目录资源统一放根级目录」。index.html引用图片用images/products/rose-001.jpg即可list/下的页面要退一级写成../images/detail/下两层深写成../../images/。这个规则要在复制第一页之前就想明白不然后面 20 个详情页的图片全得返工。文件名统一小写加中划线商品编号从 001 递增。Rose-001.HTML这种写法在 Linux 部署时会把链接打断虽然毕设多半在 Windows 上演示但源码评审时这个细节很加分。2.3 div 分层的正确姿势语义化分区不写内联样式div 在纯静态页面里的价值是「分层」把页面切成 header、nav、main、footer 这些区块再在区块里继续切卡片、标签、价格行。html 网页制作里常说的 div 图层指的就是这种垂直堆叠与局部浮动的组合关系。常见误用是全部div classbox1、div classbox2或者干脆给每个 div 写stylemargin-top: 10px这会让 30 个页面里的同一类区块长得不一样。我的建议是布局类 div 用结构语义命名site-header、product-grid内容类 div 用业务语义命名flower-price、add-to-cart并且所有颜色、间距、宽度都收进 css 统一管理。这样「将计 30 页」的源码文件里绝大部分页面都是「换汤不换药」地重用同一套公共样式答辩时老师问「这么多页面你怎么维护的」这句话就是答案。3. divcss 的核心布局与关键样式参数3.1 公共页面骨架一个 header 管住 30 页的导航先把公共骨架固定下来。下面这段 html 是花店站每个页面都复用的「壳」我通常把它作为新页面的起点!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 meta namedescription content花店鲜花在线选购网站玫瑰、永生花、绿植礼盒 title在线花店/title link relstylesheet href../css/reset.css link relstylesheet href../css/common.css /head body div classsite-header div classcontainer nav-bar div classlogo a href../index.htmlimg src../images/icons/logo.png alt花店首页/a /div ul classnav-list lia href../index.html classactive首页/a/li lia href../list/roses.html玫瑰/a/li lia href../list/preserved.html永生花/a/li lia href../about/us.html关于我们/a/li lia href../cart/cart.html购物车/a/li /ul /div /div div classsite-main !-- 每页的内容区从这里开始 -- /div div classsite-footer div classcontainer p© 2024 Flower Shop 在线花店 · 配送说明 · 隐私政策/p /div /div /body /html这段骨架的引用路径是给list/下的页面准备的所以 css 和图片都用了../首页和detail/下的页面要对应调整成无前缀或../../。header 和 main 之间不要用绝对定位互相覆盖如果详情页需要「价格标签浮在图片上」这类效果才在局部模块里设置position: relative的父容器和position: absolute的子元素这就是 div 图层的典型用法避免一上来就在骨架层做定位。3.2 主样式里那组必调的参数宽度、间距、断点公共样式common.css里我会先写几组全局变量和基础容器规则:root { --max-width: 1200px; --gap: 20px; --radius: 10px; --primary: #c24b4b; --text-main: #333; --text-light: #999; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: PingFang SC, Microsoft YaHei, sans-serif; color: var(--text-main); background: #fff; } .container { max-width: var(--max-width); margin: 0 auto; padding: 0 var(--gap); } .product-grid { display: flex; flex-wrap: wrap; gap: var(--gap); } .product-grid .product-card { width: calc((100% - 60px) / 4); } media (max-width: 768px) { .product-grid .product-card { width: calc((100% - 20px) / 2); } }参数的选择理由如下表这组参数也是答辩时老师常追问的地方参数建议值理由页面容器宽度1200px15.6 寸笔记本浏览器全屏时不出现横向滚动条商品卡片列数4 列桌面 / 2 列平板一行 4 个卡片图片、标题、价格层次清楚栅格间距20px与卡片内边距一致视觉对齐最省事圆角10px812px 范围内都有精致感过大会让卡片显「玩具感」价格主色偏红深色花店调性也符合打折信息的高亮需求css 伪类选择器怎么用在这套页面里非常具体:hover控制卡片浮起:focus保证键盘用户能看到焦点:nth-child可以单独处理每行最后一个卡片的对齐。比如卡片浮起效果不用 JS只用两行 css.product-card:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0,0,0,.08); }。很多人管这叫「css 鼠标移入事件」严格说它只是视觉反馈真正的逻辑事件还得交给 JS这个区别后面第 4.4 节还会提到。3.3 商品卡片组件图片、名称、价格、按钮怎么摆得整齐有了栅格之后单个商品卡片的结构要固定下来30 页里所有列表页和详情页都靠它撑场面div classproduct-card a href../detail/rose-001.html div classcard-img img src../images/products/rose-001.jpg alt红色玫瑰鲜花束 span classcard-tag热卖/span /div div classcard-body h3 classcard-title红玫瑰鲜花束 19 枝/h3 p classcard-desc厄瓜多尔玫瑰 · 含包装 · 当日送达/p div classcard-price span classprice-now¥199/span span classprice-origin¥299/span /div div classcard-btn加入购物车/div /div /a /div.product-card { background: #fff; border: 1px solid #f0e8e8; border-radius: var(--radius); overflow: hidden; transition: transform .2s ease, box-shadow .2s ease; } .product-card:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0, 0, 0, .08); } .card-img { position: relative; } .card-img img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; } .card-tag { position: absolute; top: 10px; left: 10px; background: #c24b4b; color: #fff; font-size: 12px; padding: 2px 8px; border-radius: 4px; } .card-body { padding: 14px; } .card-title { font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-price { display: flex; align-items: baseline; gap: 8px; margin: 8px 0; } .price-now { color: #c24b4b; font-size: 20px; font-weight: 600; } .price-origin { color: #999; font-size: 14px; text-decoration: line-through; } .card-btn { text-align: center; padding: 10px 0; background: #faf5f0; color: #c24b4b; border-radius: 6px; font-size: 14px; }这段 css 里有两个值得在答辩时主动讲两句话的点。第一text-decoration: line-through就是 css 删除线的标准写法用来表达原价¥299已经被划掉配合price-now的高饱和度颜色形成价格对比第二card-tag的圆角标签用position: absolute浮在图片左上角如果你想让标签带「优惠券」的锯齿感常见做法是用background: radial-gradient(circle at left, transparent 10px, #c24b4b 11px)在左侧抠出一个半圆缺口这就是 css 优惠券圆切的思路。aspect-ratio: 1 / 1让所有商品图统一成正方形object-fit: cover保证图片裁切后不变形这两个属性组合起来解决 90% 的商品图对齐问题。4. 30 页源码的落地复制、链接检查与交互点缀4.1 复制出 30 页之后先修这三个 bug页面批量复制后最容易出现的是三个问题而它们恰好都是静态站点特有的。第一是相对路径错位list/roses.html里图片要写../images/xxx.jpg但直接从首页代码复制过来时往往还留着images/xxx.jpg浏览器解析时就会去找list/images/xxx.jpg。第二是title没改30 个页面全部叫「在线花店」浏览器标签页无法区分搜索引擎收录时也会判成重复页面。第三是「返回链接死循环」详情页互跳时写出了detail/rose-002.html但从list/页面点过去没有前置../结果拼成list/detail/rose-002.html。排查时我一般直接在项目根目录执行grep -rn images/products list/ detail/ | grep -v ../images这个命令把list/和detail/下所有不带../前缀的图片引用都揪出来凡是命中的行就是写错路径的地方。它不执行任何修改只负责定位改的时候在 VS Code 里用「在文件间替换」批量加前缀。4.2 用 python 脚本把 30 页里的死链全部扫出来手点 30 个页面再点 30 次链接不现实我习惯在交源码前跑一段小脚本这也正好呼应「源码」这个关键词——用源码去检查源码。import os import re from urllib.parse import unquote root os.path.abspath(.) pages [] for dirpath, _, files in os.walk(root): for f in files: if f.endswith((.html, .htm)): pages.append(os.path.join(dirpath, f)) bad_links [] for page in pages: base os.path.dirname(page) with open(page, encodingutf-8) as fp: content fp.read() for ref in re.findall(r(?:href|src)([^#]), content): if ref.startswith((http, mailto, javascript, tel:)): continue clean unquote(ref.split(?)[0]) if not clean: continue target os.path.normpath(os.path.join(base, clean)) if not os.path.exists(target): bad_links.append((os.path.relpath(page), clean)) for page, ref in bad_links: print(f{page} - {ref}) if not bad_links: print(OK: 所有 html 内链与资源路径均可访问)脚本的逻辑分三段。第一段用os.walk(root)把项目里所有.html文件收集进pages列表考虑到了多级子目录的情况第二段逐个打开页面用正则抓出href和src的属性值跳过外链、邮件、JS 调用第三段是核心——以当前页面所在目录为基准os.path.join(base, clean)拼出目标路径再用os.path.normpath标准化掉../和./最终判断文件是否存在。注意一个小坑页面编码必须统一。默认按utf-8读取如果某个页面曾经被其他编辑器存成了 GBKopen会直接抛UnicodeDecodeError。这种情况我一般先查哪些文件编码不一致统一转成 UTF-8 再跑脚本不要在脚本里静默吞掉异常不然漏检了编码非法的页面反而更麻烦。4.3 页脚版权批量替换与 html 一键返回顶部算法30 个页面的页脚如果还是「复制后手改年份」最后一刻才发现有一半页面写着去年的版权体验会很尴尬。批量替换不需要什么高级工具VS Code 的「在文件中替换」就能一次改完也可以用 python 跑一个三行级的小循环遍历.html文件把固定字符串替换掉。替换前后注意缩进和换行是否一致别把页脚里的版权符号©弄丢。多数花店静态站的页脚还会放一个「返回顶部」入口。很多人直接给a标签写href#点击后页面会带#跳到顶部但 URL 会多出个锚点连续点两次还会出现奇怪的跳动。一个更干净的 html 一键返回顶部算法是用 JS 控制滚动距离button idbackTop onclickbackTop() styleposition:fixed;right:20px;bottom:20px;z-index:999;返回顶部/button script function backTop() { function step() { var cur document.documentElement.scrollTop || document.body.scrollTop; if (cur 0) { document.documentElement.scrollTop document.body.scrollTop cur - Math.ceil(cur / 8); requestAnimationFrame(step); } } step(); } /script这段代码不是瞬间跳回顶部而是每次把当前滚动距离减掉剩余的八分之一形成「先快后慢」的缓动效果requestAnimationFrame保证每一帧只执行一次滚动调整比setInterval省资源。第一次写的人往往卡在document.documentElement.scrollTop和document.body.scrollTop二选一上——不同浏览器滚动的宿主节点不一样所以赋值时两个属性同时写读的时候两个都取再判断这是兼容老浏览器的稳妥写法。4.4 用 divulli 模拟下拉筛选css 鼠标移入事件和 JS 怎么分工列表页通常要提供「按价格排序」「按花材筛选」功能。原生select在跨浏览器下的样式不一致而且很难完全融入花店的视觉风格所以静态站里更常见的做法是用 div 模拟下拉框外层一个div classselect触发区一个div.select-trigger选项列表用ulli组合。div classfilter-select idpriceFilter div classselect-trigger按价格排序/div ul classselect-list li>.filter-select { position: relative; display: inline-block; } .select-list { display: none; position: absolute; top: 100%; left: 0; background: #fff; border: 1px solid #eee; border-radius: 6px; list-style: none; padding: 6px 0; min-width: 120px; } .filter-select:hover .select-list, .select-list.open { display: block; }这里特意保留了.filter-select:hover .select-list在桌面端鼠标移入触发区就展开面板这就是 css 鼠标移入事件在该场景的落点但:hover是伪类而非事件触屏设备上鼠标不存在所以同一处还要允许select-list.open类展开由 JS 在点击触发区时动态添加open类。两种机制并存既不依赖复杂的 JS 判断又能覆盖移动端。JS 部分只用两个监听就够了document.getElementById(priceFilter).addEventListener(click, function (e) { var list this.querySelector(.select-list); if (e.target.tagName LI) { document.querySelector(.select-trigger).textContent e.target.textContent; list.classList.remove(open); } else { list.classList.toggle(open); } }); document.addEventListener(click, function (e) { var box document.getElementById(priceFilter); if (!box.contains(e.target)) { box.querySelector(.select-list).classList.remove(open); } });第一个监听负责「点了选项就更新触发区文字并收起面板」第二个监听负责「点面板外面任意位置就收起」。值得留意的是这种非原生下拉框没法用自动化工具里的 Select 类直接定位比如 Selenium 的Select对象是给select用的遇到 divulli 组合时只能先 click 触发区再 click 目标 li这是静态站交互里很容易被问到的细节。答辩时能说出这句分工比背诵框架概念更有说服力。5. 答辩前能自查的验收清单与四个加分细节5.1 十分钟跑完的静态站验收清单检查项操作方法通过标准链接完整性运行 4.2 节的 python 脚本输出OK0 个坏路径横向滚动浏览器缩放到 80%、100%、125% 各看一遍页面无横向滚动条编码显示随机打开首页、1 个列表页、1 个详情页中文、价格符号显示正常控制台报错F12 打开 Console刷新全部页面无红色 error图片缺页逐个切换商品列表页无破图、无变形标题唯一性grep -r title .查看输出30 个 title 互不相同移动端表现DevTools 模拟 iPhone 12 宽度卡片从 4 列变 2 列不溢出这组检查里最重要的是链接完整性和控制台报错它们是演示现场最容易当场出丑的两类问题移动端表现则决定了老师如果顺手用手机打开网页时页面是否还能见人。5.2 四个答辩加分细节第一个加分细节是给index.html补全meta namedescription并给每张商品图写alt文本。尺寸虽小但老师一眼就能分辨你是把页面当工程做还是当作业糊弄。第二个细节是确保购物车与结算页形成交互闭环购物车页的「去结算」按钮必须真能跳到checkout.html结算表单至少加required校验静态站不要求真的提交订单但跳转链路不能断。第三个建议是把所有商品图放在本地images/products/下不要用网上临时图片链接离线环境下演示才能不受网络波动干扰。第四个细节是在 div 区块之间写!-- 头部开始 --、!-- 商品卡片区域 --这类注释保持 30 个页面里的注释位置一致老师抽查任意一个页面都会看到结构完全对齐的源码风格。把这套清单跑完给每个分类的报价改成真实参考价30 页静态花店网站能打开、能跳转、能筛选、能结算源代码目录干净答辩演示的底气自然就有了。本文还有配套的精品资源点击获取