Community编程与开发github.com

移动端适配

当用户希望将网站、应用、界面、流程、仪表板或完整项目适配为手机或移动网页,或提及响应式/移动优先/iPhone/iOS Safari/触摸/安全区域/横屏/键盘问题时使用。也适用于移动端审计、移动端回归测试、小屏幕布局修复、底部导航重新设计、表单/表格/图表适配,或iPhone特定可用性工作。

移动端适配 是什么?

移动端适配技能专门用于将现有界面优化为在手机上正常使用,同时保留核心功能。它优先针对iPhone Pro Max级别的设备及iOS Safari浏览器,并默认以375-440 CSS像素宽度的紧凑触摸屏为目标。该技能提供了一套全面的规则,包括保持紧凑手机为单列布局、使用底部导航、确保交互目标至少为44x44 CSS像素、不依赖悬停、避免水平页面滚动、正确处理安全区域和动态视口单位,以及优化键盘交互。此外,它还包含对导航、列表、表单、表格、图表和统计数据进行具体审计的检查清单,并提供跨多种设备和场景的详细验证步骤,包括横竖屏、安全区域、键盘打开状态、大文本、减少运动和空状态。该技能强调在真实设备上进行测试,以充分模拟触摸精度和键盘时序。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/s0up4200/skills/tree/HEAD/skills/mobile-adapt

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

移动端适配 是做什么的?

目标

将现有界面适配为在手机上良好运行,同时不移除核心功能。除非用户指定其他目标,否则优先针对 iPhone 级别的移动网页进行优化。

默认目标

如果用户未指定设备或浏览器,则首先针对以下环境进行优化:

  • iPhone Pro Max 级别,竖屏和横屏
  • iOS Safari
  • 紧凑型触摸屏,宽度约 375-440 CSS px
  • 键盘打开状态、大文本、安全区域和减少运动

何时进行研究

此技能依赖于当前平台行为。

  • 当用户要求了解最新/当前指南、iPhone 特定行为、Safari/WebKit 怪癖、安全区域行为、PWA/主屏幕行为或直接引用时,请查阅官方来源。
  • 首选 Apple Developer、WebKit、W3C/WCAG、MDN、Android Developers 和 web.dev。
  • 在引用最近的平台更改时,应使用绝对日期。

有关当前高信号规则和来源,请阅读 references/mobile-ui-2026.md。

核心规则

  • 保持紧凑型手机为单列布局。 不要仅仅因为横屏手机跨越了通用断点就切换为桌面信息架构。旋转侧放的手机仍然是用双手在臂展距离握持的——用户的思维模型是“手机”,而不是“平板”。拆分为多列布局会产生令人困惑的体验,导致没有任何内容足够大,难以舒适使用。

  • 仅对真正的一级部分使用底部优先的移动导航。 将其限制在 3-5 个主要目的地;将溢出项移入 更多、一个弹出面板或次要流程。屏幕底部是拇指的自然休息区——将主要导航放在那里意味着最常见的操作只需最少的努力。超过 5 个项会缩小触控目标至可用尺寸以下,并让用户难以扫描。

  • 每个交互目标在两个维度上都应至少为 44x44 CSS px。 这包括容易被忽略的次要元素:内联操作按钮(编辑、删除、查看)、展开/折叠切换开关、筛选标签、工具栏中的图标按钮、弹出面板上的关闭按钮以及复选框/单选按钮行(使用 <label> 作为完整触控目标,而不仅仅是输入本身)。电容式触摸屏在约 44pt 处注册手指接触区域的中心——较小的目标会导致误触挫折感,尤其是在运动中。常见的 Tailwind 类不足的示例:h-8 (32px)、h-9 (36px)、在图标上使用 p-1 (~24px)、p-1.5 (~28px)、p-2 (~32px)。使用 h-11 (44px)、min-h-[44px] 或等效值作为每个可点击元素的基准。这与 Apple HIG 一致,并超过了 WCAG 2.2 的 24px 最低要求。

  • 不要依赖悬停、小图标点击或隐藏的行操作。 触摸设备上没有悬停状态——任何需要悬停才能发现的内容都是不可见的。使用可见的控件、带有视觉提示的滑动操作或上下文弹出面板/菜单。

  • 避免水平页面滚动。 单手手机使用是垂直拇指滚动。水平滚动破坏了用户的空间模型,并将内容隐藏在屏幕外,没有可见的提示。应重新流式排列、堆叠、分页或本地滚动表格和图表,而不是整个页面。

  • 使用 viewport-fit=cover、env(safe-area-inset-*) 和 min-height: 100dvh。 现代 iPhone 具有圆角、灵动岛和主页指示器——所有这些都会侵占矩形视口。没有明确的安全区域处理,内容会被硬件控件区域遮挡。dvh 考虑到了旧版 vh 未能处理的 Safari 折叠工具栏。

  • 使主要操作远离浏览器栏、主页指示器、圆角和屏幕键盘。 隐藏在键盘后面或与主页指示器重叠的“提交”按钮在功能上是损坏的——用户要么看不到它,要么无法在不触发系统手势的情况下点击它。

  • 对于表单密集或键盘密集的流程,优先使用一个主滚动容器。 iOS Safari 上的嵌套滚动区域会产生滚动陷阱:用户的手指滚动内部容器时,原本意图滚动页面,反之亦然。WebKit 在此处存在持续的错误(请参阅参考文件)。仅在没有其他选择时才使用嵌套滚动。

  • 使用语义化的移动输入。 标签位于字段上方(而不是旁边——没有水平空间)、正确的 type、inputmode、autocomplete 和 enterkeyhint。这些属性控制显示哪个键盘——inputmode="decimal" 为货币显示数字键盘,enterkeyhint="next" 允许用户在不关闭键盘的情况下在表单中跳转。

  • 将大文本视为真正的布局输入。 iOS 用户可以设置系统范围的大文本,许多人确实如此。应进行换行和重新流式排列——不要将关键含义隐藏在截断之后。如果截断的标签让用户猜测他们看到的是“储蓄账户”还是“工资账户”,布局就失败了。

  • 在手机上,图表辅助叙述;它们不是叙述的全部。 手机屏幕可能只能渲染大约 5-6 个可读的条形或一个甜甜圈。这不足以让图表自解释。首先显示关键数字和文本摘要;将图表用作视觉强化。

  • 保留产品的现有品牌和设计系统,除非用户要求进行更广泛的重新设计。移动端适配是关于布局和交互,而不是换肤。

示例

在更改导航外壳、数据表或带有提交按钮的表单之前,请阅读 references/mobile-examples.md。其中包含侧边栏变为底部标签栏、表格变为手机上的卡片列表以及提交按钮保持在键盘上方的表单的 before/after 代码。

工作流程

  1. 锁定目标上下文。
    • 设备、浏览器、方向、使用上下文
    • 如果未指定,默认使用 iPhone Pro Max + iOS Safari
  2. 首先审计外壳。
    • 导航模式
    • 安全区域
    • 粘性/固定栏
    • 横屏行为
    • 键盘行为
  3. 审计每个屏幕或组件。
    • 列表和行
    • 表单
    • 表格
    • 图表
    • 空/错误/加载状态
  4. 选择硬切换点。
    • 哪些变为单列
    • 哪些变为卡片
    • 哪些移入弹出面板/抽屉
    • 哪些在“更多”下变为次要内容
  5. 实施移动优先适配。
    • 组件内部优先使用容器查询
    • 外壳/布局模式更改优先使用视口查询
    • 除非明确要求,否则不要保留旧的半桌面/半移动行为
  6. 在紧凑型竖屏和紧凑型横屏上验证。
    • 首先验证 Safari/WebKit
    • 然后验证 Chromium
  7. 首先报告最高风险的问题,然后报告具体更改和任何遗留的差距。

屏幕检查清单

外壳和导航

  • 保持横屏手机处于手机外壳模式。
  • 避免对仍然是手机的设备进行硬性 md => 桌面侧边栏 切换。
  • 使用 env(safe-area-inset-bottom) 为底部 UI 添加内边距。
  • 使粘性操作位于底部导航上方。
  • 保持移动端标签简短。

列表和行

  • 允许标题、元数据和金额在需要时换行成两行。
  • 为价格、余额和总计保留稳定空间。
  • 优先使用堆叠的元数据而非压缩的内联元数据。
  • 使用可见控件或弹出面板/菜单来暴露操作,而不是悬停。
  • 将行操作按钮(编辑、删除、查看、展开)的尺寸至少设为 44x44 CSS px——不仅仅是主要导航和工具栏按钮。

表单

  • 在紧凑型手机上使用单列。
  • 使提交按钮保持在键盘上方可见。
  • 使用清晰的全宽主要行动号召按钮。
  • 将长流程分解为步骤或渐进式披露。
  • 如果格式化或精度很重要,避免使用 type="number" 来处理货币。

表格和导入/审核流程

  • 在手机上,将密集的可编辑表格转换为卡片/列表。
  • 如果必须保留真正的表格,请将水平滚动限制在表格内部。
  • 确保粘性标题和工具栏不会遮挡焦点输入框。

图表和统计数据

  • 首先显示关键数字和简短叙述。
  • 添加紧凑的图例和文本后备。
  • 优先使用水平滚动或分页比较,而不是不可读的密集条形图。
  • 避免在紧凑屏幕上使用小甜甜圈图。

验证

对于下面的每个检查项,确认具体的通过条件并使用建议的工具。真实设备测试是黄金标准——模拟器对于迭代很有用,但无法完全重现键盘时序、滚动惯性或触摸精度。

  • 竖屏和横屏——手机在两种方向上都保持移动外壳模式。没有布局损坏、内容溢出,也不会突然切换到桌面侧边栏或多列视图。在 375px(iPhone SE/mini 级别)、390px(iPhone Pro)和 430px(iPhone Pro Max)竖屏及其对应的横屏下测试。使用 Chrome DevTools 设备工具栏或 Xcode Simulator。

  • iOS Safari 安全区域——内容不会被灵动岛、圆角或主页指示器剪裁。底部固定元素具有可见的 env(safe-area-inset-bottom) 内边距(在 Face ID iPhone 上约为 34px)。验证视口元标记中是否设置了 viewport-fit=cover——如果没有设置,所有 env(safe-area-inset-*) 值都将返回 0。最好在 Xcode Simulator(准确的每设备内边距)或 Polypane 26+(具有真实安全区域内边距预设的桌面浏览器)中测试。Chrome DevTools 135+ 支持 Emulation.setSafeAreaInsetsOverride,但需要手动配置。

  • 键盘打开的表单流程——按顺序聚焦每个输入并验证:(1) 焦点字段滚动到视图中,(2) 提交操作可见且可点击,(3) 粘性标题不会遮挡焦点字段。请注意,position: fixed; bottom: 0 元素会隐藏在 iOS 键盘后面(布局视口不会缩小),并且 position: sticky; bottom: 0 在键盘显示期间也无法固定(WebKit bug #202120)。Playwright 和 Cypress 无法触发真实的屏幕键盘——这需要真实设备测试或带有 Safari Web Inspector 的 Xcode Simulator。

  • 大文本/显示缩放——WCAG 1.4.4 (AA) 要求文本可调整到 200% 而不丢失内容。WCAG 1.4.10 (AA) 要求在 400% 缩放(相当于 320px 宽的视口)下重新流式排列,而不会出现水平滚动。测试方法:(1) 将浏览器缩放设置为 200% 并验证没有截断或重叠,(2) 将视口设置为 1280px 并放大至 400% 以模拟 320px 重新流式排列要求,(3) 启用 iOS 设置 > 辅助功能 > 显示与文字大小 > 更大字体至最大。验证视口元标记未设置 user-scalable=no 或 maximum-scale 低于 2.0。

  • 减少运动——动画尊重 prefers-reduced-motion: reduce。过渡仍然传达状态变化,但使用交叉淡入淡出或不透明度而不是运动。iOS Safari 在开启“减少运动”时不会自动抑制 Web 动画——开发者必须自行处理。通过以下方式测试:Chrome DevTools 渲染选项卡 > “模拟 prefers-reduced-motion”、Safari Web Inspector 偏好覆盖(自 2022 年末起可用)或 Playwright 的 page.emulateMedia({ reducedMotion: 'reduce' })。

  • 空/错误/加载状态——这些状态在紧凑屏幕上正确渲染。加载骨架匹配移动布局,而不是桌面布局。错误消息无需滚动即可阅读。

  • 独立/PWA 模式(相关时)——如果应用支持 display: standalone,请验证状态栏区域、主页指示器和手势区域是否已处理。svh 和 dvh 在独立模式下解析为相同的值,因为没有可折叠的工具栏(WebKit bug #261185)。WebKit bug #254868 可能导致错误的高度值。WebKit bug #265578 导致当 Safari UI 动画回到视图时,视觉视口高度更新延迟。

  • 没有水平文档滚动——在页面主体上左右滑动不会产生任何移动。任何水平滚动都隔离到特定容器(表格、轮播),具有可见的溢出提示和 overscroll-behavior: contain,以防止触发 Safari UI 偏移(WebKit bug #240861)。对于 Playwright 中的自动验证:

    const hasOverflow = await page.evaluate(() =>
      document.documentElement.scrollWidth > document.documentElement.clientWidth
    );
    expect(hasOverflow).toBe(false);
    

交付物

使用此技能时,应生成:

  • 一个简短的移动端适配计划
  • 首先列出最高风险的问题
  • 具体的每屏幕更改
  • 已执行的验证
  • 任何剩余的设备/浏览器不确定性

相关技能