跳到主要内容

media

2023年02月23日
柏拉文
越努力,越幸运

一、认识


通过媒体查询(Media queries),您可以根据各种设备特征和参数的值或者是否存在来调整您的网站或应用。它们是响应式设计 (en-US)的关键组成部分。例如,媒体查询可以缩小小型设备上的字体大小,在纵向模式下查看页面时增加段落之间的填充,或者增加触摸屏上按钮的大小。

CSS 中,使用 @media at-rule 根据媒体查询的结果有条件地应用样式表的一部分。使用 @import 有条件地应用整个样式表。

二、在 HTML 中使用媒体查询


2.1 应用各种元素

  • <link>元素的media属性中,它们定义了待应用链接资源(通常是 CSS)的媒体。

  • <source>元素的media属性中,它们定义待应用源的媒体。 (这仅在<picture>元素内有效。)

  • <style>元素的media属性中,它们定义待应用样式的媒体。

2.2 定位媒体类型

  • CSS 针对打印机:

    @media print { ... }
  • CSS 针对屏幕:

    @media screen, print { ... }
  • CSS 定位多种设备:

    @media screen, print { ... }

2.3 定位媒体特性

  • CSS 定位用户行为:

    @media (hover: hover) { ... }
  • CSS 定位屏幕宽度

    @media screen and (max-width: 12450px) { ... }

    等价于

    @media screen and (width <= 12450px) { ... }

2.4 多种类型特性

  • 通过and查询: and关键字将媒体功能与媒体类型或其他媒体功能组合在一起

    • 案例一、将样式限制为宽度至少为 30 em 的横向的设备:

      @media (min-width: 30em) and (orientation: landscape) { ... }
    • 案例二、将样式限制为带有屏幕的设备,可以将媒体功能链接到screen媒体类型:

      @media screen and (min-width: 30em) and (orientation: landscape) { ... }
    • 案例三、将样式限制在带有屏幕的设备, 屏幕宽度小于等于1400,大于等于900

      @media screen and (min-width: 800) and (max-width: 1400) { ... }

      等价于

      @media screen and (800 <= width <=  1400) { ... }
  • 通过or查询: 可以使用or测试多个功能之间的匹配,如果任何功能为 true,则解析为 true

    • 案例一、以下查询测试具有单色显示或悬停功能的设备

      @media (not (color)) or (hover) { ... }

2.5 定位多重查询

通过逗号查询: 当用户的设备与各种媒体类型,功能或状态中的任何一种匹配时,可以使用逗号分隔的列表来应用样式。

  • 案例一、例如,如果用户设备的最小高度为 680px 或为纵向模式的屏幕设备,则以下规则将应用其样式:

    @media (min-height: 680px), screen and (orientation: portrait) { ... }

    以上面的示例为例,如果用户使用的打印机的页面高度为 800 像素,则 media 语句将返回 true,因为将应用第一个查询。同样,如果用户使用的是纵向模式的智能手机,并且视口高度为 480px,则将应用第二个查询,并且 media 语句仍将返回 true

2.6 定位反转查询

通过not查询: not关键字会反转整个媒体查询的含义。它只会否定要应用的特定媒体查询。 (因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询。)not关键字不能用于否定单个功能查询,只能用于否定整个媒体查询。

  • 案例一:

    @media not all and (monochrome) { ... }

    所以上述查询等价于:

    @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) { ... }
  • 案例三: 在媒体功能周围使用not()会否定查询中的该特性。例如,如果设备没有悬停功能,则not(hover)将被匹配:

    @media (not(hover)) { ... }

三、在 JavaScript 中使用媒体查询


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

  1. 创建媒体查询列表: 在获取查询结果前,首先要创建查询列表,也就是 MediaQueryList 对象来存放媒体查询。为了实现这个目的,可以使用 window.matchMedia 方法。

    var mediaQueryList = window.matchMedia("(orientation: portrait)");
  2. 检查查询结果: 一旦创建了媒体查询列表,你就可以通过检查它的 matches 属性来获取相应的查询结果,上述属性会直接返回查询结果

    if (mediaQueryList.matches) {
    /* 设备的旋转方向为纵向 portrait */
    } else {
    /* 设备的旋转方向不是纵向,也就是横向 landscape */
    }
  3. 接收查询提醒: 如果你需要持续观察查询结果值的变化情况,那么,注册一个监听器比手动检查查询结果要高效很多。要注册监听器,只要在 MediaQueryList 对象上使用 addListener() 方法,并使用一个回调函数作为其参数。这样,就通过实现 MediaQueryListListener (en-US) 接口指定了一个监听器。每当查询结果发生变化,比如从 true 变为 false 时,就会调用一遍传入的回调函数。

    // 创建查询列表
    const mediaQueryList = window.matchMedia("(orientation: portrait)");

    function handleOrientationChange(evt) {
    if (evt.matches) {
    /* The viewport is currently in portrait orientation */
    } else {
    /* The viewport is currently in landscape orientation */
    }
    }

    // 先运行一次回调函数
    handleOrientationChange(mediaQueryList);

    // 为查询列表注册监听器,同时将回调函数传给监听器
    mediaQueryList.addListener(handleOrientationChange);
  4. 终止查询通知: 如果不再需要再接收媒体查询值变化的相关通知,那么,只要调用 MediaQueryListremoveListener() 方法,就可以方便地移除监听:

    mediaQueryList.removeListener(handleOrientationChange);