4、媒体查询进阶:断点策略

媒体查询这东西,入门容易,用好难。我见过太多同学写了满屏的 @media,结果一换设备就崩。问题出在哪?说白了,就是断点没定好。

今天咱们聊聊断点策略。这东西决定了你的页面在不同屏幕上的表现。选对了,事半功倍;选错了,改到怀疑人生。

Mobile First vs Desktop First

这两种策略,我一开始也纠结过。后来踩了坑才明白,它们各有各的适用场景。

Mobile First,就是先写手机端的样式,再用媒体查询逐步增强。代码长这样:

/* 默认:手机端样式 */
.container {
    width: 100%;
    padding: 0 15px;
}

/* 平板:宽度超过768px时生效 */
@media (min-width: 768px) {
    .container {
        width: 750px;
        margin: 0 auto;
    }
}

/* 桌面:宽度超过992px时生效 */
@media (min-width: 992px) {
    .container {
        width: 970px;
    }
}

你看,用的是 min-width。从小往大写,像盖楼一样,一层层往上加。

Desktop First 反过来,先写桌面端,再用媒体查询降级:

/* 默认:桌面端样式 */
.container {
    width: 970px;
    margin: 0 auto;
}

/* 平板:宽度小于992px时生效 */
@media (max-width: 991px) {
    .container {
        width: 750px;
    }
}

/* 手机:宽度小于768px时生效 */
@media (max-width: 767px) {
    .container {
        width: 100%;
        padding: 0 15px;
    }
}

这里用的是 max-width。从大往小写,像拆积木一样,一层层拆掉。

我个人习惯:新项目用 Mobile First。为什么?因为现在移动端流量占比太大了。你想想看,用户掏出手机看你的页面,结果加载了一堆桌面端的样式,再被媒体查询覆盖掉,多浪费性能。

但 Desktop First 也不是一无是处。我在做后台管理系统时,就经常用 Desktop First。因为后台用户基本都在电脑上操作,手机端只是偶尔看看。这时候先保证桌面体验,再适配手机,反而更合理。

小技巧:不确定选哪个?看看你的用户画像。如果移动端用户多,选 Mobile First;如果桌面端用户多,选 Desktop First。别纠结,数据说话。

常见断点设置

断点怎么设?网上有各种推荐值。我直接给你一套我用了三年的方案,稳得很:

设备类型 断点值 说明
手机竖屏 < 576px 小屏手机,如 iPhone SE
手机横屏 ≥ 576px 大屏手机横过来看
平板竖屏 ≥ 768px iPad 竖屏状态
平板横屏/小桌面 ≥ 992px iPad 横屏或小笔记本
桌面 ≥ 1200px 标准桌面显示器
大桌面 ≥ 1400px 宽屏显示器

这套断点,我参考了 Bootstrap 的体系,但做了微调。为什么是 576、768、992、1200、1400?因为这些值覆盖了市面上绝大多数设备的宽度。

注意:别拿具体设备当断点!我见过有人写 @media (max-width: 375px),因为那是 iPhone X 的宽度。结果 iPhone 12 一出,宽度变了,代码就废了。断点应该基于内容,而不是设备。

使用媒体查询调整布局

布局调整,是媒体查询最常用的场景。我给你看个例子,是我之前做的一个产品列表页:

/* Mobile First 策略 */
/* 手机:单列布局 */
.product-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 15px;
}

/* 平板:两列布局 */
@media (min-width: 768px) {
    .product-list {
        grid-template-columns: repeat(2, 1fr);
        gap: 20px;
    }
}

/* 桌面:三列布局 */
@media (min-width: 992px) {
    .product-list {
        grid-template-columns: repeat(3, 1fr);
        gap: 30px;
    }
}

/* 大桌面:四列布局 */
@media (min-width: 1200px) {
    .product-list {
        grid-template-columns: repeat(4, 1fr);
    }
}

你看,从 1 列到 4 列,随着屏幕变宽,内容越来越多。这就是 Mobile First 的精髓——从小屏开始,逐步释放能力。

除了网格,导航栏也是重灾区。手机上的汉堡菜单,到了桌面就得展开:

/* 手机:隐藏导航,显示汉堡按钮 */
.nav-menu {
    display: none;
}
.nav-toggle {
    display: block;
}

/* 桌面:显示导航,隐藏汉堡按钮 */
@media (min-width: 992px) {
    .nav-menu {
        display: flex;
    }
    .nav-toggle {
        display: none;
    }
}

嗯,这里要注意:display: none 切换时,别忘了考虑可访问性。屏幕阅读器可能读不到隐藏的内容。我一般会配合 aria-hidden 属性一起用。

使用媒体查询调整字体

字体大小,很多人忽略了。你想想看,手机上字太小看不清,桌面上字太大又显得傻。所以字体也得跟着屏幕走。

我常用的方案有两种:

方案一:直接设置不同断点的字号

body {
    font-size: 14px;  /* 手机端基础字号 */
    line-height: 1.6;
}

@media (min-width: 768px) {
    body {
        font-size: 16px;  /* 平板端稍微大一点 */
    }
}

@media (min-width: 1200px) {
    body {
        font-size: 18px;  /* 桌面端更大,阅读更舒服 */
    }
}

方案二:用视口单位 + 媒体查询兜底

body {
    font-size: calc(14px + 0.25vw);  /* 随视口宽度微调 */
}

/* 但为了防止太大或太小,用媒体查询兜底 */
@media (max-width: 320px) {
    body {
        font-size: 12px;  /* 极小屏,不能再小了 */
    }
}

@media (min-width: 1600px) {
    body {
        font-size: 20px;  /* 超大屏,不能再大了 */
    }
}

方案二更灵活,但兼容性要注意。我一般在生产环境用方案一,简单粗暴,不会出幺蛾子。

避坑指南:我曾经在项目里只用 vw 做响应式字体,结果在 4K 屏上,字大得像标题。后来加了 max-font-size 的限制才解决。记住,纯视口单位有风险,一定要设上下限。

还有标题的字体大小,也得跟着变。比如:

h1 {
    font-size: 1.5rem;  /* 手机端 */
}

@media (min-width: 768px) {
    h1 {
        font-size: 2rem;  /* 平板端 */
    }
}

@media (min-width: 1200px) {
    h1 {
        font-size: 2.5rem;  /* 桌面端 */
    }
}

这样做的好处是,标题在手机上不会占满整个屏幕,在桌面上也不会显得小家子气。

好了,断点策略这块,核心就是这些。记住三点:选对策略(Mobile First 还是 Desktop First)、定好断点(别死磕具体设备)、灵活调整(布局和字体都要管)。下次写媒体查询,试试这些思路,你会发现代码清爽很多。