本文约 3,703 字,预计阅读 10 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:断点抄了一套,真机上还是有横向滚动条
按 768px / 992px / 1200px 三档写完主题,Chrome 设备模拟器里看着挺好,真机一打开就出问题:iPhone 14 是 390px 宽,iPad mini 竖屏是 744px,某些 Android 机的浏览器可视区只有 360px 不到。更常见的是「平板横屏 1024px 卡在两档之间」,既不是手机布局也不是桌面布局,侧边栏挤成一条。
国内设备宽度分布和国外教程里的假设并不一致。按 Bootstrap 的默认断点照抄,最容易踩的就是 768px 这一档——它把 iPad 竖屏(768px)判成了「桌面」,于是 iPad 用户看到的是三栏桌面布局被压扁后的样子。本文给出一套更贴合国内设备的断点建议,并说明什么时候根本不该用断点。
原理分析:断点该由内容决定,而不是由设备决定
响应式设计的经典原则是「内容断点」:布局在哪个宽度开始变得难看,就在那里加断点。实践中为了方便,通常取主流设备的宽度作为参考值,但要留余量。
| 名称 | 建议断点 | 对应设备 |
|---|---|---|
| 小屏手机 | ≤ 374px | iPhone SE (375) 以下、老 Android |
| 标准手机 | 375–413px | iPhone 14/15 (390/393)、多数 Android (412) |
| 大屏手机 | 414–539px | iPhone Pro Max (430)、折叠屏外屏 |
| 平板竖屏 | 540–767px | iPad mini (744)、折叠屏展开 |
| 平板横屏 | 768–1023px | iPad 竖屏 768、iPad Air 820 |
| 小笔记本 | 1024–1279px | iPad Pro 横屏 1024、1366 缩窗 |
| 桌面 | ≥ 1280px | 1440、1920 主流显示器 |
注意 iPad 竖屏正好是 768px 这个尴尬值。如果断点写成 @media (min-width: 768px),iPad 竖屏会命中桌面布局;写成 max-width: 767.98px 则命中手机布局,两者都不理想。解决办法是在 768–1023 单独给一档平板布局,或者干脆把断点设在 900px 这种设备之间的空隙上。
现代 CSS 还有更好的选择:clamp() 让字号和间距在上下限之间连续变化,min() / max() 处理宽度,grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) 让列数自适应而不需要断点,容器查询 @container 则让组件根据自身宽度而非视口宽度响应。这些手段能大幅减少断点数量。
保姆级实操
- 定断点变量:用 CSS 自定义属性或在 SCSS 里定义
$bp-*变量,全站统一引用,避免各处硬编码数字。 - 移动优先:基础样式写手机,再用
min-width逐档增强,这样老设备拿到的是最简单的布局。 - 避开设备边界值:断点取 600 / 900 / 1200 这类「设备之间」的数字,而不是 768 / 1024 这种正好命中设备的数字。
- 优先用无断点方案:能用
auto-fit + minmax的列,就别写三段 media query。 - 字号用 clamp:标题字号随视口连续变化,省掉多档覆盖。
- 服务端判断只在必要时用:
wp_is_mobile()依赖 User-Agent,会被页面缓存污染,慎用。
// 断点变量:取设备之间的空隙值,避开 768/1024 这类边界
$bp-sm: 600px;
$bp-md: 900px;
$bp-lg: 1200px;
$bp-xl: 1600px;
@mixin from($bp) {
@media (min-width: $bp) { @content; }
}
.site-main {
padding: 16px;
@include from($bp-md) {
display: grid;
grid-template-columns: minmax(0, 1fr) 300px;
gap: 32px;
padding: 32px;
}
}
.widget-area {
@include from($bp-md) {
position: sticky;
top: 32px;
}
}
/* 无断点的自适应列 + clamp 字号,大幅减少 media query 数量 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: clamp(12px, 2vw, 24px);
}
.entry-title {
font-size: clamp(1.375rem, 1rem + 2vw, 2.25rem);
line-height: 1.25;
}
/* 容器查询:侧边栏组件根据自身宽度响应,而非视口 */
.widget {
container-type: inline-size;
}
@container (min-width: 320px) {
.widget__list {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
<?php
// 服务端判断仅用于「输出不同 HTML」的场景,不要用于纯样式
add_action( 'template_redirect', 'mimangfei_mobile_body_class' );
function mimangfei_mobile_body_class() {
if ( wp_is_mobile() ) {
add_filter( 'body_class', function( $classes ) {
$classes[] = 'is-mobile-ua';
return $classes;
} );
}
}
常见踩坑
- 断点写
min-width: 768px命中 iPad 竖屏:iPad 竖屏视口正好 768,会拿到桌面三栏布局。用 900px 作为平板到桌面的分界更安全。 - 混用
min-width和max-width导致覆盖冲突:两种方向混着写,后加载的规则会覆盖前面的,调试极其痛苦。统一用移动优先的min-width。 - 案例:某主题在每个组件文件里各写各的断点,一共 17 个不同的像素值。改版时想统一改成 900px,结果改完侧边栏在 899px 时消失,因为有个组件用的是 899.98px。最后把所有断点收进 SCSS 变量文件,全站引用变量,问题一次性解决。教训:断点必须集中定义,禁止散落硬编码。
wp_is_mobile()被缓存污染:页面缓存按 URL 存一份 HTML,手机用户命中桌面缓存后会拿到桌面版。这个函数只适合决定「输出不同结构」,不适合做样式切换;有全页缓存时干脆别用。- 忘写 viewport meta:
<meta name="viewport" content="width=device-width, initial-scale=1">缺失时,手机浏览器会按 980px 虚拟视口渲染,所有 media query 全部失效。 - 横向滚动条:某个元素写了固定宽度 400px,在 360px 屏上撑出滚动条。用
max-width: 100%和minmax(0, 1fr)修复 grid 子项溢出。 - 断点过多维护不动:超过 5 档断点的主题基本没人能改得动。三档(手机 / 平板 / 桌面)配合 clamp 和容器查询,通常就够了。
- 忽略高 DPI 与横屏:横屏时高度骤减,fixed 头部可能吃掉一半屏幕。用
@media (max-height: 480px)单独处理矮视口。
总结
断点的判断标准是:你的布局在哪个宽度开始变难看,就在那里断,而不是「某某设备是多少 px」。行动清单:把断点集中成变量 → 取值避开 768/1024 这类设备边界 → 基础样式移动优先 → 能用 auto-fit、clamp()、容器查询的就不写 media query → 加 viewport meta → 真机(至少一台 iPhone 和一台 Android)实测而非只信模拟器。合理设置断点后,可以再去处理 主题广告位与 CLS 布局偏移控制,因为广告容器的响应式尺寸同样依赖这套断点。
