3、媒体查询基础:媒体查询语法、媒体类型、媒体特性、逻辑运算符
媒体查询,说白了就是让网页「看人下菜碟」的工具。你想想看,手机屏幕那么小,电脑屏幕那么大,用同一套布局肯定不行。媒体查询就是帮我们判断「当前设备是什么情况」,然后给出对应的样式。
我个人习惯把媒体查询比作「门卫」。它会检查来访者的特征——你是手机还是电脑?屏幕是横着还是竖着?宽度够不够大?然后决定放行哪套样式进来。
3.1 媒体查询的基本语法
语法其实很简单,就一个公式:
@media 媒体类型 and (媒体特性) {
/* 满足条件时应用的样式 */
}
嗯,这里要注意:@media 是关键字,后面跟条件,条件成立就执行花括号里的样式。我在项目中见过不少新手把括号写漏了,结果样式死活不生效——检查了半天才发现少了个括号。
来个最基础的例子:
/* 当屏幕宽度小于等于 768px 时 */
@media screen and (max-width: 768px) {
body {
background-color: #f0f8ff;
}
.container {
padding: 10px;
}
}
这段代码的意思是:如果设备是屏幕,并且宽度不超过 768 像素,就把背景色改成浅蓝色,容器内边距缩小到 10 像素。说白了,这就是给手机端准备的样式。
3.2 媒体类型:screen / print / all
媒体类型就是告诉浏览器「我这条规则是给谁看的」。常用的就三种:
| 媒体类型 | 说明 | 使用场景 |
|---|---|---|
screen |
电脑屏幕、手机屏幕、平板等 | 绝大多数网页场景 |
print |
打印机或打印预览 | 打印页面时隐藏导航栏、调整字体 |
all |
所有设备(默认值) | 通用样式,不区分设备 |
我记得有一次做后台管理系统,客户要求打印报表时不能显示侧边栏和按钮。我当时就用了 @media print:
@media print {
.sidebar,
.btn-group,
.header-nav {
display: none;
}
.main-content {
width: 100%;
margin: 0;
padding: 0;
}
}
效果立竿见影。打印预览一打开,那些乱七八糟的导航全消失了,只剩下干干净净的数据表格。你想想看,要是没有媒体查询,你还得单独做个打印版页面,多麻烦。
至于 all,其实就是「不管什么设备都给我执行」。如果你不写媒体类型,默认就是 all。我个人习惯是明确写出来,哪怕写 all 也比不写强——代码可读性会好很多。
3.3 媒体特性:width / height / orientation
媒体特性才是真正干活的东西。它告诉浏览器「你要检查设备的哪些属性」。常用的有这几个:
3.3.1 width 和 height
这是最常用的两个特性。注意,它们可以加 min- 和 max- 前缀:
width:精确匹配某个宽度min-width:宽度大于等于某个值max-width:宽度小于等于某个值height、min-height、max-height:同理
实际项目中,min-width 和 max-width 用得最多。为什么呢?因为精确匹配某个宽度太死板了,你不可能要求所有手机都是 375px 宽。用范围判断更灵活。
/* 手机端:宽度小于 768px */
@media screen and (max-width: 767px) {
.card { width: 100%; }
}
/* 平板端:宽度在 768px 到 1024px 之间 */
@media screen and (min-width: 768px) and (max-width: 1024px) {
.card { width: 48%; }
}
/* 桌面端:宽度大于 1024px */
@media screen and (min-width: 1025px) {
.card { width: 30%; }
}
我曾经犯过一个错:把 max-width: 768px 和 min-width: 768px 都写了,结果在 768px 宽度的设备上两个条件都满足,样式冲突了。后来我学乖了,要么用 max-width: 767px 和 min-width: 768px 错开一个像素,要么用 max-width: 768px 和 min-width: 769px。嗯,这个细节很重要。
3.3.2 orientation:横屏还是竖屏
这个特性很有意思,它判断设备的方向:
orientation: portrait:竖屏(高度大于宽度)orientation: landscape:横屏(宽度大于高度)
我在做视频播放器的时候就用到了这个。手机横屏时自动全屏播放,竖屏时显示缩略图和标题:
@media screen and (orientation: landscape) {
.video-player {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
}
@media screen and (orientation: portrait) {
.video-player {
position: relative;
width: 100%;
max-height: 300px;
}
}
你想想看,用户把手机一转,页面布局就跟着变了,体验是不是很丝滑?
3.4 逻辑运算符:and / or / not
一个条件不够用怎么办?那就用逻辑运算符把它们组合起来。
3.4.1 and:并且
多个条件同时满足时才生效。刚才的例子已经用过了:
/* 屏幕设备 并且 宽度在 768px 以上 并且 横屏 */
@media screen and (min-width: 768px) and (orientation: landscape) {
.sidebar {
width: 300px;
}
}
三个条件缺一不可。少一个都不行,就是这么严格。
3.4.2 or(用逗号实现):或者
CSS 里没有 or 这个关键字,而是用逗号 , 来表示「或」的关系:
/* 宽度小于 480px 或者 横屏状态 */
@media screen and (max-width: 480px), screen and (orientation: landscape) {
.menu {
font-size: 14px;
}
}
只要满足其中一个条件,样式就会生效。逗号分隔的每个部分都是独立的查询条件。
4.4.3 not:否定
not 表示「不满足某个条件」。注意它的位置:要写在媒体类型前面。
/* 不是打印设备 */
@media not print {
.header {
position: sticky;
top: 0;
}
}
/* 宽度不小于 768px(即大于等于 768px) */
@media not screen and (max-width: 767px) {
.container {
max-width: 1200px;
}
}
说实话,not 在实际项目中用得不多。因为大部分时候用 min-width 和 max-width 就能搞定。但偶尔会有一些边界情况,比如「除了打印模式,其他情况都显示这个元素」,这时候 not print 就很好用。
重点总结:
- 媒体查询的格式:
@media 类型 and (特性) { 样式 } - 媒体类型:
screen(屏幕)、print(打印)、all(全部) - 媒体特性:
width、height、orientation,配合min-和max-使用 - 逻辑运算符:
and(并且)、逗号(或者)、not(否定)
我的小技巧:
写媒体查询时,我习惯用「移动端优先」的思路。先写手机端的默认样式,然后用 min-width 逐步往上适配平板和桌面。这样代码更简洁,也更容易维护。你试试看,真的会爱上这种写法。
避坑指南:
我曾经在项目里同时用了 max-width: 768px 和 min-width: 768px,结果在 768px 宽度的设备上两个条件都匹配,样式互相覆盖。后来我改成 max-width: 767px 和 min-width: 768px,问题就解决了。记住,边界值要错开一个像素,别给自己挖坑。