CSS前端

我不知道的媒体查询

· 7min

起因

由于对于 CSS 没有很多深入的了解,技能能满足平时画画页面也没有那么关注 CSS 的一些新特性。前两天在实现代码块 Copy 功能的时候想实现一个效果。

当鼠标在代码块内的时候显示出 Copy Button ,移出的时候不显示。移动端就让他一直能显示这个按钮

前面的在鼠标在内显示出来很容易,通过 hover 这个伪类就能实现。移动端不显示开始我想到了两种解决方式,嗯看起来都能解决问题

  • 使用 @media 根据屏幕尺寸判断
  • 通过 User-Agent 来判断

媒体查询

决定使用媒体查询的方式来实现,使用 User-Agent 需要用 js 感觉没必要就准备上 MDN 看看 @media 的语法的(用得少现用现看),不看不知道原来媒体查询有这么多能力了,有非常多我没使用过的查询能力。

媒体查询基本语法

一般媒体查询的基本语法由媒体类型(可选,默认 all ) + 媒体规则 + CSS组成,比如下面的意思就是:视口等于 750 像素的时候,让 body 的背景变成红色。还可以使用逻辑运算符进行组合。

@media screen and (width: 750px) {
  body {
    background: red;
  }
}

复制成功!

@media screen and (width: 750px) {
  body {
    background: red;
  }
}

复制成功!

媒体类型、特性

目前能用的媒体类型有

  • all
  • print 打印模式
  • screen 屏幕设备
  • speech 语音合成器(应该是朗读设备之类的)

媒体规则

下面是 MDN 上列出目前存在的媒体规则,发现除了我常用的宽度、配色方案等几个之外还有很多没用过的内容

简介
any-hover是否有任何可用的输入机制允许用户(将鼠标等)悬停在元素上。在 Media Queries Level 4 中被添加。
any-pointer可用的输入机制中是否有任何指针设备,如果有,它的精度如何(coarse-粗糙、fine-精细)?在 Media Queries Level 4 中被添加。
aspect-ratio视口(viewport)的宽高比。
color输出设备每个像素的比特值,如果设备不支持输出彩色,则该值为 0。
color-gamut用户代理和输出设备大致程度上支持的色域。在 Media Queries Level 4 中被添加。
color-index输出设备的颜色查询表(color lookup table)中的条目数量,如果设备不使用颜色查询表,则该值为 0。
device-aspect-ratio输出设备的宽高比。已在 Media Queries Level 4 中被弃用。
device-height输出设备渲染表面(如屏幕)的高度。已在 Media Queries Level 4 中被弃用。
device-width输出设备渲染表面(如屏幕)的宽度。已在 Media Queries Level 4 中被弃用。
display-mode应用程序的显示模式,如 web app 的 manifest 中的 display 成员所指定。在 Web App Manifest spec 中被定义。
dynamic-range用户代理和输出设备支持的亮度、对比度和颜色深度的组合。在 Media Queries Level 5 中被添加。
forced-colors检测用户代理是否限制调色板。在 Media Queries Level 5 中被添加。
grid输出设备使用网格屏幕还是点阵屏幕?
height视口的高度。
hover主输入机制是否允许用户在元素上悬停。在 Media Queries Level 4 中被添加。
inverted-colors用户代理或者底层操作系统是否反转了颜色。在 Media Queries Level 5 中被添加。
monochrome输出设备单色帧缓冲区中每个像素的位深度。如果设备并非黑白屏幕,则该值为 0。
orientation视口的旋转方向。
overflow-block输出设备如何处理沿块轴溢出视口的内容。在 Media Queries Level 4 中被添加。
overflow-inline沿内联轴溢出视口的内容是否可以滚动。在 Media Queries Level 4 中被添加。
pointer主输入机制是一个指针设备吗?如果是,它的精度如何?在 Media Queries Level 4 中被添加。
prefers-color-scheme检测用户倾向于选择亮色还是暗色的配色方案。在 Media Queries Level 5 中被添加。
prefers-contrast检测用户是否有向系统要求提高或降低相近颜色之间的对比度。在 Media Queries Level 5 中被添加。
prefers-reduced-motion用户是否希望页面上出现更少的动态效果。在 Media Queries Level 5 中被添加。
resolution输出设备的像素密度(分辨率)。
scripting检测脚本(例如 JavaScript)是否可用。在 Media Queries Level 5 中被添加。
update输出设备修改渲染内容的频率 (none、slow、fase)。在 Media Queries Level 4 中被添加。
video-dynamic-range用户代理的视频平面(video plane)和输出设备支持的亮度、对比度及颜色深度的组合。在 Media Queries Level 5 中被添加。
width视口的宽度,包括纵向滚动条的宽度。

上面的部分规则是表示范围性的,可以使用 min max 来表示范围, 或者 <= 简单写,比如下面两条 CSS 是等效的

@media (min-width: 750px) and (max-width: 1280px) { ... }
@media (750px <= width <= 1280px ) { ... }

复制成功!

@media (min-width: 750px) and (max-width: 1280px) { ... }
@media (750px <= width <= 1280px ) { ... }

复制成功!

逻辑运算符

通过逻辑操作符,就能够构造出更加复杂的媒体查询,目前支持的运算符:

  • and
  • or(,)
  • not
  • only 仅在整个查询匹配时才用于应用样式,可以解决较早的浏览器应用所选样式。比如当不使用 only 时,旧版本的浏览器会将 screen and (max-width: 500px) 简单地解释为 screen,忽略查询的其余部分,并将其样式应用于所有屏幕。

更好的解决方式

通过前面的媒体规则不难发现 hover 这个规则使用在这里就非常合适

/* 默认显示按钮 */
.copy-button {
  opacity: 1;
}
/* 如果支持 hover 就默认不显示 */
@media (hover: hover) {
  .copy-button {
    opacity: 0;
  }
}

复制成功!

/* 默认显示按钮 */
.copy-button {
  opacity: 1;
}
/* 如果支持 hover 就默认不显示 */
@media (hover: hover) {
  .copy-button {
    opacity: 0;
  }
}

复制成功!

最后

MDN 我的 CSS 就指着你了,内容参考 Using_media_queries