跳到主要内容

基础-媒体查询

CSS2 中就存在了媒体查询, 在 CSS3 中新增了媒体属性和使用场景.

media 属性用于为不同的媒介类型规定不同的样式

媒介类型

关键字描述
screen计算机屏幕(默认值)
tty电传打字机以及使用等宽字符网格的类似媒介
tv电视类型设备(低分辨率、有限的屏幕翻滚能力)
projection放映机
handheld手持设备(小屏幕、有限的带宽)
print打印预览模式 / 打印页
braille盲人用点字法反馈设备
aural语音合成器
all适合所有设备

其中用的比较广泛的就是screenall了.

媒体属性

媒体属性是 css3 新增的内容, 多数媒体属性含有"min-"和"max-"前缀, 用于小于等于或大于等于, 这避免使用 HTML 和 XHTML 冲突的"<"和">"字符.

[注意]媒体属性必须要用括号包起来, 否则是无效的:

width | min-width | max-width
height | min-height | max-height
device-width | min-device-width | max-device-width
device-height | min-device-height | max-device-height
aspect-ratio | min-aspect-ratio | max-aspect-ratio
device-aspect-ratio | min-device-aspect-ratio max-device-aspect-ratio
color | min-color | max-color
color-index | min-color-index | max-color-index
monochrome | min-monochrome | max-monochrome
resolution | min-resolution | max-resolution
scan | grid

颜色(color)

指定输出设备每个像素单元的比特值。如果设备不支持输出颜色,则该值为 0

@media (color) {
.box {
}
}

颜色索引(color-index)

颜色索引指定了输出设备中颜色查询表中的条目数量, 如果没有使用颜色查询表, 则等于 0.

@media (min-color-index: 256) {
.box {
}
}

宽高比(aspect-ratio)

输出设备目标显示区域的宽高比

@media (min-aspect-ratio: 1/1) {
.box {
}
}

设备宽高比(device-aspect-ratio)

描述了输出设备的宽高比:

@media (device-aspect-ratio: 16/9) {
.box {
}
}

设备高度(device-height)

设备高度描述了输出设备的高度

@media (min-device-height: 1000px) {
.box {
}
}

设备宽度(device-width)

输出设备的宽度

@media (min-device-width: 1000px) {
.box {
}
}

网格(grid)

网格判断输出设备是网格设备还是位图设备

@media (grid: 0) {
.box {
}
}

高度(height)

输出设备渲染区域(如可视区域的高度或打印机纸盒的高度)的高度

@media (min-height: 800px) {
.box {
}
}

宽度(width)

宽度描述了输出设备渲染区域的宽度

@media (min-width: 800px) {
.box {
}
}

黑白(monochrome)

黑白指定了一个黑白(灰度)设备每个像素的比特数。如果不是黑白设备,值为 0

@media (monochrome: 0) {
.box {
}
}

方向(orientation)

方向指定了设备处于横屏(宽度大于宽度)模式还是竖屏(高度大于宽度)模式

值:landscape(横屏) | portrait(竖屏)

@media (orientation: portrait) {
.box {
}
}

分辨率(resolution)

分辨率指定输出设备的分辨率(像素密度)。分辨率可以用每英寸(dpi)或每厘米(dpcm)的点数来表示.

@media (min-resolution: 90dpi) {
.box {
}
}

扫描(scan)

扫描描述了电视输出设备的扫描过程

值: progressive | interlace

减弱动画效果(prefers-reduced-motion)

prefers-reduced-motion规则用于减弱动画效果, 除了默认规则, 只有一种语法取值:

prefers-reduced-motion: reduce

开启该规则相当于告诉用户代理, 希望他看到的页面可以删除或者替换掉一些会让部分视觉障碍者不适的动画类型.

.ele {
animation: aniName 5s infinite linear;
}

@media (prefers-reduced-motion: reduce) {
.ele {
animation: none;
}
}

如何在浏览器中开启(link):

  • 在 GTK/Gnome 中,可以通过 GNOME Tweaks(在“通用”或“外观”菜单中,取决于具体版本)的配置,设置 gtk-enable-animations 的值为 false。
  • 可以在 GTK 3 的配置文件中的 [Settings] 模块下设置 gtk-enable-animations = false。
  • 在 Windows 10 中:设置 > 轻松获取 > 显示 > 在 Windows 中显示动画。
  • 在 Windows 7 中:控制面板 > 轻松获取 > ?是计算机更易于查看 > 关闭不必要动画。
  • 在 MacOS 中:系统偏好 > 辅助使用 > 显示 > 减少运动。
  • 在 iOS 上:设置 > 通用 > 辅助性 > 减少运动。
  • 在 Android 9+ 上:设置 > 辅助性 > 移除动画。

适配明暗主题(prefers-color-scheme)

用于匹配操作系统设置的明亮或者夜间模式:

  • prefers-color-scheme: light: 浅色模式
  • prefers-color-scheme: dark: 深色模式
body {
background: white;
color: black;
}

@media (prefers-color-scheme: dark) {
body {
background: black;
color: white;
}
}

调整内容色彩对比度(prefers-contrast)

  • prefers-contrast: no-preference:默认值,不作任何变化
  • prefers-contrast: less:希望使用对比度更低的界面
  • prefers-contrast: more:希望使用对比度更高的界面
body {
background: #fff; // 文字与背景对比度为 5.74
color: #666;
}

// 提升对比度
@media (prefers-contrast: more) {
body {
background: #fff; // 文字与背景对比度为 21
color: #000;
}
}

或者是可以使用filter: contrast()全局统一处理.

减少透明元素(prefers-reduced-transparency)

该查询用于检测用户是否要就减少网页中的透明元素.

  • prefers-contrast: no-preference: 默认值,不作任何变化
  • prefers-contrast: reduce: 希望界面元素存在尽可能少的透明元素
.ele {
opacity: 0.5;
}

// 减少透明元素
@media (prefers-contrast: reduce) {
.ele {
opacity: 1;
}
}

减少数据传输(prefers-reduced-data)

prefers-reduced-data该 CSS 媒体查询功能是用于告知用户代理,希望减少页面的流量请求:

  • prefers-reduced-data: no-preference: 默认值,不作任何变化
  • prefers-reduced-data: reduce: 希望界面元素消耗更少的互联网流量
.ele {
background-image: url(image-1800w.jpg);
}

/* 降低图片质量 */
@media (prefers-reduced-data: reduce) {
.ele {
background-image: url(image-600w.jpg);
}
}

需要chrome 85+并且开启是现实功能.

语法

标签使用:

<link rel="stylesheet" href="style.css" media="print" />

<div class="box"></div>

逻辑操作符

操作符 not、and、only 和逗号(,)可以用来构建复杂的媒体查询

and

and 操作符用来把多个媒体属性组合起来,合并到同一条媒体查询中。只有当每个属性都为真时,这条查询的结果才为真

[注意]在不使用 not 或 only 操作符的情况下,媒体类型是可选的,默认为 all

满足横屏以及最小宽度为 700px 的条件应用样式表

@media all and (min-width: 700px) and (orientation: landscape) {
}

or

@media (min-width: 700px), handheld and (orientation: landscape) {
}

not

[注意]not 关键字仅能应用于整个查询,而不能单独应用于一个独立的查询

@media not all and (monochrome) {
}
//等价于
@media not (all and (monochrome)) {
}

only

only 操作符表示仅在媒体查询匹配成功时应用指定样式。可以通过它让选中的样式在老式浏览器中不被应用

@media only screen and (max-width:1000px)' {

}

方法

window.matchMedia()

用来检查 CSS 的 mediaQuery 语句

[注意]IE9-浏览器不支持,可以使用第三方函数库 matchMedia.js

var result = window.matchMedia('(min-width: 600px)');
console.log(result.media); //'(min-width: 600px)'
console.log(result.matches); // true
  • media: 返回所查询的 mediaQuery 语句的字符串
  • matches: 返回当前环境是否匹配

如果无法解析 mediaQuery 参数, 也会返回 false.

除此之外, 还可以设置监听事件:

// 指定回调函数
mql.addListener(mqCallback);
// 撤销回调函数
mql.removeListener(mqCallback);

注意,只有 mediaQuery 查询结果发生变化时,才调用指定的回调函数

所以,如果想要 mediaQuery 查询未变化时,就显示相应效果,需要提前调用一次函数

下面这个例子是当页面宽度小于 1000px 时,页面背景颜色为品红色;否则为淡蓝色

var mql = window.matchMedia('(min-width: 1000px)');
mqCallback(mql);
mql.addListener(mqCallback);
function mqCallback(mql) {
if (mql.matches) {
document.body.background = 'pink';
} else {
document.body.background = 'lightblue';
}
}

打印样式

媒体查询的一个常用功能是打印样式的设置,主要是背景清除、字体颜色变黑等

@media print {
*,
*:before,
*:after {
background: transparent !important;
color: #000 !important;
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: '(' attr(href) ')';
}
abbr[title]:after {
content: '(' attr(title) ')';
}
a[href^='#']:after,
a[href^='javascript:;']:after {
content: '';
}
pre,
blockquote {
border: 1px solid #999;
/*只有opera浏览器起作用,避免在元素内部插入分页符*/
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
/*元素内部发生分页时,最少保留3行*/
orphans: 3;
/*元素内部发生分页时,元素顶部最少保留3行*/
windows: 3;
}
h2,
h3 {
/*避免在元素后面插入一个分页符*/
page-break-after: avoid;
}
}

相对单位

如果媒体查询@media 使用的是相对单位,如 rem,这里有一个坑需要着重强调一下

一般而言,rem 是相对于 HTML 的字体大小的。但是,由于媒体查询的级别非常高,它并不是 HTML 的子元素,不是相对于 HTML,而是相对于浏览器的,而浏览器的默认字体大小是 16px

如果 HTML 设置字体大小为 12px,设置如下媒体查询

@media only screen and (max-width: 1rem);

实际上,max-width 等于 16px,而不是 12px

而正是由于媒体查询是相对于浏览器的, 所以使用 rem 就没有必要,完全可以使用 em 来替代

@media only screen and (max-width: 1em);

参考链接