CSS @media 媒体查询不要只会视口宽度适配详解

笔记哥 / 05-08 / 36点赞 / 0评论 / 768阅读
`@media` 媒体查询的出现解决了什么问题? 曾经,一个网页要兼容移动端和 PC 端,前端的代码复杂度嗖嗖嗖的飙升,需要使用多套代码对各种屏幕尺寸做适配。 `@media` 的出现解决了 CSS 中无法适配设备尺寸的问题,让 CSS 拥有了处理简单逻辑的能力。 媒体查询就像进店试穿衣服一样,穿得上,咱就用这一套;穿不上,咱就换一套;都穿不上,那就还是穿进店时身上这套吧~~ ## 媒体查询 使用媒体查询之前,先要明白 `媒体` 二字是指的用户软件设备(比如:电脑中浏览器、网页打印预览等)。 媒体查询无法针对某个具体的 HTML 元素做出响应!! 也无法针对特定的硬件设备做出响应(比如:小米手机、苹果手机等)!! 它只能对用户设备的固定特性做出响应(比如浏览器的可视宽度,是否支持鼠标悬停,设备像素密度等)!! ### 语法 ```css @media { } ``` ### 一个简单示例 查询媒体宽度在某个范围内时,设置不同的背景色: ```html
媒体查询应用
``` 效果: ![](https://cdn.res.knowhub.vip/c/2505/08/0a4d6ac4.gif?G1UAAMTc2vOlu6bTrd%2fToCVYBtoMVKQRVOpZr2fvf51E%2fXUG53h9bUxfH37RxnQSK7BKDBYIQoDCkmVWTeHQyoZiqtH7DQ%3d%3d) ### 指定媒体类型 以上媒体查询在未指定媒体类型时,默认为 `all` 全部媒体类型,将会应用于屏幕和打印预览~ 可使用关键字指定 `screen` 指定用于屏幕或 `print` 指定用于打印。 ```html
媒体查询应用
``` 可在浏览器中 `ctrl + p` 查看打印样式: ![](https://cdn.res.knowhub.vip/c/2505/08/95f28859.png?G1MAAMTW3DgpHwVC22gDdWfqnTYDElUElXrW6917rpvo%2b4PBV356bSPWhz%2fUNoLEFV6IwQJB0jD46WKHSiquUBjn2QM%3d) ### 使用逻辑运算符 使用逻辑运算符 `and` 、 `not` 、 `only` 、 `,` 、 `or`,可以组合多个媒体查询条件,实现更复杂的逻辑判断。 `and` 用于多个查询条件同时匹配时才应用样式: ```css @media screen and (min-width: 320px) and (max-width: 600px) { .box { line-height: 3; } } ``` `not` 用于查询条件不匹配时才应用样式: ```css @media not screen and (min-width: 600px) { /* 指定屏幕设备宽度不大于 600px 时,背景色为 #ffa947 */ .box { background-color: #ffa947; } } ``` `only` 仅在整个查询匹配时才应用样式。这对于防止较老的浏览器应用所选样式很有用。当不使用 only 时,较老的浏览器会将 screen and (max-width: 500px) 简单地解释为 screen,忽略查询的其余部分,并将其样式应用于所有屏幕。如果使用 only 运算符,则还必须指定媒体类型。 --- 摘自 MDN ```css @media only screen and (max-width: 600px) { /* 指定屏幕设备宽度小于 600px 时,字体色为 #ff4757 */ .box { color: #ff4757; } } ``` `,` 和 `or` 运算符等价,`or` 在媒体查询第 4 版中加入,仅 `2022` 年之后的浏览器支持: ```css @media screen, print { .box { font-size: 28px; } } @media (not (color)) or (not (hover)) { .box { font-weight: bold; } } ``` **需特别注意:逻辑运算符后面必须有至少一个空格!!比如 `not(hover)` 将不生效,必须写成 `not (hover)`。** ### 新语法 媒体查询第 4 版引入了一种新的范围语法,使用此语法需特别注意浏览器兼容性: 支持的运算符有:等于 `=`、小于 `<`、 小于等于 `<=`、大于 `>`、大于等于 `>=`。 ```css /* @media (max-width: 600px) { ... } 等价于 */ @media (width <= 600px) { .box { font-size: 28px; } } /* @media (min-width: 600px) and (max-width: 1200px) { ... } 等价于 */ @media (600px <= width <= 1200px) { .box { font-size: 28px; } } @media screen and (width = 320px) { /* 指定屏幕设备宽度等于 320px 时,行高为 10 */ .box { line-height: 10; } } ``` 第 4 版的媒体查询 W3C 参考文档:https://drafts.csswg.org/mediaqueries/ ### 常用媒体特性列表 **any-hover** 是否有任何可用的输入机制允许用户将鼠标悬停在元素上。有效值: `none`、`hover`。 **width** 可视区域的宽度,包括滚动条的宽度。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (width: 600px) {} @media (min-width: 30rem) {} @media (max-width: 40rem) {} ``` ```css @media (any-hover: hover) { /* 有鼠标悬停时(比如PC端),字体色为 #ff4757 */ .box { color: #ff4757; } } ``` **height** 可视区域的高度。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (height: 600px) {} @media (min-height: 30rem) {} @media (max-height: 40rem) {} ``` **resolution** 输出设备的像素密度。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (resolution: 150dpi) {} @media (min-resolution: 300dpi) {} @media (max-resolution: 2dpcm) {} ``` **orientation** 可视区域的方向。有效值:`portrait`(纵向:高度大于或等于宽度)、`landscape`(横向:宽度大于高度)。 ```css @media (orientation: portrait) {} @media (orientation: landscape) {} ``` **pointer** 主输入机构是否为指针设备,如果是,其准确性如何。有效值:`none`(不包括定点设备)、`coarse`(精度有限的定点设备,例如触摸屏上的手指)、`fine`(精确指针设备,例如鼠标)。 ```css @media (any-pointer: fine) {} @media (any-pointer: coarse) {} ``` **hover** 输入机制是否允许用户将鼠标悬停在元素上。有效值:`none`(无法悬停或无法方便地悬停)、`hover`(可以方便地将鼠标悬停)。 ```css @media (hover: hover) {} ``` **aspect-ratio** 可视区域的宽高纵横比。有效值:`4/3`、`1.33333`。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (min-aspect-ratio: 8/5) {} @media (aspect-ratio: 1/1) {} @media (max-aspect-ratio: 8/5) {} @media screen and (min-aspect-ratio: 16/9) {} ``` **prefers-color-scheme** 检测用户是喜欢浅色还是深色配色方案。 在 Media Queries Level 5 中添加。有效值:`light`(浅色)、`dark`(深色)。 ```css @media (prefers-color-scheme: dark) {} ``` ### 不常用媒体特性列表 **any-pointer** 是否有任何可用的输入机制是指针设备。有效值: `none`、`fine` 或 `coarse`。 ```css @media (any-pointer: fine) { /* 至少一个输入机制包括精确指针设备 */ } @media (any-pointer: coarse) { /* 至少一个 input 机制包括精度有限的定点设备 */ } ``` **color** 输出设备的每个颜色分量的位数,如果设备不支持输出彩色,则为 `0`。 允许 `min-` 和 `max-` 前缀查询范围。 ```css /* 任何颜色设备 */ @media (color) {} /* 每个颜色分量至少有8位的颜色设备 */ @media (min-color: 8) {} ``` **color-gamut** 用户代理和输出设备支持的颜色的大致范围。有效值:`srgb`、`p3`、`rec2020`。 ```css @media (color-gamut: srgb) {} ``` **color-index** 输出设备的颜色查找表中的条目数,如果设备不使用此类表,则为 `0`。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (color-index) {} @media (min-color-index: 16000) {} ``` **device-posture** 实验性 检测设备的当前状态,即可视区域是处于平放状态还是折叠状态。在 Device Posture API 中定义。有效值:`continuous` 平面屏幕状态、`folded` 折叠屏幕状态。 ```css @media (device-posture: folded) and (orientation: landscape) {} @media (device-posture: continuous) {} ``` **display-mode** 应用程序的显示模式:例如,全屏或画中画模式。 在 Media Queries Level 5 中添加。有效值:浏览器 `browser`、全屏 `fullscreen`、画中画 `picture-in-picture`、`minimal-ui`、`standalone`、`window-controls-overlay`。 ```css @media all and (display-mode: fullscreen) {} ``` **dynamic-range** 用户代理和输出设备支持的亮度、对比度和颜色深度的组合。在 Media Queries Level 5 中添加。有效值:`standard`(任何可视设备)、`high`(支持的亮度、对比度和颜色深度的组合)。 ```css @media (dynamic-range: standard) {} @media (dynamic-range: high) {} ``` **forced-colors** 检测 User Agent 是否限制调色板。 在 Media Queries Level 5 中添加。有效值:`none`、`active`(强制颜色模式处于活动状态)。 ```css @media (forced-colors: active) {} ``` **grid** 设备是否使用网格屏幕还是点阵屏幕。有效值:`0`、`1`。 ```css @media (grid: 0) {} @media (grid: 1) {} ``` **inverted-colors** 用户代理或底层作系统是否反转了颜色。在 Media Queries Level 5 中添加。有效值:`none`(颜色正常显示)、`inverted`(所有像素都已反转)。 ```css @media (inverted-colors: inverted) {} @media (inverted-colors: none) {} ``` **monochrome** 输出设备的单色帧缓冲区中每像素的位数,如果设备不是单色的,则为 `0`。 允许 `min-` 和 `max-` 前缀查询范围。 ```css @media (monochrome: 0) {} @media (max-monochrome: 8) {} ``` **overflow-block** 输出设备如何处理沿块轴溢出可视区域的内容。有效值:`none`(不显示溢出内容)、`scroll`(滚动显示)、`optional-paged`、`paged`。 ```css @media (overflow-block: scroll) {} ``` **overflow-inline** 沿内联轴溢出可视区域的内容是否可以滚动。有效值:`none`(不显示溢出内容)、`scroll`(滚动显示)。 ```css @media (overflow-inline: scroll) {} ``` **prefers-contrast** 检测用户是否请求系统增加或减少相邻颜色之间的对比度。 在 Media Queries Level 5 中添加。有效值:`no-preference`(无偏好)、`more`(增加对比度)、`less`(减少对比度)、`custom`(自定义对比度)。 ```css @media (prefers-contrast: more) {} ``` **prefers-reduced-data** 检测用户是否请求了消耗较少 Internet 流量的 Web 内容。有效值:`no-preference`(无偏好)、`reduce`(减少数据流量)。 ```css @media (prefers-reduced-data: no-preference) {} ``` **prefers-reduced-motion** 用户喜欢在页面上进行较少的运动。 在 Media Queries Level 5 中添加。有效值:`no-preference`(无偏好)、`reduce`(减少运动)。 ```css @media (prefers-reduced-motion) {} ``` **prefers-reduced-transparency** 检测用户是否在其设备上启用了设置,以减少设备上使用的透明或半透明图层效果。有效值:`no-preference`(无偏好)、`reduce`(减少透明效果)。 ```css @media (prefers-reduced-transparency) {} ``` **scan** 显示输出是逐行扫描还是隔行扫描。有效值:`progressive`(逐行扫描)、`interlace`(隔行扫描)。 ```css @media screen and (scan: interlace) {} @media screen and (scan: progressive) {} ``` **scripting** 检测脚本(即 JavaScript)是否可用。 在 Media Queries Level 5 中添加。有效值:`none`(脚本不可用)、`initial-only`(脚本在初始页面加载期间启用,但之后不会启用)、`enabled`(脚本可用)。 ```css @media (scripting: none) {} @media (scripting: initial-only) {} @media (scripting: enabled) {} ``` **shape** 实验性 检测设备的形状以区分矩形和圆形显示器。有效值:`rect`(矩形或正方形)、`round`(圆形或与圆形相似的形状)。 ```css @media (shape: rect) {} @media (shape: round) {} ``` **update** 输出设备可以修改内容外观的频率。有效值:`none`(不支持)、`slow`(慢速)、`fast`(快速)。 ```css @media (update: none) {} @media (update: slow) {} @media (update: fast) {} ``` **video-dynamic-range** 用户代理和输出设备的视频平面支持的亮度、对比度和颜色深度的组合。在 Media Queries Level 5 中添加。有效值:`standard`(标准)、`high`(高)。 ```css @media (video-dynamic-range: high) {} @media (video-dynamic-range: standard) {} ``` ## 写在最后 虽然媒体查询多用于响应式布局,但多了解一些其他媒体特性,可做出一些很有用的交互设计效果,比如:深色、浅色主题适配;指针设备、和非指针设备适配等等~~ 媒体查询兼容性参考文档:https://developer.mozilla.org/en-US/docs/Web/CSS/@media#browser_compatibility 参考资料:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media