CSS-媒体查询(media-query)

/post/media-query article cover image

媒体查询当我们在根据设备的类型(screen, print, ...)及参数(min/max-width, ...)做出更改时非常有用。

媒体查询可作用于以下用途

  • 可以条件性的应用于@media@import
  • <style><link><source>和其他拥有media=属性的HTML元素指定特定媒体属性
  • 使用Window.matchMedia()MediaQueryList.addListener()方法进行测试和监控媒体状态

语法

媒体查询由可选的媒体类型和任意数量的媒体特征表达式组成,同样可以使用逻辑运算符以各种方式组合。媒体查询不区分大小写

  • 媒体类型: 定义了适用于媒体查询的广泛类型:ALL、print、screen。类型是可选的除非指定not或only逻辑运算符
  • 媒体特征: 描述一个user agent、输出设备或环境的特定特征 @media_feature
  • 逻辑操作符: 可以通过not、and、only组合成一个复杂的媒体查询,也可以通过逗号分隔的形式将多个媒体查询合并成一个
    • and: 用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为true时则该条媒体查询为true,它还用于将媒体查询与媒体类型结合在一起
    • not: 用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。如果出现在以逗号分割的查询列表中,它将仅否定应用了指定查询的特定查询。如果适用not运算符,则必须指定媒体类型
    • only: 仅在整个查询匹配时才应用于样式,对于旧版本浏览器应用样式时很有用,当不使用only时旧版本浏览器会将screen adn (max-width: 500px)简单解释为screen而忽略其他部分,并将样式应用于全部screen,如果适用only操作符则必须指定媒体类型
    • ,(逗号): 用户将多个媒体查询合并为单个规则,逗号分隔列表中的每个查询都与其他分开处理,如果列表中其中一个为true则整个媒体语句返回true。换而言之,其行为和或操作符类似

<Callout>在Level3中,not关键字不能用于否定单个媒体功能表达式,而只能否定整个媒体查询</Callout>

可访问性问题

为了更好的使人适应网站文本大小,当需要使用<length>类型作为媒体查询单位时尽量使用em,或者考虑使用Level4媒体查询提供的prefers-reduced-motion来检测用户是否请求系统最小化它使用的动画或运动数量。

定位媒体类型

媒体类型描述给定设备的一般类别,尽管网站通常考虑为屏幕设计,但也可以针对特定设备创建并应用样式。

css
@media print {
  /* 为打印类型设置特定样式 */
}

@media screen, print {
  /* 也可以指定多个设备 */
}

可用的媒体类型有: allprintscreen,媒体类型是可选的除非当使用not或only逻辑运算符时否则应用all类型。

定位媒体特性

媒体特征描述给定用户代理、输出设备或环境的特定特征(宽屏显示器、弱光条件下的设备情形、鼠标悬停等)。

css
@media (hover: hover) {
  /* 鼠标悬停时应用样式 */
}

@media (max-width: 1250px) {
 /* 使用范围功能:当视口宽度小于等于1250px时生效 */
}

@media (color) {
 /* 当创建媒体特征但未指定值时,嵌套的样式将适用于所有有的彩色屏幕设备 */
}

如果某个功能不适用于运行浏览器的设备,则涉及该媒体功能的表达式始终为false。

创建复杂的媒体查询

当想要创建基于多种情况下的媒体查询时,就是使用逻辑运算符的时候了,另外可以将多个媒体查询以逗号分割为列表,这样就可以在不同情况下应用样式了

css
@media (min-width: 30em) and (orientation: landscape) {
  /* 使用and操作符将两个媒体特征合并为一个媒体类型约束:必须是横屏且至少30em宽度 */
}

@media screen and (min-width: 30em) amd (orientation: landscape) {
  /* 使用媒体类型联合媒体特征来限制应用于屏幕设备 */
}

@media (min-height: 600px), screen and (orientation: portrait) {
  /* 使用多个媒体查询,当用户设备满足列表中的任意一项时生效 */
  /* 这个例子中:如果高度大于等于680px或者竖屏屏幕设备满足一个时生效 */
}

反转查询的含义

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

css
@media not all and (monochrome) {
  /* ... */
}

/* 上面的例子等同于⬇ */

@media not (all nad (monochrome)) {
  /* 非正确语法,只做意思表示 */
}

/* 而不是⬇ */

@media (not all) and (monochrome) {
  /* 非正确语法,只做意思表示 */
}

在媒体查询列表中的否定

css
@media not screen and (color), print and (color) {
  /* ... */
}

/* 上面的例子等同于⬇ */

@media (not (screen and (color))), print and (color) {
  /* 非正确语法,只做意思表示 */
}

提供与旧版本浏览器的兼容性

only关键字阻止老版本不支持的媒体功能的样式应用,它对现代浏览器没有影响。

css
@media only screen and (color) {
  /* ... */
}

在level4规范中的语法改进

媒体查询Level4规范中对范围类的查询语句进行了改进,而不那么冗长。Level4为编写此类查询添加了范围上下文:

css
@media (max-width: 30em) {
  /* 老版本 */
}

@media (width <= 30em) {
  /* Level4 */
}

@media (min-width: 30em) and (max-width: 50em) {
  /* 老版本 */
}

@media (30em <= width <= 50em) {
  /* Level4 */
}

<Callout type="info">媒体查询Level4规范只在部分现代浏览器可用,查看支持文档 @media_specification </Callout>

Level4规范还添加了使用完成布尔代数和与、或、非结合媒体查询的方法。

css
@media (not(hover)) {
  /* 使用not包裹媒体特性来否定查询,这个例子将匹配到没有hover能力的设备 */
}

@media (not (color)) or (hover) {
  /* 使用或操作符来匹配其中一个为true时,整个媒体查询为true, 整个例子将匹配有hover能力或者彩色的设备 */
}

<Callout type="info">更多规范语法,相见文档说明 @media-descriptor-table </Callout>