搜索全站
主题 14 分钟阅读

WordPress 主题 AMP 与移动适配:样式、交互与验证要点

开启 AMP 后页面报错「CSS 超过 75000 字节」、轮播失效、表单提交没反应?本文讲清 AMP 的三种模式、主题要满足的样式与脚本约束,以及移动端适配里最容易漏掉的视口、图片与交互细节。

U
UFO_PF 2023-09-16 · 阅读 14 分钟
Wo 主题
阅读提示
本文约 5,318 字,预计阅读 14 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:移动端慢,不只是图片大的问题

国内做内容站,移动流量占比常年在七成以上。很多站长的第一反应是压缩图片、上缓存,这些都对,但还有一个更彻底的思路:让页面直接符合 AMP 规范,从而进入搜索引擎的 AMP 缓存、拿到移动端的额外展示机会。

但 AMP 不是「装个插件就完事」。它对 HTML、CSS、JS 的限制非常硬:不能用自定义 JavaScript、CSS 必须内联且有体积上限、图片必须写成 <amp-img>、表单要换成 <form amp-form>。一个为标准浏览器写的主题,开启 AMP 后大概率会出现一堆验证错误——轮播不动、菜单点不开、样式丢一半。搞懂限制再做适配,比事后一个个修错误省事得多。

原理分析:三种模式与限制清单

官方 AMP 插件(AMP for WordPress,由 Google 与 Automattic 团队维护)提供三种模式:

模式 说明 适配难度
Reader(阅读器) 单独的 AMP 版本,主题简单,与桌面版样式不同 低
Transitional(过渡) 同一套 URL,AMP 版用移动模板 中
Standard(标准) 整站就是 AMP,桌面移动同一份 HTML 高,但最一致

现在新站点建议直接上 Standard 模式——它要求主题本身合法,虽然前期改得多,但不存在「桌面版与移动版样式不一致」的长期维护负担。

AMP 的核心约束(主题必须遵守):

  • CSS:只能内联在 <style amp-custom> 里,总大小 75000 字节以内;禁止 !important(少数例外);不能引用外部样式表(自定义字体除外)。
  • JS:不能有自己的 JavaScript 文件;交互必须用 AMP 内置组件(amp-carousel、amp-accordion、amp-form、amp-sidebar)或 amp-script(有体积与作用域限制)。
  • 图片:<img> 必须替换为 <amp-img> 并显式给出 width/height;<iframe> 换成 <amp-iframe>。
  • 表单:需要引入 amp-form 组件,提交走 XHR,且必须处理成功/失败响应,否则控制台报错。
  • 菜单:移动端抽屉菜单用 <amp-sidebar> 实现,配 on="tap:sidebar.toggle" 之类的事件。

移动端适配则是另一条独立的主线:viewport 声明、响应式断点、srcset 响应式图片、触控目标尺寸(建议 ≥ 44px)、表单字号不小于 16px(否则 iOS 会自动放大页面)、避免横向滚动。

保姆级实操

第一步:装插件并选模式

wp plugin install amp --activate

后台「AMP → Settings」里选 Standard(标准)模式,保存后访问任意文章页,在 URL 后加 #development=1 打开开发者模式,浏览器控制台会列出所有验证错误。

第二步:确认 viewport 与响应式基础

add_action( 'after_setup_theme', 'mimangfei_setup' );

function mimangfei_setup() {
    add_theme_support( 'responsive-embeds' );
    add_theme_support( 'post-thumbnails' );
    add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script' ) );
}

头部必须有 viewport(主题里漏了会被 AMP 判为错误):

<meta name="viewport" content="width=device-width, initial-scale=1">

它由 WordPress 核心在 wp_head 里输出,前提是主题没有删掉 wp_head()。

第三步:把 CSS 收进 amp-custom 并控制体积

AMP 插件会自动收集已注册的样式内联进 <style amp-custom>,超限就报错。控制体积的做法:

add_action( 'wp_enqueue_scripts', 'mimangfei_lean_styles', 20 );

function mimangfei_lean_styles() {
    // 只在需要的地方加载组件样式,避免整站样式表过大
    if ( ! is_front_page() ) {
        wp_dequeue_style( 'mimangfei-home' );
    }
    if ( ! is_singular() ) {
        wp_dequeue_style( 'mimangfei-single' );
    }
}

再用构建工具裁剪(示例为 PostCSS 配置,配合 Tailwind 的 purge 也同理):

module.exports = {
    plugins: [
        require( 'cssnano' )( { preset: [ 'default', { discardComments: { removeAll: true } } ] } ),
    ],
};

第四步:图片改成 amp-img

AMP 插件默认会通过 sanitizer 自动把 <img> 转成 <amp-img>,但主题手写的背景图(CSS background-image)不会被转换,也不会报错,只是移动端可能模糊。图片输出统一走核心函数:

the_post_thumbnail( 'medium_large', array(
    'class' => 'entry-thumb',
    'loading' => 'lazy',
) );

核心会自动输出 srcset 与 sizes,移动端不必下载大图。不要在模板里手写 <img src="...">,那样既没有响应式属性,也可能绕过 sanitizer。

第五步:移动端抽屉菜单用 amp-sidebar

add_action( 'wp_footer', 'mimangfei_amp_sidebar' );

function mimangfei_amp_sidebar() {
    ?>
    <amp-sidebar id="mf-sidebar" layout="nodisplay" side="right">
        <button aria-label="关闭菜单" on="tap:mf-sidebar.close">×</button>
        <nav>
            <?php
            wp_nav_menu( array(
                'theme_location' => 'primary',
                'container'      => false,
                'items_wrap'     => '<ul>%3$s</ul>',
            ) );
            ?>
        </nav>
    </amp-sidebar>
    <button class="menu-toggle" aria-label="打开菜单" on="tap:mf-sidebar.toggle">菜单</button>
    <?php
}

注意 AMP 的 on 属性写法:on="tap:mf-sidebar.toggle",不带 javascript:。同时给按钮加 aria-label,兼顾可访问性(见 主题可访问性基础)。

第六步:表单(含评论、搜索)适配

add_action( 'wp_enqueue_scripts', 'mimangfei_amp_form_component' );

function mimangfei_amp_form_component() {
    if ( function_exists( 'amp_is_request' ) && amp_is_request() ) {
        wp_enqueue_script(
            'amp-form',
            'https://cdn.ampproject.org/v0/amp-form-0.1.js',
            array(),
            null,
            false
        );
    }
}

更简单的做法是让 AMP 插件自动注入组件(插件会根据内容中出现的 amp-form 自动加载)。提交后需要返回 JSON 并在模板里渲染 submit-success / submit-error 模板,否则用户点了没反馈。搜索表单建议直接降级为 GET 跳转到非 AMP 搜索页,实现成本最低。

第七步:验证与排错

# 用官方 CLI 校验单个 URL
npx amphtml-validator https://example.com/sample-post/

或者在浏览器打开 https://example.com/sample-post/#development=1,控制台会逐条列出错误,常见如 The attribute 'onclick' may not appear in tag 'button'、CSS exceeds 75000 bytes。

常见踩坑

  1. 主题里引了 jQuery 轮播:AMP 下脚本被剥离,轮播变静态图,需要换成 amp-carousel。
  2. !important 满天飞:验证报 The !important qualifier is not allowed,改用更高优先级选择器。
  3. CSS 超限:整站一个大 style.css 塞进 amp-custom,超限后 AMP 直接判无效,页面被搜索引擎排除在 AMP 索引之外。
  4. 第三方统计代码失效:AMP 要用 <amp-analytics>,普通 GA 代码无效;百度统计同理需要专用配置。
  5. 表单提交没反应:未引入 amp-form 或未写 submit-success 模板,用户以为站点坏了。
  6. 案例:某资讯站开启 AMP 后,移动端文章页的「相关阅读」模块整块消失。排查发现该模块是用 jQuery 的 .load() 异步拉取的,AMP 环境下脚本被移除且 HTML 无任何降级内容。修复方案是改 PHP 直接输出,并加上 amp-state 无关的简单列表,同时给桌面版保留原逻辑。
  7. iOS 表单放大:输入框 font-size 小于 16px 时 iOS 会自动缩放页面,移动端样式规则里统一给 input, textarea, select 设 font-size: 16px。
  8. 横向滚动:width: 100vw 在移动端会包含滚动条宽度导致溢出,改用 width: 100%;长英文串要加 overflow-wrap: break-word。

总结

判断要不要上 AMP:内容型站点(资讯、博客、文档)收益明显;交互型站点(商城、社区、工具)收益有限而改造成本极高,建议优先做移动端性能优化(响应式图片、按需加载、字体子集化)而不是强上 AMP。若决定上,动手顺序是:先 Standard 模式跑通文章页 → 修 CSS 体积与脚本 → 补 amp-sidebar 与表单 → 全流程 #development=1 验证。移动端适配与 AMP 之外的常规优化并不冲突,两者结合才能把 LCP 压下来;主题的底子是否扎实,还要回到 主题上线前自检 那套检查上。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。