学习 CSS At Rules 媒体查询 — @media

前言

之前写过一篇《学习 CSS At Rules 容器查询 --- @container》 文章,其中提到了 容器查询 的蛮生兄弟 媒体查询,两兄弟都同属于 CSS At-Rules 大家庭。但论两兄弟的"出生",那 媒体查询 可是老大哥了。所以这篇文章算是补发,也是带大家认识下这位老大哥 媒体查询 @media。

在前端开发中,我们往往需要一套网页同时支持适配 不同分辨率屏幕WEB端 (PC端和移动端),而我们将同时能够自适配不同分辨率屏幕的网页称为响应式网页。在最初方案中我们通过 JS 监听浏览器视区宽度变化来实现响应式布局 (onresize) ,但当我们监听浏览器视区宽度 resize,卸载当前样式文件,然后加载新的样式文件。以此往复网页不断卸载样式、加载新样式,此时我们就会看到明显网页抖动。可见 JS 来触发响应式布局,并不是一种好的方式。

所以为了实现平滑、顺畅、无抖动的响应式布局,CSS3 推出了 媒体查询 @media。

媒体查询

简介

媒体查询 可以让我们根据设备显示器的特性(如视口宽度、屏幕比例、设备方向:横向或纵向)为其应用特定的 CSS 样式,媒体查询由媒体类型或检测媒体特性的条件表达式组成。

  • 媒体类型: 媒体类型描述了给定设备的一般类别

    媒体类型 介绍说明 状态
    all 所有媒体 默认值(可省略)
    screen 屏幕媒体,包括电脑、手机、平板 /
    print 打印媒体,如打印机 /
    ...
  • 媒体特性: 媒体功能描述了给定的的输出设备或环境的特定特征

    媒体特性 介绍说明
    width 视区宽度(可加max min前缀)
    height 视区高度(可加max min前缀)
    device-width 设备屏幕分辨率的宽度(可加max min前缀)
    orientation portrait竖屏/landscape横屏
    ...

语法定义

  • 在 @media 语法中,定义待应用样式的媒体

    css 复制代码
      /* 适配所有媒体 */
      @media { /* css code */ }
      @media all { /* css code */ }
      
      /* 仅适配打印媒体 */
      @media print {
        /* css code */ 
      }
        
      /* 仅适配手机设备 */
      @media (max-width: 768px) {
        /* css code */ 
      }
        
      /* 仅适配竖屏设备 */
      @media (orientation: portrait) {
        /* css code */ 
      }
        
  • 在 style 元素的 media 属性中,定义待应用样式的媒体

    html 复制代码
      <!-- 适配所有媒体 -->
      <style type="text/css"></style>
      
      <!-- 仅适配打印媒体 -->
      <style type="text/css" media="print"></style>
      
      <!-- 仅适配手机设备 -->
      <style type="text/css" media="(max-width: 768px)"></style>
        
      <!-- 仅适配竖屏设备 -->
      <style type="text/css" media="(orientation: portrait)"></style>
      
  • @import url语法中,定义待应用样式的媒体

    css 复制代码
      /* 适配所有媒体 */
      @import url('./index.css');
      
      /* 仅适配打印媒体 */
      @import url('./index.css') print;
       
      /* 仅适配手机设备 */
      @import url('./index.css') (max-width: 768px);
       
      /* 仅适配竖屏设备 */
      @import url('./index.css') (orientation: portrait);
       
  • 在 <link > 元素的 media 属性中,定义了待应用链接资源(通常是 CSS)的媒体

    html 复制代码
      <!-- 适配所有媒体 -->
      <link rel="stylesheet" href="./index.css">
      
      <!-- 仅适配打印媒体 -->
      <link rel="stylesheet" href="./index.css" media="print">
       
      <!-- 仅适配手机设备 -->
      <link rel="stylesheet" href="./index.css" media="(max-width: 768px)">
       
      <!-- 仅适配竖屏设备 -->
      <link rel="stylesheet" href="./index.css" media="(orientation: portrait)">
        
  • 在 <picture > 之内 <source > 元素的 media 属性中,定义不同的显示/设备场景提供图像版本

    html 复制代码
      <picture>
       <source srcset="./lower.jpg" media="(max-width: 768px)" />
       <source srcset="./higher.jpg" media="(min-width: 960px)" />
       <img src="./normal.png" alt="photo" />
      </picture>

在媒体查询中,有这么一些注意事项

  1. 媒体类型是必要条件,但 all 可以省略
  2. 媒体特性是次要条件,可以不定义。如果定义必须用小括号括起来且只能定义一个
  3. 媒体类型、媒体特性,他们彼此之间需使用 逻辑运算符 关联, 即"与"、"或"、"非"

逻辑运算符

当创建一个取决于多个条件的复杂媒体查询时, 这就是需要 逻辑运算符 的配合使用。具体如下:

  • and: 将媒体功能与媒体类型或其他媒体功能组合一起, 用户设备完全匹配时应用样式,例如

    css 复制代码
      /* 仅适配横向的手机设备 */
      @media (max-width: 768px) and (orientation: landscape) { 
        /* css code */
      } 
      
  • ,: 用户设备与各种媒体类型或特性中任何一种匹配时,可以用逗号分隔来应用样式,例如

    css 复制代码
      /* 适配用户设备的最小宽度为 768px 或 纵向模式的屏幕设备 */
      @media (min-width: 768px), screen and (orientation: portrait) {
        /* css code */
      } 
      
  • not: 会反转整个媒体查询的含义。它只会否定要应用的特定媒体查询。例如

    css 复制代码
      /* 下面两者等价 */
      @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) {}
      
  • only: 防止不支持带有媒体功能的媒体查询的旧版浏览器应用给定的样式。对现代浏览器没有影响

    css 复制代码
      /* 适配屏幕媒体 */
      @media only screen {}

媒体查询的应用

例如常见的 Bootstrap 响应式栅格系统设计

css 复制代码
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) { ... }

/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) { ... }

/* Large devices (desktops, 992px and up) */ */
@media (min-width: 992px) { ... }

/* X-Large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { ... }

/* XX-Large devices (larger desktops, 1400px and up) */
@media (min-width: 1400px) { ... }

媒体查询单位

单位 说明
vw 表示浏览器视口宽度的 1%
vh 表示浏览器视口高度的 1%
vmin 表示浏览器视口尺寸较小的值,如果视口尺寸是 1280px * 960px,则 100vmin 对应的是尺寸较小的宽度 960px
vmax 表示浏览器视口尺寸较大的值,如果视口尺寸是 1280px * 960px,则 100vmax 对应的是尺寸较大的宽度 1280px

有了这些媒体查询单位,相比 JS 的 window.innerWidth 和 window.innerHeight 的获取和设置,在 CSS 中的适配更加平滑和便捷。

相关 JS API

JavaScript 中可以使用 Window.matchMedia() 方法根据媒体查询进行测试。还可以使用 MediaQueryList.addListener() 在查询状态发生变化时收到通知。借助此功能,你的应用动态响应设备配置,方向或状态的更改。

  • matchMedia() 方法返回一个新的 MediaQueryList 对象,用于判定 document 是否匹配媒体查询,或者监控 document 来判定它匹配了或者停止匹配了此媒体查询。

    js 复制代码
      window.matchMedia('(min-width: 600px)')
      
      // result:
      //  {
      //    matches: true,
      //    media: "(min-width: 600px)",
      //    onchange: null 
      //  }
  • addListener() 方法向 MediaQueryListener添加一个侦听器,该侦听器将运行自定义回调函数以响应媒体查询状态的更改。

    js 复制代码
      const mql = window.matchMedia("(min-width: 600px)")
    
      mql.addListener(function(e) {
        if (e.matches) {
          /* 视口宽度 >= 600像素 */
        } else {    
          /* 视口宽度 < 600像素 */
        }
      })

与容器查询区别 ?

  • 媒体查询 @media 关注匹配的是浏览器窗口尺寸
  • 容器查询 @container 关注匹配的是父容器元素尺寸

关于 容器查询 更多信息,请看这篇

相关推荐
Jmyd01234 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
砚凝霜4 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
u0111026756 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
jerrywus7 小时前
让 AI 写完代码后交一份报告:我改造了 answer-me-with-html
前端·claude·cursor
派小心.7 小时前
小程序分享链路中来源参数的传递校验
大数据·前端·数据库·人工智能·小程序·数据分析
hhb_6187 小时前
一键生成数据看板,ECharts实战演示
前端·javascript·echarts
Java后端的Ai之路8 小时前
08_React组件API
前端·react.js·前端框架
小马不起床8 小时前
零基础玩转 FastAPI_09:前端基础工程构建
前端·状态模式·fastapi
风骏时光牛马9 小时前
用户管理模块接口开发
前端
彭亚川Allen9 小时前
从零手搓 RAG 之检索全流程,给大模型接上自己的知识库
前端·后端·ai编程