站点:纯静态 HTML + CSS + 原生 JS,零框架零构建
页面:首页 / 合作品牌 / 荣誉资质 / 客户案例 / 关于我们
内容:
- site/ 站点本体(含已压缩 webp 图片,约 4.8 MB)
- deploy/ Docker Compose / Caddy / Apache 部署配置
- _tools/ 开发自检脚本与部署脚本
- Dockerfile 自建 nginx 镜像方案
- README.md 项目文档
设计:品牌黄 #ffc107 + 白,深蓝仅用于页脚;菜单长期置顶;
交互动效只加在关键词与区块级元素上。
素材说明:原始素材(背景图/老网站/方案/荣誉资质/合作品牌,约 290 MB)
未纳入版本控制,站点使用的是 site/assets 内已处理压缩的图片。
14 KiB
上海炫恒网络系统有限公司 · 官方网站
企业官网静态站点,五个页面:首页 / 合作品牌 / 荣誉资质 / 客户案例 / 关于我们。 纯 HTML + CSS + 原生 JavaScript,零框架、零依赖、零构建步骤,用 Docker + Nginx 一条命令上线。
目录
快速开始
方式一:Docker Compose(推荐,用于正式部署)
前置条件:装好 Docker(含 Compose 插件,Docker Desktop 或 Docker Engine 20.10+ 都行)。
# 在项目根目录执行
docker compose up -d --build
启动后打开 http://localhost:8080
常用命令:
docker compose logs -f # 看实时日志
docker compose ps # 看容器与健康状态
docker compose down # 停止并删除容器
docker compose up -d --build --force-recreate # 改完内容后重新构建
换端口:默认宿主机 8080。想用 80 端口,在项目根目录建一个 .env 文件:
SITE_PORT=80
或者直接改 docker-compose.yml 里 ports 的左边数字("8080:80" → "80:80")。
方式二:本地直接打开(改样式时最方便)
页面之间全部是同级相对路径,双击 site/index.html 就能看,五个页面也能互相跳转。
方式三:本地起一个静态服务器
# 有 Python
python -m http.server 8080 --directory site
# 有 Node
npx serve site
项目结构
.
├── Dockerfile 生产镜像(nginx:1.27-alpine,约 30 MB)
├── docker-compose.yml Compose 编排(端口 / 健康检查 / 日志轮转)
├── .dockerignore 构建上下文排除清单
├── nginx/
│ └── default.conf Nginx 站点配置(伪静态 / 缓存 / gzip / 安全头)
├── deploy/
│ └── apache/
│ └── htaccess.txt 改用 Apache 时的配置(重命名为 .htaccess 使用)
│
├── site/ ★ 站点本体,整个目录就是网站根目录
│ ├── index.html 首页
│ ├── brands.html 合作品牌
│ ├── honors.html 荣誉资质
│ ├── cases.html 客户案例
│ ├── about.html 关于我们
│ ├── favicon.ico
│ └── assets/
│ ├── css/main.css 全部样式(设计系统,单文件)
│ ├── js/main.js 全部交互(原生 JS,无依赖)
│ ├── lqip.css 图片模糊占位(构建时自动生成)
│ └── img/ 全部图片(webp 压缩)
│ ├── hero/ 首屏大图、深色背景
│ ├── brands/ 合作品牌 logo(已做尺寸归一化)
│ ├── solutions/ 行业方案封面
│ ├── cases/ 客户案例图
│ ├── honors/ 荣誉证书(含 person/ 个人认证)
│ └── misc/ Logo 与 favicon
│
├── _tools/ 开发自检脚本(不参与构建、不部署)
└── (素材目录) 合作品牌/ 方案/ 荣誉资质/ 背景图/ 老网站/
站点设计上刻意做成「同级相对路径」:所有页面都在同一层,页面之间引用
brands.html、 资源引用assets/...。这样双击能开、放子目录能开、换域名能开,不会出现 「本地能看、传上去 404」的问题。
部署方式
1. Docker Compose(本文主要支持)
见上方快速开始。镜像构建时会做一次自检:五个页面和入口资源缺任何一个,构建直接失败,
不会把半成品推上线。容器内置健康检查(访问 /healthz)。
2. 任意静态托管
把 site/ 目录里的全部内容上传到网站根目录即可(Nginx、Apache、Caddy、
对象存储、CDN 都行),不需要 Node、不需要构建。
- Nginx:可参考
nginx/default.conf里的伪静态与缓存规则 - Apache:把
deploy/apache/htaccess.txt重命名为.htaccess放到根目录 - 腾讯云 / 阿里云 OSS + CDN:直接传文件,缓存规则设「HTML 不缓存、img/css/js 长缓存」
3. 关于「不带 .html 的网址」
直接访问 https://你的域名/brands.html 永远是通的。想用
https://你的域名/brands 这种更干净的地址,需要服务器支持伪静态:
- 本项目的 Nginx 配置里已经写好了(
try_files $uri $uri.html $uri/index.html) - Apache 用
htaccess.txt里的 rewrite 规则
页面与素材对照
| 页面 | 文件 | 主要素材来源 |
|---|---|---|
| 首页 | site/index.html |
背景图/轮播/lunbo01(2).png(首屏)、方案/*.png(行业卡)、合作品牌/*.png(品牌条)、老网站 案例图 |
| 合作品牌 | site/brands.html |
合作品牌/ 下 8 个 logo(锐捷、思科、华三、Microsoft、vmware、citrix、juniper、radware) |
| 荣誉资质 | site/honors.html |
荣誉资质/ 9 张公司证书 + 老网站 assets/img/about/2/ 20 张个人认证 |
| 客户案例 | site/cases.html |
老网站 assets/img/solution-details/ 各行业案例图 + 成功案例-吾悦架构图.png |
| 关于我们 | site/about.html |
老网站 about.html / itt.html 的文本 |
文字内容来自老网站的真实文案(企业简介、2004–2022 发展历程、五大行业案例描述、 服务宗旨与「标准·诚实·负责·尊重·快速」价值观、联系方式),老网站模板里的 英文占位文案(BizMax、lorem 等)已全部剔除。
设计规范
配色(黄 + 白,深蓝只用于文字与页脚)
| 用途 | 变量 | 色值 |
|---|---|---|
| 主黄(按钮 / 强调) | --y-500 |
#ffc61a |
| 亮黄(渐变起点) | --y-400 |
#ffd656 |
| 浅黄底(标签 / 图标底) | --y-100 |
#fff9e6 |
| 深金(黄色系文字) | --y-700 |
#92620a |
| 标题文字 | --ink-900 |
#0f1c31 |
| 正文文字 | --text-2 |
#4e5e76 |
| 浅灰底 | --bg-alt |
#f7f9fc |
| 暖白底 | --bg-warm |
#fffdf7 |
深色只出现在页脚(#0a1526)与少量渐变遮罩上,其余全部白底 / 浅底,整体明亮。
尺寸与节奏
- 内容最大宽度
1320px,栅格间距clamp()随视口缩放 - 区块上下留白
clamp(60px, 6.4vw, 100px) - 圆角:小
8px/ 中14px/ 大18px/ 特大26px - 缓动统一
cubic-bezier(.22,.61,.36,1)(舒适不弹跳),按钮用轻回弹
字体
不请求外部字体(避免国内加载慢与备案风险),使用系统字体栈:
HarmonyOS Sans SC → MiSans → PingFang SC → Microsoft YaHei UI → …
交互与动效
设计原则:只有关键词和区块整体有动效,重复的卡片不逐个动画。
| 位置 | 效果 |
|---|---|
| 页头 | 长期置顶(position: fixed)。滚动后变白底毛玻璃 + 高度收窄,始终可见、不会自动隐藏 |
| 首屏标题 | 逐行从下方升起 |
| 首屏「数字未来」 | 黄色高亮条从左展开 |
| 首屏数据面板 | 进入视口后数字滚动计数 |
| 首屏背景 | 滚动时 0.12 倍速视差(固定单图,无轮播) |
| 区块进场 | 只在整个区块/标题层做淡入上移 |
| 按钮 | 悬停上浮 2px + 黄色渐变自下填充 |
| 卡片 | 悬停上浮 6px + 描边转黄 + 底部黄线展开 |
| 品牌 logo | 默认原厂彩色,悬停轻微放大 1.06 倍 |
| 案例筛选 | 淡出缩小的交错过渡 |
| 证书 | 点击开灯箱,支持 ← → 翻页、Esc 关闭 |
已适配 prefers-reduced-motion(系统开启「减少动态效果」时全部动画关闭)与打印样式。
如何改内容
改文字
直接编辑 site/*.html。注意:文件必须存为 UTF-8 编码(不要用会改编码的编辑器设置)。
换首屏大图
- 把新图放到
site/assets/img/hero/hero-1.webp(或改site/index.html里hero__bg那行的路径) - 首屏还会用到
hero-1@2x.webp(高分屏 2 倍图),可以一起换
加合作品牌
首页品牌条是 4 列网格,每个卡片里放一张 logo:
<div class="marquee__item"><img src="assets/img/brands/新品牌.webp" alt="品牌名" loading="lazy"></div>
注意两点(踩过坑):
-
不要给 logo 加
width/height属性,也不要让 JS 去写内联像素尺寸。 logo 由 CSS 用「固定高度 + 宽度自动」统管(height: 56px; width: auto; max-width: 100%), 这样所有 logo 视觉高度一致、宽度按各自比例、不会被拉伸变形。 一旦写了像素尺寸,CSS 的max-width会失效,宽 logo 会撑出卡片被裁切。 -
logo 源图要先裁掉透明留白。厂商 logo 原图常带很大留白(实测锐捷上下各留 153px), 不裁的话进卡片会显得又小又偏。归一化脚本:
python _tools/build_brands_v2.py
品牌页(brands.html)的品牌墙用同一套 .marquee__item 样式,加一张卡片即可。
品牌相关文案已刻意不写数量(首页是「携手全球一线 IT 厂商」、品牌页是「核心合作品牌」), 后续增删品牌不需要改文案。
换 Logo / favicon
XH-logo.png 是品牌标识源文件,处理脚本 _tools/build_assets.py 会生成
site/assets/img/misc/logo-256.png 与 site/favicon.ico。
表单对接后端
site/about.html 的「客户留言」目前是前端校验 + 成功提示,不发请求。
要真正收件,把 <form> 改成:
<form class="form" data-validate action="https://你的表单服务地址" method="POST">
并删掉 site/assets/js/main.js 里 initForms() 中的 e.preventDefault(),
或在提交成功后自行 form.submit()。
自检工具
_tools/ 里的脚本用于开发期验证,不参与构建:
| 脚本 | 作用 |
|---|---|
check.js |
资源引用、站内链接、锚点、标签配对、图标名合法性 |
check_html.py |
HTML 嵌套合法性、alt/lang/外链 rel、h1 唯一性 |
final_check.py |
编码、相对路径、导航互达、资源存在性、模板文案残留(最全面,建议每次改完都跑) |
test-js.js + domshim.js |
在 Node 里用最小 DOM 仿真跑 main.js,验证 64 项交互逻辑 |
audit-css.js |
HTML 用到的 class 是否都有 CSS 定义 |
build_assets.py |
从原始素材生成站点图片、LQIP 占位、favicon |
build_brands_v2.py |
品牌 logo 尺寸归一化 |
build_assets_v2.py |
首屏图与行业方案图处理 |
prune-images.js / prune-css.js |
清理未引用的图片与 CSS 规则 |
运行示例:
python _tools/final_check.py # 综合检查
python _tools/check_html.py # HTML 结构
node _tools/test-js.js # 交互逻辑(64 项断言)
node _tools/audit-css.js # class 覆盖
已验证 / 未验证
诚实说明当前状态,避免上线踩坑。
已验证
| 项目 | 结果 |
|---|---|
| HTML 结构(嵌套、alt、lang、外链 rel) | 5 个页面全部通过 |
| 编码(UTF-8、无 BOM、无乱码) | 5 个页面干净 |
路径(无根绝对路径、无 ../)与导航互达 |
全部通过 |
| 图片资源存在性 | 75 个引用全部存在 |
| 交互逻辑断言 | 64 项通过 / 0 失败 |
| HTML ↔ CSS class 覆盖 | 无缺失 |
| CSS 语法(括号配对) | 通过 |
| 静态服务器实测五个页面 | 全部 200 |
未验证(重要)
-
容器没有真正跑起来过。 开发这个站点的环境里没有安装 Docker,所以
docker compose up我无法执行。 Dockerfile / compose / nginx 配置都是按标准写法编写的,静态检查过, 但首次启动请留意docker compose logs有没有报错。docker compose up -d --build docker compose logs -f docker compose ps # 确认 STATUS 是 healthy -
浏览器渲染没有截图确认过。 同一环境的沙箱会拦截 Chrome 的进程间通信(mojo IPC),无法启动浏览器, 所以视觉效果(间距、对齐、logo 大小)都是靠代码与几何计算保证的, 请你在浏览器里过一遍。
常见问题
Q:docker compose up 报端口被占用?
改 .env 里的 SITE_PORT,或改 docker-compose.yml 的 ports 左边数字。
Q:改了内容但页面没变?
镜像里的文件是构建时 COPY 进去的,需要重新构建:
docker compose up -d --build。
另外 Nginx 配置里 HTML 是 no-cache,所以浏览器不会缓存旧页面,刷新即可。
Q:想用 80 端口直接对外的域名?
SITE_PORT=80。正式环境建议前面再挂一层带 HTTPS 的反向代理
(Nginx / Caddy / 宝塔 / 云负载均衡),本容器只监听 80。
Q:可以直接把 site/ 丢到虚拟主机吗?
可以,这是最省事的方式,不需要 Docker。
Q:为什么图片都是 .webp?
体积比 jpg/png 小很多(首屏大图 1920px 宽只有约 82 KB)。所有现代浏览器都支持
(Chrome / Edge / Firefox / Safari 14+)。
Q:表单提交给谁了? 没有发给任何人,目前只做前端校验。要真正收件见上面「表单对接后端」。
版权
站点图文仅用于上海炫恒网络系统有限公司企业形象展示。 第三方厂商名称与标识(Cisco、Microsoft、VMware、Citrix、H3C、Juniper、Radware、锐捷) 版权归各自公司所有,仅用于说明合作关系。