@规则:@media(媒体查询)
媒体查询(Media queries)可以根据设备类型、屏幕特征、浏览器视口参数来条件性应用 CSS 样式,是响应式布局的核心能力。可以区分屏幕、打印设备、视口宽高、横竖屏、像素密度等环境,在不改动 HTML 内容的前提下,输出适配不同设备的展示效果。
媒体查询常见使用场景:
- 通过
@media、@importat-rule,条件性加载 CSS 样式; - 在 HTML 的
<link>、<style>、<source>等标签上使用media属性,限定资源生效条件; - JS 通过
window.matchMedia()检测、监听媒体查询状态变化,做逻辑分支处理。
媒体查询由可选的媒体类型 + 若干媒体特性表达式组成,支持逻辑运算符组合多条条件;不区分大小写。
匹配规则:媒体类型匹配,并且全部媒体特性表达式结果为 true,整条媒体查询才生效;遇到未知媒体类型,直接返回 false。
@media screen and (min-width: 768px) {}
@media (orientation: portrait) {}
@media (min-width: 1200px), (orientation: landscape) {}
@import url("") screen and (max-width: 767px);
@import url("") print;
<link rel="stylesheet" href="" media="screen and (max-width: 767px)" />
<link rel="stylesheet" href="" media="print" />
<style media="(orientation: landscape)"></style>
<picture>
<source srcset="" media="(min-width: 1000px)">
<source srcset="" media="(min-width: 600px)">
<img src="" alt="">
</picture>
const matchMedia = window.matchMedia('(orientation: portrait)');
if (matchMedia.matches) {
matchMedia.addEventListener('change', (e) => {
if (e.matches) {}
});
}
媒体类型
描述设备的大类,为可选项;省略时隐式等同于 all。
all:适用于全部设备;screen:面向屏幕显示器(PC、手机屏幕);print:打印预览、分页打印文档场景;speech:语音合成读屏设备。
废弃提醒:tty、tv、projection、handheld、braille、aural 等类型在 Media Queries Level 4 规范已经废弃,不要再使用;原 aural 由 speech 替代。
@media all and (max-width: 480px) {}
@media (max-width: 480px) {}
@media screen and (min-width: 768px) {}
@media print {}
@media speech {}
@media screen, print {}
@media not all and (monochrome) {}
@media only screen and (min-width: 1024px) {}
注意:使用 not、only 运算符时,必须显式书写媒体类型。
媒体特性
描述浏览器、输出设备的具体特征,表达式必须包裹在圆括号 () 内。
常用媒体特性:
width、height:浏览器视口宽、高度(包含滚动条),支持min-、max-前缀做范围判断;aspect-ratio:视口宽高比,支持min-、max-前缀做范围判断;orientation:屏幕方向;取值portrait(竖屏,高度 > 宽度)、landscape(横屏,宽度 > 高度);resolution:设备像素密度,单位支持dpi、dppx,支持min-、max-前缀做范围判断;color:设备彩色位深;黑白设备该值为0,支持min-、max-前缀做范围判断;monochrome:单色设备每像素位深度,彩色设备值为0;display-mode:对应 PWA manifest 的display,取值:fullscreen、standalone、minimal-ui、browser。仅在 PWA 安装后才会命中,普通浏览器标签页是browser。
@media (min-width: 768px) {}
@media (max-width: 480px) {}
@media (min-height: 600px) {}
@media (min-aspect-ratio: 16/9) {}
@media (max-aspect-ratio: 4/3) {}
@media (orientation: portrait) {}
@media (orientation: landscape) {}
@media (min-resolution: 2dppx) {}
@media (min-resolution: 192dpi) {}
@media (color) {}
@media (min-color: 8) {}
@media (monochrome) {}
@media not all and (monochrome) {}
@media (display-mode: standalone) {}
@media (display-mode: fullscreen) {}
废弃提示:device-width、device-height 已经在 Level 4 废弃,不要继续使用。
逻辑运算符
支持 and、not、only,逗号 , 等价逻辑或 OR。
and:将媒体类型与媒体特性、多个媒体特性做“逻辑与”合并,全部条件满足才匹配。not:对整条媒体查询取反,不能单独否定某一个媒体特性;逗号分隔多条查询时,not只作用于它所在的那一条。Level3 语法限制:not不能写在括号内部否定单个特性,只能写在查询最开头。only:用来兼容老旧不支持媒体特性的浏览器;老浏览器会把only screen整条忽略,不会错误执行后面条件;现代浏览器无任何影响。- 逗号
,(逻辑或 OR):多条查询用逗号隔开,任意一条匹配成功,整体生效。
@media screen and (min-width: 768px) and (orientation: landscape) {}
@media not all and (monochrome) {}
@media not (all and (monochrome)) {}
@media not screen and (color), print and (color) {}
@media (not (screen and (color))), print and (color) {}
@media only screen and (min-width:768px) {}
@media (min-width:1200px), (orientation:landscape) {}
CSS 使用 @media
基础语法:
@media 媒体类型 [逻辑运算符] (媒体特性) {}
/* 屏幕设备,视口宽度 >=900px 生效 */
@media screen and (min-width: 900px) {}
/* 竖屏时生效,省略媒体类型默认 all */
@media (orientation: portrait) {}
/* 屏幕断点划分,移动端优先(min-width向上匹配) */
@media screen and (min-width: 1200px) {}
@media screen and (min-width: 960px) and (max-width: 1199px) {}
@media screen and (min-width: 768px) and (max-width: 959px) {}
@media screen and (min-width: 480px) and (max-width: 767px) {}
@media screen and (max-width: 479px) {}
/* 横竖屏 */
@media (orientation: landscape) {}
@media (orientation: portrait) {}
/* 视口宽高比 */
@media (min-aspect-ratio: 16/9) {}
/* 高分屏 Retina */
@media (min-resolution: 2dppx) {}
HTML 使用 media 属性
<link>、<style>、<source> 可以设置 media 属性,限定资源生效条件。
<link rel="stylesheet" media="screen and (max-width:960px)" href="">
三者资源加载行为不同:
<link>:即使媒体查询条件不匹配,浏览器依旧会下载该 CSS 文件,只是不会应用样式,产生多余网络请求。<style>:条件不匹配则样式不生效,不存在下载行为。<source>:媒体查询条件不匹配时直接跳过,不会发起该条的资源网络请求;浏览器只会加载第一个匹配条件的资源。
最佳实践:尽量把多端样式合并到同一个 CSS 文件内部,使用内部 @media 做分支,不要拆分多个 link。