我们依赖于 CSS 媒体查询 来根据目标条件选择和设置元素的样式。 该条件可以是各种各样的东西,但通常分为两类:(1)正在使用的媒体类型,以及(2)浏览器、设备甚至用户环境的特定功能。
因此,假设我们要对打印文档应用某些 CSS 样式
@media print {
.element {
/* Style away! */
}
}
我们可以根据特定视窗宽度应用样式,这一事实使 CSS 媒体查询成为响应式网页设计的核心要素,自 Ethan Marcotte 创造了这个词 以来。 如果浏览器的视窗宽度为特定大小,则应用一组样式规则,这使我们能够设计响应于浏览器大小的元素。
/* When the viewport width is at least 30em... */
@media screen and (min-width: 30em) {
.element {
/* Style away! */
}
}
注意其中的 and
吗? 这是一个运算符,允许我们组合语句。 在该示例中,我们将媒体类型为 screen
且 min-width
特性设置为 30em
(或更高)的条件组合在一起。 我们可以做同样的事情来定位视窗大小范围
/* When the viewport width is between 30em - 80em */
@media screen and (min-width: 30em) and (max-width: 80em) {
.element {
/* Style away! */
}
}
现在,这些样式适用于显式的视窗宽度范围,而不是单个宽度!
但媒体查询级别 4 规范引入了一种新的语法,用于使用常见的数学比较运算符来定位视窗宽度的范围——例如 <
、>
和 =
——在编写代码时,这些运算符在语法上更有意义,同时代码更少。
让我们深入了解它的工作原理。
新的比较运算符
最后一个例子很好地说明了我们如何通过使用 and
运算符组合条件来“伪造”范围。 媒体查询级别 4 规范中的重大变化是,我们有了新的运算符来比较值,而不是组合它们
<
评估一个值是否小于另一个值>
评估一个值是否大于另一个值=
评估一个值是否等于另一个值<=
评估一个值是否小于或等于另一个值>=
评估一个值是否大于或等于另一个值
以下是我们如何编写一个媒体查询,如果浏览器宽度为 600px
或更大,则应用样式
@media (min-width: 600px) {
.element {
/* Style away! */
}
}
以下是使用比较运算符编写相同内容的方式
@media (width >= 600px) {
.element {
/* Style away! */
}
}
定位视窗宽度范围
通常,当我们编写 CSS 媒体查询时,我们创建的是所谓的 断点——设计“中断”并应用一组样式来修复它的条件。 设计可以有多个断点! 它们通常基于视窗介于两个宽度之间:断点开始的位置和断点结束的位置。
以下是我们如何使用 and
运算符组合两个断点值来实现这一点
/* When the browser is between 400px - 1000px */
@media (min-width: 400px) and (max-width: 1000px) {
/* etc. */
}
您开始了解到,当我们放弃布尔 and
运算符而采用新的范围比较语法时,编写媒体查询要短得多、更容易。
@media (400px <= width <= 1000px) {
/* etc. */
}
容易多了,对吧? 而且它清楚地说明了这个媒体查询在做什么。
浏览器支持
截至本文撰写之时,这种改进的媒体查询语法还处于早期阶段,目前还没有像结合 min-width
和 max-width
的方法那样得到广泛支持。 不过,我们正在接近! 截至目前,Safari 是唯一一个主要的坚持者,但 有一个关于它的公开票据,您可以关注它。
这些浏览器支持数据来自 Caniuse,它提供了更多详细信息。 数字表示浏览器从该版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
104 | 63 | 否 | 104 | 16.4 |
移动/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 16.4 |
让我们看一个例子
这是一个适合更大屏幕(如台式机)的布局

此布局具有所有断点通用的基本样式。 但随着屏幕变窄,我们开始应用条件应用于不同较小断点的样式,这些样式非常适合平板电脑,一直到手机

要查看正在发生的事情,以下是布局在两个较小断点之间如何响应。 隐藏的导航列表显示出来,以及 main
中的 title
的 font-size
增加了。
当视窗的更改从匹配一个媒体的条件变为另一个媒体的条件时,就会触发该更改
/* Base styles (any screen size) */
header {
display: flex;
justify-content: center;
}
header ul {
display: none;
}
.title p {
font-size: 3.75rem;
}
/* When the media type is a screen with a width greater or equal to 768px */
@media screen and (width >= 768px) {
header {
justify-content: space-between;
}
header ul {
display: flex;
justify-content: space-between;
gap: 3rem;
}
.title p {
font-size: 5.75rem;
}
}
我们结合了一些我们已经讨论过的概念! 我们定位具有 screen
媒体类型的设备,使用新的媒体特性范围语法评估视窗宽度是否大于或等于特定值,并使用 and
运算符组合这两个条件。

好的,这对 768px
以下的移动设备以及等于或大于 768px
的其他设备来说很棒。 但是,桌面布局怎么办……我们如何才能做到这一点?
就布局而言
main
元素变为 12 列网格。- 在图像上显示一个按钮。
.title
元素的字体大小增加并与图像重叠。
假设我们已经完成了功课并确定了这些更改的确切发生位置,我们可以在视窗匹配该断点的 width
条件时应用这些样式。 我们将说断点在 1000px
/* When the media type is a screen with a width greater or equal to 1000px */
@media screen and (width >= 1000px) {
/* Becomes a 12-column grid */
main {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: auto 250px;
}
/* Places the .title on the grid */
.title {
grid-row: 1;
}
/* Bumps up the font-size */
.title p {
font-size: 7.75rem;
}
/* Places .images on the grid */
.images {
grid-row: 1 / span 2;
align-self: end;
position: relative;
}
/* Displays the button */
.images .button {
display: block;
position: absolute;
inset-block-end: 5rem;
inset-inline-end: -1rem;
}
}

试玩一下
为什么新的语法更容易理解
底线:区分比较运算符(例如 width >= 320px
)比使用 and
运算符区分 min-width
和 max-width
容易。 通过消除 min-
和 max-
之间的细微差别,我们只有一个 width
参数可以使用,运算符告诉我们其他信息。
除了这些语法的视觉差异之外,它们还在做一些细微的不同的事情。 使用 min-
和 max-
等效于使用数学比较运算符
max-width
等效于<=
运算符(例如(max-width: 320px)
等效于(width <= 320px)
)。min-width
等效于>=
运算符(例如(min-width: 320px)
等效于(width >= 320px)
)。
请注意,两者都不等效于 >
或 <
运算符。
让我们直接从媒体查询级别 4 规范中提取一个示例,其中我们使用 min-width
和 max-width
根据视窗宽度在 320px
处的断点定义不同的样式
@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320px) { /* styles for viewports >= 320px */ }
当视窗宽度等于 320px
时,两个媒体查询都会匹配条件。 这并不完全是我们想要的。 我们想要其中一个条件,而不是同时满足两个条件。 为了避免这种隐式更改,我们可以根据 min-width
在查询中添加一个像素
@media (max-width: 320px){ /* styles for viewports <= 320px */ }
@media (min-width: 321px){ /* styles for viewports >= 321px */ }
虽然这确保了当视窗宽度为 320px
时,两组样式不会同时应用,但任何介于 320px
和 321px
之间的视窗宽度将导致一个非常小的区域,其中两个查询中的样式都不会应用——这是一种奇怪的“无样式内容闪烁”情况。
一种解决方案是将第二个比较标度值(小数点后的数字)增加到 320.01px
@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320.01px) { /* styles for viewports >= 320.01px */ }
但这变得很愚蠢且过于复杂。 这就是新的媒体特性范围语法是更合适的方法的原因
@media (width <= 320px) { /* styles for viewports <= 320px */ }
@media (width > 320px) { /* styles for viewports > 320px */ }
总结
Whew,我们已经涵盖了 CSS 媒体查询中针对视窗宽度范围的新语法。现在 Media Queries Level 4 规范已经引入了该语法,并且已被 Firefox 和 Chromium 浏览器采用,我们正在接近能够使用新的比较运算符并将其与除 `width` 之外的其他范围媒体特征(如 `height` 和 `aspect-ratio`)结合使用。
这只是 Level 4 规范引入的新功能之一,与之一起的还有 我们可以根据用户偏好进行的一系列查询。但这才仅仅是开始!查看 CSS 媒体查询完整指南,抢先了解 Media Queries Level 5 可能包含的内容。
很棒的总结!我对 `=` 运算符的实际用例非常好奇。我很难想到任何除了愚蠢的彩蛋和内部笑话之外的用例。
哈哈!确实如此,对吧?!我已经可以想象在特定/精确断点处出现各种有趣的彩蛋。
我能想象人们会错误地使用它来创建设备特定的布局,就像我们在 `320px` / `768px` 时代所做的那样。但我也很想知道其他人是否心中有实际用例!
我想处理 `=` 的功能只是处理 `>=` 和 `<=` 的必要条件,因此它成为一个独立的运算符,而没有针对设计师和开发者更大的实际用途。
但你绝对是对的,人们会期望使用它来创建这个古怪功能的有趣体验。
嗯,这方面没有新的功能,因此任何潜在的笑话都可以通过 `min-width` 和 `max-width` 的组合来实现。
这看起来像是一个不错的简写,但这让我想起了 Safari 之前的一个 bug,媒体查询需要偏移 0.2px。因此,Bootstrap 等框架生成了类似 `@media (max-width: 767.98px)` 的媒体查询。我们是否需要继续这样做?因为如果我们这样做,我们可能还无法使用这个简写。
回答我自己的问题,人们报告说他们无法再复制这个 bug https://bugs.webkit.org/show_bug.cgi?id=178261
我喜欢你们所有的逻辑技巧
.
.
.
.
.
.
.
…太棒了 ❤
感谢分享!这个新的语法让理解 MQ 变得容易多了。不过,除非你明确地为仅限屏幕的样式编写代码,否则无需在 MQ 中编写 `screen and`。这种情况几乎不会发生。我建议更新代码片段,这样就不会再传播这个错误。
只是……JS 并不“支持” `a <= b <= c`(以 Python 或这个新的范围查询解析它的方式)。
所以有点令人困惑。
但肯定比 min/max 的东西好得多……
看起来 Safari 也发布了这个功能 (https://bugs.webkit.org/show_bug.cgi?id=180234#c4),很棒!
有什么意义呢?一旦你设置了你的 mixin,你就不再需要它了。再说一次,试图修复一个没有损坏的东西。
我更喜欢像 Swift 那样的范围样式,但现在看来已经太迟了,无法改变它。把宽度放在中间太难看了..
@media (width ~= 400px…1000px)