4、媒体查询进阶:移动优先与桌面优先策略、组合查询、常用断点库

媒体查询这东西,很多人觉得就是写几个 @media 完事。但实际项目里,断点怎么定、查询怎么写、优先策略怎么选,处处都是坑。今天我把这几年踩过的坑和总结的经验,一次性说清楚。

4.1 两种策略:移动优先 vs 桌面优先

先问个问题:你的页面是先写手机版,还是先写电脑版?

这决定了你用 min-width 还是 max-width。说白了,就是从小屏往上写,还是从大屏往下写。

移动优先(Mobile First)

我个人习惯用移动优先。原因很简单:手机用户多,而且从小屏往大屏写,逻辑更顺。

/* 基础样式:手机端 */
.container {
    display: flex;
    flex-direction: column;
    padding: 16px;
}

/* 平板及以上 */
@media (min-width: 768px) {
    .container {
        flex-direction: row;
        padding: 24px;
    }
}

/* 桌面 */
@media (min-width: 1024px) {
    .container {
        max-width: 1200px;
        margin: 0 auto;
    }
}

你看,默认就是手机样式,然后一层层往上加。这样写出来的 CSS,基础样式就是移动端的,不会出现「手机端要覆盖桌面端样式」的尴尬。

桌面优先(Desktop First)

有些项目,比如后台管理系统、数据大屏,用户基本都在大屏上操作。这时候桌面优先更合理。

/* 基础样式:桌面端 */
.dashboard {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}

/* 平板 */
@media (max-width: 1024px) {
    .dashboard {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* 手机 */
@media (max-width: 768px) {
    .dashboard {
        grid-template-columns: 1fr;
    }
}

嗯,这里要注意:桌面优先用的是 max-width,意思是「小于这个宽度时生效」。所以写的时候要从大往小写,否则后面的规则会覆盖前面的。

对比项 移动优先 桌面优先
关键词 min-width max-width
默认样式 手机端 桌面端
适用场景 面向消费者的网站 后台、大屏、工具类
代码量 通常更少 需要更多覆盖
维护难度 低 中
我的建议:新项目默认用移动优先。除非你确定 80% 以上的用户都在桌面端,否则别选桌面优先。我曾经在一个电商项目里用了桌面优先,结果手机端样式改了三轮才搞定。

4.2 组合查询:不只是宽度

很多人以为媒体查询只能查屏幕宽度。其实它能查的东西多着呢。

逻辑运算符

/* and:同时满足 */
@media (min-width: 768px) and (max-width: 1024px) {
    /* 平板竖屏 */
}

/* or(用逗号):满足其一 */
@media (max-width: 480px), (orientation: landscape) {
    /* 小屏手机 或 横屏 */
}

/* not:排除 */
@media not all and (pointer: coarse) {
    /* 排除触屏设备 */
}

常用媒体特性

特性 说明 示例值
width / height 视口宽高 768px
orientation 横竖屏 portrait / landscape
aspect-ratio 宽高比 16/9
resolution 分辨率 2dppx
pointer 指针精度 fine / coarse
hover 是否支持悬停 hover / none
实战案例:我在做一个地图项目时,用 pointer: coarse 判断触屏设备,给按钮加了更大的点击区域。桌面端保持正常大小,移动端自动放大。一行代码解决触屏适配问题。

组合查询实战

/* 平板横屏 + 高分辨率 */
@media (min-width: 1024px) and (orientation: landscape) and (min-resolution: 2dppx) {
    .map {
        background-image: url('map@2x.png');
    }
}

/* 可悬停 + 精细指针(鼠标) */
@media (hover: hover) and (pointer: fine) {
    .card:hover {
        transform: translateY(-4px);
        box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    }
}

/* 触屏设备 + 竖屏 */
@media (pointer: coarse) and (orientation: portrait) {
    .nav {
        position: fixed;
        bottom: 0;
        width: 100%;
    }
}

你想想看,如果只用宽度判断,你能区分出「带鼠标的平板」和「触屏平板」吗?不能。但 pointer 和 hover 可以。

4.3 常用断点库

断点怎么定?我见过有人拍脑袋写 600px、900px、1200px。结果到真机上一测,iPad 横屏显示不对,iPhone 14 Pro Max 又出问题。

下面是我在多个项目中沉淀下来的断点库,直接拿去用。

标准断点(移动优先)

/* 手机:默认 */
/* 大屏手机 */
@media (min-width: 480px) { }
/* 平板竖屏 */
@media (min-width: 768px) { }
/* 平板横屏 / 小桌面 */
@media (min-width: 1024px) { }
/* 桌面 */
@media (min-width: 1280px) { }
/* 大桌面 */
@media (min-width: 1440px) { }
/* 超大屏 */
@media (min-width: 1920px) { }

标准断点(桌面优先)

/* 超大屏:默认 */
/* 大桌面 */
@media (max-width: 1920px) { }
/* 桌面 */
@media (max-width: 1440px) { }
/* 小桌面 */
@media (max-width: 1280px) { }
/* 平板横屏 */
@media (max-width: 1024px) { }
/* 平板竖屏 */
@media (max-width: 768px) { }
/* 大屏手机 */
@media (max-width: 480px) { }

设备特定断点

设备 宽度 备注
iPhone SE 375px 小屏手机基准
iPhone 14 Pro Max 430px 大屏手机基准
iPad mini 744px 小平板竖屏
iPad Pro 11" 834px 标准平板竖屏
iPad Pro 12.9" 1024px 平板横屏边界
MacBook Air 13" 1280px 小桌面基准
MacBook Pro 16" 1512px 标准桌面基准
避坑指南:我曾经直接拿 iPhone 的物理像素(如 1170px)写断点,结果在真机上完全不对。记住:媒体查询用的是 CSS 像素,不是物理像素。iPhone 14 Pro Max 的 CSS 宽度是 430px,不是 1290px。

4.4 知识体系图

下面这张图把媒体查询的核心知识点串起来了。你可以把它当作复习提纲。

媒体查询进阶知识体系 媒体查询进阶知识体系 媒体查询 策略选择 移动优先 桌面优先 组合查询 逻辑运算符 媒体特性 常用断点库 标准断点 设备断点 核心原则:先定策略 → 再选特性 → 最后定断点 不要一上来就写 @media,先想清楚你的用户用啥设备

4.5 实战建议

最后说几个我踩过的坑,你写代码时注意避开。

  1. 别用太多断点。3-5 个就够了。断点越多,测试成本越高,维护越痛苦。
  2. 断点值用变量。Sass 或 CSS 自定义属性都行。别在代码里到处写死 768、1024。
  3. 真机测试不可少。Chrome 模拟器再准,也不如拿真机划两下。尤其是触屏交互,模拟器永远模拟不出真实手感。
  4. 别忘了打印样式。@media print 很多人不写,但用户真要打印时,体验会很差。
我的习惯:项目初期先定好断点变量,写在全局样式文件里。然后所有组件都引用这些变量。这样后期改断点,改一个地方就行。我曾经在一个项目里改了三次断点,就是因为前期没定好,后期到处改,改到怀疑人生。