媒体查询

0x00 简介

前文 📚 Layout 拾遗 提到了栅格布局系统中响应式布局的实现方式媒体查询,本文将对其深入分析, 耐心读完,相信会对您有所帮助。

0x01 媒体查询

媒体查询Media queries)是实现响应式设计的最常见方法,它可以让我们根据设备的大致类型(如打印、手机、平板或电脑等)或者特定的特征和设备参数(例如屏幕分辨率和浏览器视口宽度)来调整网站或应用。 例如,缩小小型设备上的字体大小,判断手机朝向(横屏或竖屏)等。

CSS 语法

媒体查询语法通常使用 @media(@规则), 可用于基于一个或多个媒体查询的结果来应用样式表。 通过指定的媒体类型与正在显示文档的设备类型匹配,并且媒体查询中的所有表达式均为 true,将应用样式规则。

// 媒体类型   媒体特性表达式
@media media-type and (media-feature-rule) {
  /* CSS rules go here */
}

媒体类型

媒体类型Media types)描述设备的一般类别。可以指定的媒体类型为:

  • all 适用于所有设备。

  • print 适用于在打印预览模式下。

  • screen 主要用于屏幕(计算机屏幕、平板电脑、智能手机)。

  • speech 主要应用于屏幕阅读器等发声设备。

在不使用 notonly 操作符的情况下,媒体类型是可选的,默认为 all

媒体特性

媒体特性Media features)描述了 user agent、输出设备,或是浏览环境的具体特征。媒体特性表达式是完全可选的,它负责测试这些特性或特征是否存在、值为多少。每条媒体特性表达式都必须用括号括起来。

最常用的特性是视口宽度,可以使用min-width最常用)、max-widthwidth媒体特性,在视口宽度大于或者小于某个大小——或者是恰好等于某个大小——的时候,应用 CSS 样式规则。

逻辑运算符

逻辑操作符logical operators) 使用 not, and, only, (逗号) 构建复杂的媒体查询。

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

  • not运算符用于否定媒体查询,如果不满足这个条件则返回 true,否则返回 false。 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。 not关键字不能用于否定单个媒体功能表达式,而只能用于否定整个媒体查询。

  • only 运算符仅在整个查询匹配时才用于应用样式,并且对于防止老式浏览应用所选样式很有用。

  • , 逗号将多个媒体查询合并为一个规则。 逗号分隔列表中的每个查询都与其他查询分开处理。 因此,如果列表中的任何查询为 true,则整个 @media 语句均返回 true。 换句话说,列表的行为类似于逻辑或or运算符。

使用 not, only 运算符,必须指定媒体类型

在老式浏览器中将@media only screen and (min-width: 992px) {...} 简单地解释为only,因为没有叫 only 的设备,所以老式浏览器不会应用样式。 当不使用only时,将@media screen and (min-width: 992px) {...}简单地解释为screen,忽略查询的其余部分,应用样式。

0x02 断点

断点(Breakpoints) 是响应式设计的基石。 它是可自定义的宽度,使用它可以控制何时可以在特定视口或设备大小下调整布局。

断点设置

参照了 Bootstrap 的 响应式设计,预设了五个响应尺寸:xssmmdlgxl

断点
类中缀
分辨率
设备

X-Small

xs

<767px

超小屏幕 手机

Small

sm

≥768px

小屏幕 平板

Medium

md

≥992px

中等屏幕 桌面显示器

Large

lg

≥1200px

大屏幕 大桌面显示器

Extra large

xl

≥1920px

超大屏幕 大桌面显示器

在文件 theme-chalk\src\common\var.scss 定义了这些断点。

0x03 组件响应式实现

@mixin res()

在文件 theme-chalk\src\mixins\mixins.scss 定义了指令 res构建 css,使用媒体查询来创建关键的分界点阈值。

指令功能逻辑如下:

  1. 指令 res 接受两个参数 $key(响应尺寸) 和 $map(断点 Map)。

  2. 指令内部使用函数 map-has-key($map,$key) 作用是根据 $key 参数,返回 $key$map 中对应的 value 值。如果 $key 不存在 $map中,将返回 null 值(此时生成警告断点未定义 Undefeined points )。

  3. 若返回 true,使用函数 map-get($map,$key) 返回 $key$map 中对应的 value 值。

  4. 使用函数 inspect($value) 将其转成字符串,使用插值 #{}@content 生成 媒体查询。

在栅格系统中,媒体查询通过断点构建 CSS。响应式布局五个响应尺寸样式如下:

0x04 基于断点的隐藏实现

Element 额外提供了一系列类名,用于在某些条件下隐藏元素。

使用方式

首先,项目引入样式文件:

然后将这些类名可以添加在任何 DOM 元素或自定义组件上。

  • hidden-xs-only - 当视口在 xs 尺寸时隐藏

  • hidden-sm-only - 当视口在 sm 尺寸时隐藏

  • hidden-sm-and-down - 当视口在 sm 及以下尺寸时隐藏

  • hidden-sm-and-up - 当视口在 sm 及以上尺寸时隐藏

  • hidden-md-only - 当视口在 md 尺寸时隐藏

  • hidden-md-and-down - 当视口在 md 及以下尺寸时隐藏

  • hidden-md-and-up - 当视口在 md 及以上尺寸时隐藏

  • hidden-lg-only - 当视口在 lg 尺寸时隐藏

  • hidden-lg-and-down - 当视口在 lg 及以下尺寸时隐藏

  • hidden-lg-and-up - 当视口在 lg 及以上尺寸时隐藏

  • hidden-xl-only - 当视口在 xl 尺寸时隐藏

实现原理

文件 theme-chalk\src\common\var.scss 定义了隐藏类断点 Map$--breakpoints-spec ,使用逻辑运算符 and,让媒体查询能跨越多个断点宽度。

转译后内容如下,定了关于视口宽度的各种媒体查询规则。

使用指令 res 生成带前缀 hidden的隐藏类。隐藏类 CSS 规则 display: none !important; 用于隐藏元素。

最终生成 display.css,内容如下:

0x05 📚 参考

“使用媒体查询”,MDN “Media_queries”,MDN "@规则",MDN screen sizes “sass 在线编辑器”,sassmeister.com

最后更新于