CSS媒体查询新特性

发布于 大漠

在探索A11YH5 Dark Mode的时候,我们发现使用CSS的一些属性可以识别出用户的偏好设置,比如prefers-reduced-motion来识别设备是否开启了Reduce Motion功能,用prefers-color-scheme来识别设备是否开启了Dark Mode模式。而这些都是CSS新的媒体特性,即 **Media Queries Level 5**规范中介绍的特性,该规范除了这两个新特之外,还有其他的新特性,接下来,我们来一起看看CSS媒体查询新增了哪些特性。

用户偏好设置

现在很多设备都提供了一些用户偏好的设置,就好比prefers-reduced-motionprefers-color-scheme提到的,就是可以识别出用户的偏好设置,从而调整网站的样式风格。简单地说呢?**Media Queries Level 5**提供的一些新特性非常注重个性化,它引入了不少于五个不同的新的媒体查询特性,让你调整你的Web页面或Web应用,让用户更喜欢。

prefers-color-scheme

你可能知道了,macOS系统和iOS13之后,苹果设备具备Dark Mode效果,就是用户可以根据自己的喜好来选择系统提供的色系:

在CSS中的媒体查询中提供了prefers-color-scheme媒体查询。该媒体查询特性可以让你对用户是否打开了设备上Dark Mode来做出反应。换句话说,给Web页面或应用添加Dark Mode只需要几行代码即可。

prefers-color-scheme用于检测用户的系统主题是浅色深色,它对应有三个值:

  • no-preference:表示用户未指定操作系统主题。其作为布尔值时以false输出
  • light:表示用户的操作系统是浅色主题
  • dark:表示用户的操作系统是深色主题

我们可以像下面这样来使用prefers-color-scheme

// dark.css 
:root { 
    --background-color: #111416;
    --text-color: #ccc; 
    --link-color: #f96; 
} 

// light.css 
:root { 
    --background-color: #fff; 
    --text-color: #333; 
    --link-color: #b52; 
} 

// style.css 
body { 
    background-color: var(--background-color); 
    color: var(--text-color); 
} 

a { 
    color: var(--link-color); 
}

比如下面这个示例:

如果你对Dark Mode方面感兴趣,想了解这方面更多的知识,可以花点时间阅读下面这几篇文章:

inverted-colors

在Dark Mode出现之前有些安卓设备有类似的功能:

但有些安卓设备中Dark Mode的效果实际就是粗暴的颜色反转或滤镜的一个效果:

不过有些用户可能喜欢这样的效果。它看起来很整洁,黑白之间的对比度更明显:

inverted-colors媒体查询特性让用户适应这些怪癖。该媒体查询特性可以接受两个值:

  • none:颜色显示正常
  • inverted:显示区域内的所有像素都被倒置了

inverted-colors是一个布尔值选项,但也可以直接跳过这个值,写成这样:

@media (inverted-colors) {
    img { 
        filter: invert(1); 
    }

    * { 
        box-shadow: none !important; 
        text-shadow: none !important; 
    }
}

prefers-reduced-motion

Web页面或应用难免少不了用一些动效来点缀,但有些用户不喜欢这些动画效果,甚至对于少数用户来说,这些动效会让他们身体不适。这就是为什么现在大多数设备都支持一种方法让用户根据自己的喜好来做设置。

使用prefers-reduced-motion媒体查询用于检测用户的系统是否被开启了动画减弱功能。该媒体查询特性接受两个值:

  • no-preference:用户未修改系统动画相关特性
  • reduce:这个值意味着用户修改了系统设置,将动画效果最小化,最好所有的不必要的移动都能被移除

下面的例子将会展示一组令人心烦的动画,不过当你开启了系统的“减少运动”后就能看到动画减弱的效果了。

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

.animation {
    animation: vibrate 0.3s linear infinite both; 
}

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

效果如下:

就上面的示例,如果设备开启了这方面的设置,那么animation就不会有动画效果。如果你对这方面知识感兴趣的话,还可以阅读下面相关的文章:

prefers-contrast

prefers-contrast媒体查询主要用于检测用户是否要求系统增加或减少相邻颜色之间的对比度。比如一些喜欢阅读电子书的用户,在阅读与文本背景对比度相差不大的文本时会遇到困难,他们更喜欢较大的对比度,利于阅读。

该媒体查询接受三个属性值:

  • no-preference:用户未向系统显式设置任何首选项。此关键字值在布尔上下文中计算为false
  • high:用户更喜欢对比度较高的界面
  • low:用户更喜欢对比度较低的界面

比如像下面这个小示例:

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

.contrast {
color: grey; 
}

@media (prefers-contrast: high) {
    .contrast {
        color: black;
    }
}

不过该媒体查询特性目前还没有用户代理实现,尽管各种操作系统都支持此类首选项,而且如果实现了此媒体查询,用户代理可能会依赖于操作系统提供的设置。

prefers-reduced-transparency

prefers-reduced-transparency媒体特性用于检测用户是否要求系统最小化它所使用的透明或半透明层效果。换句话说,一些操作系统提供了减少系统使用透明或半透明分层效果的选项。该媒体查询特性接受的值:

  • no-preference:用户未向系统显式设置任何首选项
  • reduce:用户更喜欢最小化透明或半透明层效果的界面

在实际中,你可以像下面这样使用:

.transparency {
    opacity: 0.5; 
}

@media (prefers-reduced-transparency: reduce) {
    .transparency {
        opacity: 1;
    }
}

prefers-reduced-data

这个媒体查询特性是非常有意思的一个功能。

你可能有过出差旅行的经历,也可能碰到了手机数据不够用,那么访问一个重图片的网站是很糟糕的(虽然说现在流量对于大家来说不是很大的事情,花钱总是有摆平的)。不过,一旦prefers-reduced-data得到支持,那么这个头痛的事情就可以避免了,也可以帮用户省下一定的费用。因为,该特性可以让用户跳过大图或高分辨率的图像。

该特性支持两个属性值:

  • no-preference:用户未显式向系统设置任何首选项
  • reduce:用户表示开启了对轻量级内容的设置选项

例如,一个站点可以通过提供更小的图像来满足打开数据保存模式的用户的偏好。

.image {
    background-image: url("images/heavy.jpg");
}

@media (prefers-reduced-data: reduce) {
    .image {
        background-image: url("images/light.jpg");
    }
}

forced-colors

forced-colors特性用于检测用户代理是否启用了强制颜色模式,该模式强制在页面上使用用户选择的有限颜色调色板。该特性支持两个属性值:

  • none:强制色彩模式不活跃,页面的颜色没有被限制在一个有限的调色板中
  • active:强制色彩模式已开启。UA将通过CSS系统颜色关键字为作者提供调色板,并在适当的情况下触发prefers-color-scheme的值,以便作者可以调整页面

比如下面这个示例:

<div class="colors">weird color box</div>

.colors {
    background-color: red;
    color: grey; 
}

@media (forced-colors: active) {
    .colors {
        background-color: white;
        color: black;
    }
}

环境媒体查询特性

我们总是会有在不同的环境下使用设备的情景。特别是用户在使用移动设备下,白天和晚上,特别是在阳光的环境下,体验是不完全不一样的,甚至有的时候无法很好的看清楚页面。不过,在不久的将来,这方面的体验就可以得到改善,因为CSS媒体查询除了能根据设备的设置提供不同的样式之外,还可以根据环境的不同给页面提供不同的样式。

light-level

light-level媒体查询特性就正如上面所说的,你可以根据用户是在白天还是晚上来调整Web页面或应用的样式。该特性接受三个值:

  • dim:该设备是在昏暗的环境中使用的。在这种环境中,过高的对比度和亮度会分散读者的注意力或让用户阅读时眼睛不舒服
  • normal:该设备是在一个环境中使用的光水平在理想的范围内,这并不需要任何特定的调整
  • washed:该设备是在非常明亮的环境下使用的,导致屏幕被洗掉,难以阅读

我们到时可以像下面这样使用:

@media (light-level: normal) {
    p {
        background: url("texture.jpg");
        color: #333;
    }
}

@media (light-level: dim) {
    p {
        background: #222;
        color: #ccc;
    }
}

@media (light-level: washed) {
    p {
        background: white;
        color: black;
        font-size: 2em;
    }
}

environment-blending

environment-blending媒体特性用于查询用户显示的特征,从而调整页面样式。开发者可以根据显示技术选择调整页面的视觉效果或布局,以增加吸引力或提高可读性。该特性接受三个值:

  • opaque:文档是在不透明的媒体上渲染,比如传统的显示器或纸张。黑色是暗的,白色是100%的光
  • additive:显示器混合画布的颜色与现实世界使用的添加剂混合。黑色是完全透明的,白色是100%的光,例如汽车上的平视显示器
  • subtractive:该显示器混合了画布的颜色与现实世界使用减色法混合。白色是完全透明的,而深色的对比度最大。例如,嵌入浴室镜子中的液晶显示屏

比如下面这个示例:

body { 
    background-color: white; 
}

p { 
    color: black; 
}

@media(environment-blending: additive) {
    body { 
        background-color: black; 
    }

    p { 
        color: white; 
        font-size: 16px; 
        font-weight: 1000; 
    }
}

自定义媒体查询

Media Queries Level 5最强大的一个特性是可编写脚本、可定制的媒体查询。其主要目的是通过创建映射到较长媒体查询的自定义媒体查询来避免重复。

自定义媒体查询一般使用@custom-media关键字指定,它看起来像下面这样:

@custom-media --medium-devices (min-width: 50rem);
@custom-media --large-landscape (min-width: 70rem) and (orientation: landscape);

@media (--medium-devices) {
    .container { max-width: 40rem; }
}

CSS工作组还计划将这些值编写成脚本,这将真正为媒体查询带来强大的功能。考虑一下这样的场景,当你可以使用@media (–logged-in)@media(–no-connection)媒体查询时,如何编写样式?

目前还没有任何浏览器支持这个功能,但是可以使用PostCSS插件

判断是否是触摸设备

@张鑫旭老师在《CSS any-hover any-pointer media查询与交互体验提升》一文中详细的介绍了如何使用CSS媒体查询来判断设备是否是触摸设备。比如文章中提到的hover可以根据用户的主要输入机制是否可以悬停在元素之上来应用样式。其值接受两个值:

  • none:主要输入机制无法悬停或不方便悬停(例如,当用户执行不方便的长按操作时,许多移动设备模拟悬停),或者没有主指示输入机制
  • hover:主要输入机制可以方便地悬停在元素上

我们在代码上可以像下面这样写:

@media (hover: hover) {
    a:hover {
        background: yellow;
    }
}

hover对应的还有any-hover媒体查询特性:

@media (any-hover: hover) {
    a:hover {
        background-color: #f5f5f5;
    }
}

另外还有pointerany-pointer媒体查询特性,主要肜来识别当前的环境,是否可以非常方便的进行点击操作:

@media (pointer: coarse) {
    input[type="checkbox"] {
        width: 30px;
        height: 30px;
    }
}

有关于这方面更详细的介绍可以阅读:

小结

媒体查询一直是CSS最有用的特性之一,但是Media Queries Level 5似乎带来了令人难以置信的进步和强大的特性。请注意,该规范中很多特性还没有得到浏览器的支持,而且还是处在草案阶段。也就意味着,在未来很有可能会有所变动,或者被放弃。

从好的方面来看,媒体查询可以让CSS优雅的做降级,这也意味着你可以现在就尝试使用这些媒体特性,就算还没有得到支持也无防,因为媒体查询块中的代码并不会破坏你的页面。而且这些特性中很多都是用来给用户提供更好的体验的,比如现在可以用于工程中的prefers-reduced-motionprefers-color-scheme,特别是prefers-color-scheme,让我们实现Dark Mode变得更容易。