移动适配师(Mobile Fit)用于扫描并修复既有 Web 项目中的移动端适配问题,覆盖视口配置、溢出防护、安全区处理、响应式断点、100vh 陷阱、触控目标以及多级页面导航。
适用场景
将桌面优先的站点改造为在移动端良好可用;用户反馈手机上出现溢出、内容被裁切或刘海遮挡;为基于侧边栏的布局添加移动端导航(返回按钮、页面栈);修复 iOS/Android 浏览器上的 100vh 问题;以及一般性的“让它更适合移动端”的请求。
工作流程(强制按顺序执行)
运行辅助脚本前,需从已安装的技能上下文中解析 SKILL_DIR。若手动执行,则将其设置为包含本 SKILL.md 的目录。
第 1 步:扫描项目
运行扫描器以识别问题:
python3 "$SKILL_DIR/scripts/scan_mobile_issues.py" <project-path>
若需 JSON 输出(更便于程序化处理):
python3 "$SKILL_DIR/scripts/scan_mobile_issues.py" <project-path> --format json
查看输出。扫描器会检查:viewport meta 标签是否存在以及 viewport-fit=cover;CSS 溢出风险(固定宽度、min-width);100vh 使用(应改为 100dvh);固定/粘性元素上的 safe-area-inset 使用;触控目标尺寸(< 44px);响应式断点覆盖;Tailwind 特有问题(h-screen → h-dvh);文本溢出是否缺少省略号处理。
第 2 步:询问用户
重要:在做任何修改之前,使用 AskUserQuestion 收集范围。先呈现扫描结果摘要,然后询问:
问题:“扫描发现 X 个问题。要修哪些类别?” 选项:
- 全部修复(推荐)—— 修复发现的所有类别
- 只修布局和溢出 —— 仅 overflow 与响应式
- 只修导航 —— 改造为移动端页面栈导航
- 让我选具体类别 —— 挑选指定类别
若项目在桌面端存在侧边栏/tab 导航,还需询问:
问题:“桌面端的侧边栏/tab 导航要改成移动端多级页面吗?” 选项:
- 是,改成 push/pop 页面栈(推荐)
- 改成底部 tab bar
- 不改导航结构
第 3 步:修复问题
按以下优先级顺序应用修复:
- Viewport meta —— 添加或修正 <meta name="viewport">,包含 viewport-fit=cover
- 全局溢出防护 —— 为 html/body 添加 overflow-x: hidden
- 100vh → 100dvh —— 替换所有 100vh 用法,并添加回退
- 安全区内边距 —— 为固定/粘性元素添加 env(safe-area-inset-*)
- 图片/媒体溢出 —— 添加 max-width: 100%; height: auto
- 文本溢出 —— 在存在 white-space: nowrap 处添加省略号/line-clamp
- 触控目标 —— 增大低于 44px 的可交互元素
- 响应式断点 —— 添加移动优先媒体查询或 Tailwind 响应式类
- 导航重构 —— 若用户要求,则改造为移动端页面栈
每项修复请参照 references/mobile-patterns.md 中的正确模式。
第 4 步:导航重构(如适用)
将侧边栏/面板导航转换为移动端页面栈时:识别导航结构(侧边栏、tab、嵌套面板);创建在桌面与移动端之间切换的响应式布局包装;在移动端渲染为带返回按钮的全屏页面栈;使用 CSS 滑动过渡实现页面的 push/pop;在 md: 断点及以上保持桌面布局不变。各框架的实现模式见 references/mobile-patterns.md 的“Multi-Level Page Navigation”部分。
第 5 步:验证
完成所有修复后:重新运行扫描器,确认问题已解决;在移动视口(375px 宽)下检查站点;验证是否存在横向滚动、内容是否被刘海或 home indicator 裁切、所有可交互元素是否可点按(44px+)、导航返回按钮是否可用、全高布局是否不会溢出到浏览器工具栏之后。
CLI 参考
参数 project(必填):Web 项目根目录路径。参数 --format(默认 text):输出格式,text 或 json。
关键模式(快速参考)
缺少 viewport meta:<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 100vh 溢出:height: 100dvh(带回退 100vh) 刘海遮挡:在固定元素上使用 padding: env(safe-area-inset-top) 横向溢出:body 上 overflow-x: hidden,媒体上 max-width: 100% iOS 输入缩放:输入框 font-size: 16px 触控目标过小:min-height: 44px; min-width: 44px 下拉刷新冲突:overscroll-behavior-y: contain
详细模式见 references/mobile-patterns.md。
运行时上下文(共享)
运行前读取本 Skill 包的 skill.yaml,由宿主提供 skill-runtime/v1 上下文。字段解析顺序为:当前请求、项目上下文、个人 Preferences、品牌 Profile、通用默认值。只使用 Manifest 声明的字段;Profile 保存公开品牌事实,Preferences 保存个人工作偏好。required: true 字段缺失时,按 Manifest 的问题配置向用户提出一个聚焦问题;用户明确同意后再保存回答。报错提供可复制的 context_id、字段路径与来源,诊断内容避开秘密、完整私人路径和原始配置。
通用反馈闭环
用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行:先判断意见是 task-specific(仅本次)还是 reusable(可跨任务复用)。task-specific 只修改当前任务,不改 Skill。reusable 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。reusable 修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。