Files
xuanheng-website/README.md
T
dsh f81d41c5ca 初始化:炫恒网络官网(五个页面)
站点:纯静态 HTML + CSS + 原生 JS,零框架零构建
页面:首页 / 合作品牌 / 荣誉资质 / 客户案例 / 关于我们

内容:
- site/          站点本体(含已压缩 webp 图片,约 4.8 MB)
- deploy/        Docker Compose / Caddy / Apache 部署配置
- _tools/        开发自检脚本与部署脚本
- Dockerfile     自建 nginx 镜像方案
- README.md      项目文档

设计:品牌黄 #ffc107 + 白,深蓝仅用于页脚;菜单长期置顶;
      交互动效只加在关键词与区块级元素上。

素材说明:原始素材(背景图/老网站/方案/荣誉资质/合作品牌,约 290 MB)
         未纳入版本控制,站点使用的是 site/assets 内已处理压缩的图片。
2026-10-13 16:12:41 +08:00

14 KiB
Raw Blame History

上海炫恒网络系统有限公司 · 官方网站

企业官网静态站点,五个页面:首页 / 合作品牌 / 荣誉资质 / 客户案例 / 关于我们。 纯 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

然后访问 http://localhost:8080


项目结构

.
├── 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 编码(不要用会改编码的编辑器设置)。

换首屏大图

  1. 把新图放到 site/assets/img/hero/hero-1.webp(或改 site/index.html 里 hero__bg 那行的路径)
  2. 首屏还会用到 hero-1@2x.webp(高分屏 2 倍图),可以一起换

加合作品牌

首页品牌条是 4 列网格,每个卡片里放一张 logo:

<div class="marquee__item"><img src="assets/img/brands/新品牌.webp" alt="品牌名" loading="lazy"></div>

注意两点(踩过坑):

  1. 不要给 logo 加 width / height 属性,也不要让 JS 去写内联像素尺寸。 logo 由 CSS 用「固定高度 + 宽度自动」统管(height: 56px; width: auto; max-width: 100%), 这样所有 logo 视觉高度一致、宽度按各自比例、不会被拉伸变形。 一旦写了像素尺寸,CSS 的 max-width 会失效,宽 logo 会撑出卡片被裁切。

  2. 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

未验证(重要)

  1. 容器没有真正跑起来过。 开发这个站点的环境里没有安装 Docker,所以 docker compose up 我无法执行。 Dockerfile / compose / nginx 配置都是按标准写法编写的,静态检查过, 但首次启动请留意 docker compose logs 有没有报错。

    docker compose up -d --build
    docker compose logs -f
    docker compose ps          # 确认 STATUS 是 healthy
    
  2. 浏览器渲染没有截图确认过。 同一环境的沙箱会拦截 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、锐捷) 版权归各自公司所有,仅用于说明合作关系。