网站始终响应式
一个页面只有在通过 python3 scripts/check_responsive.py 检查后才算完成(无水平滚动,无内容超出屏幕,触控目标足够大),该脚本会在六个参考尺寸上运行。此检查也会在 CI 中执行:破坏响应式的 PR 无法部署。
参考宽度(需全部测试)
| 宽度 | 用例 |
|---|---|
| 320 px | 小屏 Android、iPhone SE 放大模式 |
| 375 px | 标准 iPhone(目标受众主要来自 TikTok) |
| 414 px | 大屏手机 |
| 768 px | 平板竖屏 |
| 1024 px | 平板横屏 / 小笔记本电脑 |
| 1440 px | 桌面端 |
脚本测试的尺寸:320×640、375×667、414×896、768×1024、1024×600(低屏)、1440×900。
CSS 规则
- 移动优先:基础样式针对 320 px,然后用
@media (min-width: …)扩展。断点:600px、900px、1200px(其他地方不应使用魔数;组件可以使用@container)。 - 无固定宽度超过 280 px 而不使用
min()/max-width: 100%:例如width: min(520px, 100%)。 - 流畅排版使用
clamp():标题clamp(32px, 7vw, 72px),正文最低 16 px(移动端不得低于此值,否则 iOS 会放大输入框)。 - 高度:使用
min-height: 100svh(不要用100vh,它在移动端会被地址栏遮挡)。文本块上绝不使用固定height。 - 侧边距:移动端留 16 px 间距(
space-4),加上env(safe-area-inset-left/right)适配刘海屏(viewport 已设置viewport-fit=cover)。 - 长文本:URL、命令和文件名使用
overflow-wrap: anywhere;代码块使用overflow-x: auto仅限于块内部,绝不作用于页面。 - 网格:教程卡片使用
grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr))。 - 装饰元素(
byte/spark块、canvas)可能溢出时:使用position: fixed或父级设置overflow: clip,尺寸使用min(vw, px)。 - 触控:独立的按钮和链接至少 44 × 44 px(脚本最低要求 24 px,符合 WCAG 2.2),两个目标之间至少间隔 8 px。不应有仅通过悬停(
:hover)提供的信息:必须考虑:focus-visible和触控状态。 - 视频和 iframe(YouTube):
aspect-ratio: 16 / 9; width: 100%; height: auto;— TikTok 视频使用9 / 16并设置max-width: 360px。
图片
- HTML 中始终指定
width和height(避免布局偏移 CLS)+ CSS 中设置max-width: 100%; height: auto。 - 格式:Logo 和图标使用 SVG,截图使用 WebP/AVIF,并配合
srcset+sizes(例如 480w、960w、1600w)。 - 首屏以下图片使用
loading="lazy"和decoding="async";绝不用于 LCP 主图,主图应使用fetchpriority="high"。 - 教程缩略图:
aspect-ratio: 16 / 9; object-fit: cover。
Viewport(已设置,不要移除)
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
禁止使用:maximum-scale=1、user-scalable=no(阻止缩放,不利于无障碍)。
动画与移动端性能
- 尊重
prefers-reduced-motion(项目规则)。 - Canvas:限制
devicePixelRatio为 2,并在 600 px 以下降低密度(已在app.js中实现,保持此原则)。 - 移动端避免使用叠加的重
backdrop-filter。
验证
# 使用已启动的 check-site 容器(:8088),或不带参数启动本地服务器(site/)
python3 scripts/check_responsive.py # 检查 site/ 下所有页面
python3 scripts/check_responsive.py --shots /tmp/rs # 额外按宽度截取 PNG 截图
脚本会在以下情况失败:scrollWidth > 宽度、可见元素超出边缘、触控目标小于 24 px(句子中的链接豁免)或正文小于 16 px。推送前请查看 320 和 375 px 的截图。