# 媒体查询

# 基本用法

不同的屏幕,web 展示的效果可能不一样。那么就需要在一部分设备里使用一种样式,另一部分使用另一种样式,具体使用过“媒体查询”这一机制来实现的。

# html 中使用

在 html 中引用或使用不同媒体下的样式,需要用到media这个属性。如果没有加上media这个属性,那么 css 样式会应用到所有媒体上,也就是不区分媒体类型。media后面的值是媒体类型,后面会讲有哪些。

<!-- 引入外部的css文件,只适用于打印设备 -->
<link rel="stylesheet" type="text/css" href="xxx-print.css" media="print" />
<!-- 直接书写css样式,适用于电脑手机等设备 -->
<style type="text/css" media="screen">
  body {
  }
</style>
1
2
3
4
5
6
7

# css 中使用

在 css 中引用不同媒体下的其他css 样式,需要配合@import媒体类型的使用。

@import url(xxx.css) screen;
@import url(xxx.css) speech;
@import url(xxx.css) print;
1
2
3

在 css 中书写不同媒体对应不同样式时,需要配合@media媒体类型的使用。

<style type="text/css">
  /* 因为<style>中没有media属性,所以这是所有媒体 */
  body {
    background: white;
    color: black;
  }
  /* 文档阅读媒体,最常见的 */
  @media screen {
    body {
      font-family: sans-serif;
    }
    h1 {
      margin-top: 1em;
    }
  }
  /* 打印媒体 */
  @media print {
    body {
      font-family: serif;
    }
    h1 {
      margin-top: 2em;
      border-bottom: 1px solid silver;
    }
  }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 媒体类型

# 四种常见媒体类型

以下是四种常见的媒体,h4 时代定义了很多媒体类型现在大多弃用了。

媒体类型 说明
all 所有内呈现内容的媒体
print 打印给非盲用户看的文档,或者是文档的打印预览
screen 呈现文档的屏幕媒体,例如电脑和手机等。运行在这种系统上的 web 浏览器是屏幕媒体的用户代理
speech 语音合成器、屏幕阅读器或其他音频渲染设备

# and、not 和逗号

可能有时候需要使用到复合媒体(其中两种媒体类型共用样式比较多),那么可以在media中的值穿插逗号,,有些类似or的意思,但media中是没有or的。

<link rel="stylesheet" type="text/css" href="xxx-print.css" media="screen, print" />

<style type="text/css">
  @import url(xxx.css) screen, print;

  @media screen, print {
  }
</style>
1
2
3
4
5
6
7
8

有使用在媒体中某个特定条件下使用样式,那么可以在使用media搭配and来使用,and后面接的是媒体特性(下一节会讲)。

<!-- 彩色打印,黑白的打印就不行 -->
<link rel="stylesheet" type="text/css" href="xxx-print.css" media="print and (color)" />

<style type="text/css">
  @import url(xxx.css) print and (color);

  @media print and (color) {
  }
</style>
1
2
3
4
5
6
7
8
9
<!-- 彩色打印 或者 彩色屏幕,黑白的不行 -->
<link rel="stylesheet" type="text/css" href="xxx-print.css" media="print and (color), screen and (color)" />

<style type="text/css">
  @import url(xxx.css) print and (color), screen and (color);

  @media print and (color), screen and (color) {
  }
</style>
1
2
3
4
5
6
7
8
9

说了逗号和and后,还剩下一个not,它是对整个查询结果取反,这个not是放在查询开头的,不像and是穿插在媒体特性之间的。

<html>
  <head>
    <style type="text/css">
      /* 分辨率大于或等于72点每英寸的显示屏上 */
      @media screen and (min-resolution: 72dpi) {
        .cl01 {
          font-style: italic;
        }
      }
      /* 分辨率大于或等于32767点每英寸的显示屏上 */
      @media screen and (min-resolution: 32767dpi) {
        .cl02 {
          font-style: italic;
        }
      }
      /* 不在打印媒体上时(或不打印预览时) */
      @media not print {
        .cl03 {
          font-style: italic;
        }
      }
      /* 即不在打印媒体上也不是灰度设备 */
      @media not print and (grayscale) {
        .cl04 {
          font-style: italic;
        }
      }
      .arena p[class]::before {
        content: "[." attr(class) "] ";
      }
    </style>
  </head>
  <body>
    <div class="arena">
      <p class="cl01">This is the first paragraph.</p>
      <p class="cl02">This is the second paragraph.</p>
      <p class="cl03">This is the third paragraph.</p>
      <p class="cl04">This is the fourth paragraph.</p>
    </div>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 媒体特性

媒体特性要放在()里使用,其取值基本上都不会是负数,下面列出一些媒体特性:

媒体特性 取值
width, min-width, max-width <length>,用户代理(浏览器)显示区域宽度(包含滚动条)。例如(min-width: 850px)在视区宽度大于或等于 850px 时起作用。
height, min-height, max-height <length>,用户代理(浏览器)显示区域高度(包含滚动条)。例如(height: 567px)在视区高度正好是 567px 时起作用。
device-width, min-device-width, max-device-width <length>,设备屏幕宽度。例如(max-device-width: 1200px)在设备屏幕宽度小于或等于 1200px 时起作用。
device-height, min-device-height, max-device-height <length>,设备屏幕高度。例如(max-device-height: 400px)在设备屏幕高度小于或等于 400px 时起作用。
aspect-ratio, min-aspect-ratio, max-aspect-ratio <ratio>,媒体特性 width 与媒体特性 height 的比值。例如(min-aspect-ratio: 2/1)在视区的宽高比大于或等于 2 时起作用。
device-aspect-ratio, min-device-aspect-ratio, max-device-aspect-ratio <ratio>,媒体特性 device-width 与媒体特性 device-height 的比值。例如(device-aspect-ratio: 16/9)在设备屏幕的宽高比正好是16:9时起作用。
color, min-color, max-color <integer>,判断媒体是否支持彩色显示,可选的数值表示每个色彩分量使用的位数。例如(color)在媒体具有色彩深度时就起作用。例如(min-color: 4)每个色彩分量至少有 4 位时起作用。
color-index, min-color-index, max-color-index <integer>,媒体色彩搜寻列表中共用的颜色。例如(color-index)在媒体具有色彩搜寻列表时就起作用。例如(min-color-index: 256)在至少 256 个颜色可用的媒体中时起作用。
monochrome, min-monochrome, max-monochrome <integer>,判断显示屏是不是单色,可选的数值表示在输出设备的帧缓冲器中每像素有多少位。例如(monochrome)在单色的输出设备时就起作用。例如(min-monochrome: 2)输出设备的帧缓冲器中每像素至少为 2 时起作用。
resolution, min-resolution, max-resolution <resolution>,指以像素密度表示的输出设备的分辨率(每英寸有多少像素点,dpi)。例如(min-resolution: 72dpi)在输出设备分辨率至少为 721dpi 时起作用。
orientation portraitlandscape,指用户代理的显示区域放置的方向。媒体特性 height 大于或等于 width(不是设备屏幕宽高),返回portrait,否则返回landscape
scan progressiveinterlace,指输出设备使用的扫描方式。CRT 和某些等离子显示屏一般使用interlace,而多数现代的显示屏是使用progressive
grid 01,判断是否为基于网格的输出设备(例如 TTY 终端)。基于网格返回1,否则返回0

# 断点设置

在屏幕大小不一的情况下,我们会使用媒体查询的断点来设置临界条件,列如将屏幕分为大屏中屏小屏等。断点经常以特定大小的像素宽度形式表示的(pxem等)。

/* 至多400px宽度时 */
@media screen and (max-width: 400px) {
}
/* 401px到1000px宽度时 */
@media screen and (min-width: 401px) and (max-width: 1000px) {
}
/* 至少1001px宽度时 */
@media screen and (min-width: 1001px) {
}
1
2
3
4
5
6
7
8
9

当然有些设备可以横向或者竖向展示,那么使用断点配合orientation媒体特性是很有必要的。