CSS 媒体查询是一种根据某些特征、功能和用户偏好来定位浏览器的方法,然后根据这些内容应用样式或运行其他代码。也许世界上最常见的媒体查询是那些针对特定视窗范围并应用自定义样式的查询,这些查询催生了响应式设计的整个理念。
/* When the browser is at least 600px and above */
@media screen and (min-width: 600px) {
.element {
/* Apply some styles */
}
}
除了视窗宽度之外,我们还可以针对许多其他内容。可能是屏幕分辨率、设备方向、操作系统偏好,甚至更多,我们可以在一堆内容中进行查询并使用它们来设置内容的样式。
正在寻找根据标准设备(如手机、平板电脑和笔记本电脑)的视窗快速列出媒体查询? 查看我们收集的代码片段。
使用媒体查询
媒体查询通常与 CSS 相关联,但它们也可以在 HTML 和 JavaScript 中使用。
HTML
我们可以在 HTML 中直接使用媒体查询,方法有好几种。
有一个 <link>
元素直接位于文档的 <head>
中。在这个示例中,我们告诉浏览器,我们希望在不同的视窗大小下使用不同的样式表
<html>
<head>
<!-- Served to all users -->
<link rel="stylesheet" href="all.css" media="all" />
<!-- Served to screens that are at least 20em wide -->
<link rel="stylesheet" href="small.css" media="(min-width: 20em)" />
<!-- Served to screens that are at least 64em wide -->
<link rel="stylesheet" href="medium.css" media="(min-width: 64em)" />
<!-- Served to screens that are at least 90em wide -->
<link rel="stylesheet" href="large.css" media="(min-width: 90em)" />
<!-- Served to screens that are at least 120em wide -->
<link rel="stylesheet" href="extra-large.css" media="(min-width: 120em)" />
<!-- Served to print media, like printers -->
<link rel="stylesheet" href="print.css" media="print" />
</head>
<!-- ... -->
</html>
为什么您要这样做?这可能是一种以细致的方式调整网站性能的好方法,因为它可以通过将样式分成需要它们的设备才能下载和提供的方式来分割样式。
但要明确的是,这并不总是阻止与这些媒体查询不匹配的样式表下载,它只是将它们分配给较低的加载优先级。
因此,如果像手机这样的较小屏幕设备访问该网站,它将只下载与它的视窗大小匹配的媒体查询中的样式表。但如果较大的桌面屏幕出现,它将下载整个样式表,因为它匹配所有这些查询(好吧,除了此特定示例中的打印查询)。
那只是 <link>
元素。正如我们的 响应式图像语法指南 所解释的那样,我们可以在 <source>
元素上使用媒体查询,它通知 <picture>
元素浏览器应该从一组图像选项中使用哪个版本的图像。
<picture>
<!-- Use this image if the screen is at least 800px wide -->
<source srcset="cat-landscape.png" media="(min-width: 800px)">
<!-- Use this image if the screen is at least 600px wide -->
<source srcset="cat-cropped.png" media="(min-width: 600px)">
<!-- Use this image if nothing matches -->
<img src="cat.png" alt="A calico cat with dark aviator sunglasses.">
</picture>
同样,这可能是性能的显著优势,因为我们可以为较小的设备提供较小的图像,这些设备可能是低功耗设备,可能仅限于数据计划。
别忘了,我们也可以直接在 <style>
元素上使用媒体查询
<style>
p {
background-color: blue;
color: white;
}
</style>
<style media="all and (max-width: 500px)">
p {
background-color: yellow;
color: blue;
}
</style>
CSS
同样,CSS 是在现实世界中发现媒体查询最常见的地方。它们直接位于样式表中的 @media
规则中,该规则将元素与条件包装在一起,这些条件规定当浏览器匹配这些条件时,何时何地应用一组样式。
/* Viewports between 320px and 480px wide */
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
.card {
background: #bada55;
}
}
也可以对导入的样式表进行范围限定,但作为一般规则,避免使用 @import,因为它 性能较差。
/* Avoid using @import if possible! */
/* Base styles for all screens */
@import url("style.css") screen;
/* Styles for screens in a portrait (narrow) orientation */
@import url('landscape.css') screen and (orientation: portrait);
/* Print styles */
@import url("print.css") print;
JavaScript
我们也可以在 JavaScript 中使用媒体查询!猜猜看?它们的运作方式与在 CSS 中非常相似。区别是什么?我们首先使用 window.matchMedia()
方法来定义条件。
因此,假设我们希望在浏览器宽度至少为 768px 时将消息记录到控制台。我们可以创建一个常量,该常量调用 matchMedia()
并定义该屏幕宽度
// Create a media condition that targets viewports at least 768px wide
const mediaQuery = window.matchMedia( '( min-width: 768px )' )
然后,当匹配该条件时,我们可以向控制台发送日志
// Create a media condition that targets viewports at least 768px wide
const mediaQuery = window.matchMedia( '( min-width: 768px )' )
// Note the `matches` property
if ( mediaQuery.matches ) {
console.log('Media Query Matched!')
}
不幸的是,这只会触发一次,因此如果警报被关闭,如果我们更改屏幕宽度并再次尝试而不刷新,它将不会再次触发。因此,使用侦听器检查更新是一个好主意。
// Create a condition that targets viewports at least 768px wide
const mediaQuery = window.matchMedia('(min-width: 768px)')
function handleTabletChange(e) {
// Check if the media query is true
if (e.matches) {
// Then log the following message to the console
console.log('Media Query Matched!')
}
}
// Register event listener
mediaQuery.addListener(handleTabletChange)
// Initial check
handleTabletChange(mediaQuery)
查看 Marko Ilic 关于 “使用 JavaScript 媒体查询” 的完整帖子,以更深入地了解这一点,包括使用媒体查询与旧的 JavaScript 方法进行比较,该方法绑定 resize
事件侦听器,检查 window.innerWidth
或 window.innerHeight
来触发更改。
媒体查询的结构
现在我们已经看到了媒体查询可以使用的几个示例,让我们将它们分解并看看它们到底在做什么。
@media
@media [media-type] ([media-feature]) {
/* Styles! */
}
媒体查询配方中的第一个成分是 @media
规则本身,它是 许多 CSS @规则 之一。为什么 @media
会受到如此多的关注?因为它侧重于网站查看时所使用的媒体类型,该媒体类型支持的功能以及可以组合起来混合匹配简单和复杂条件的运算符。
媒体类型
@media screen {
/* Styles! */
}
我们尝试定位哪种媒体类型?在许多(如果不是大多数)情况下,您会看到这里使用 screen
值,这是有道理的,因为我们尝试匹配的许多媒体类型都是带有屏幕的设备。
当然,屏幕并不是我们唯一可以定位的媒体类型。我们有一些,包括
all
:匹配所有设备print
:匹配在打印预览或将内容分解成用于打印的页面的任何媒体中查看的文档。screen
:匹配具有屏幕的设备speech
:匹配能够朗读内容的设备,例如屏幕阅读器。自从 媒体查询级别 4 以来,它取代了现在已弃用的aural
类型。
要在屏幕上预览打印样式,所有主要浏览器都可以 使用 DevTools 模拟打印样式表的输出。其他媒体类型,如 tty
、tv
、 projection
、 handheld
、braille
、embossed
和 aural
已被弃用,虽然 规范继续建议浏览器识别它们,但它们必须评估为无。如果您正在使用这些类型中的任何一种,请考虑将其更改为现代方法。
媒体功能
一旦我们定义了要匹配的媒体类型,我们就可以开始定义要匹配的特征。我们已经查看了许多将屏幕匹配到宽度的示例,其中 screen
是类型,而 min-width
和 max-width
则是具有特定值的特征。
但我们可以匹配的“特征”还有很多很多(很多!)。媒体查询级别 4 将 18 个媒体特征分组到 5 个类别中。
视窗/页面特征
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
width | 定义视窗的宽度。这可以是特定数字(例如 400px )或范围(使用 min-width 和 max-width )。 | <length> | |
height | 定义视窗的高度。这可以是特定数字(例如 400px )或范围(使用 min-height 和 max-height )。 | <length> | |
aspect-ratio | 定义视窗的宽高比 | <ratio> | |
orientation | 屏幕的方向,例如高(portrait )或宽(landscape ),根据设备旋转方式而定。 | portrait landscape | |
overflow-block | 检查设备如何处理超出块方向视窗的内容,可以是 scroll (允许滚动)、optional-paged (允许滚动和手动分页)、paged (分成页面)和 none (不显示)。 | scroll optional-paged paged | 媒体查询级别 4 |
overflow-inline | 检查是否允许沿内联轴超出视窗的内容滚动,可以是 none (不滚动)或 scroll (允许滚动)。 | scroll none | 媒体查询级别 4 |
显示质量
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
resolution | 定义设备的目标像素密度 | <resolution> infinite | |
scan | 定义设备的扫描过程,即设备将图像绘制到屏幕上的方式(其中 interlace 交替绘制奇数行和偶数行,而 progressive 顺序绘制所有行)。 | interlace progressive | |
grid | 确定设备是否使用网格(1 )或位图(0 )屏幕 | 0 = 位图1 = 网格 | 媒体查询级别 5 |
update | 检查设备可以更改内容外观的频率(如果有的话),值包括 none 、slow 和 fast 。 | slow fast none | 媒体查询级别 4 |
environment-blending | 一种用于确定设备外部环境的方法,例如昏暗或过亮的地方。 | opaque additive subtractive | |
display-mode | 测试设备的显示模式,包括 fullscreen (无浏览器 chrome)、standalone (独立应用程序)、minimal-ui (独立应用程序,但带有一些导航)和 browser (更传统的浏览器窗口) | fullscreen standalone minimal-ui browser | Web 应用清单 |
颜色
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
颜色 | 以位数形式表示设备的颜色支持,例如,值为12 等同于支持 12 位色的设备,值为 0 表示不支持颜色。 | <整数> | |
颜色索引 | 定义设备支持的值数量。这可以是一个具体数字(例如 10000 )或一个范围(例如 min-color-index: 10000 , max-color-index: 15000 ),与 width 相同。 | <整数> | |
单色 | 设备的单色支持的每像素位数,其中 0 表示不支持单色。 | <整数> | |
颜色色域 | 定义浏览器和设备支持的颜色范围,可以是 srgb 、p3 或 rec2020 | srgb p3 rec2020 | 媒体查询级别 4 |
动态范围 | 浏览器和用户设备的视频平面支持的亮度、色深和对比度比率的组合。 | 标准 高 | |
反转颜色 | 检查浏览器或操作系统是否设置为反转颜色(这对于优化视觉障碍(涉及颜色)的辅助功能很有用) | 反转 none | 媒体查询级别 5 |
交互
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
指针 | 类似于 any-pointer ,但检查主要输入机制是否为指针,如果是,则检查其精度(其中 coarse 指精度较低,fine 指精度较高,none 指没有指针)。 | 粗略 精细 none | 媒体查询级别 4 |
悬停 | 类似于 any-hover ,但检查主要输入机制(例如鼠标或触控)是否允许用户将鼠标悬停在元素上。 | 悬停 none | 媒体查询级别 4 |
任何指针 | 检查设备是否使用指针,例如鼠标或样式,以及其精度(其中 coarse 指精度较低,fine 指精度较高)。 | 粗略 精细 none | 媒体查询级别 4 |
任何悬停 | 检查设备是否能够将鼠标悬停在元素上,例如使用鼠标或手写笔。在一些罕见情况下,触控设备也能够进行悬停操作。 |
| 媒体查询级别 4 |
视频前缀
规范引用了用户代理(包括电视),这些用户代理在两个独立的平面中呈现视频和图形,每个平面都有其自身的特性。以下功能描述了这些平面。
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
视频颜色色域 | 描述浏览器和用户设备的视频平面支持的大致颜色范围。 | srgb p3 rec2020 | 媒体查询级别 5 |
视频动态范围 | 浏览器和用户设备的视频平面支持的亮度、色深和对比度比率的组合。 | 标准 高 | 媒体查询级别 5 |
video-width ¹ | 目标显示器的视频平面区域的宽度。 | <length> | 媒体查询级别 5 |
video-height ¹ | 目标显示器的视频平面区域的高度。 | <length> | 媒体查询级别 5 |
video-resolution ¹ | 目标显示器的视频平面区域的分辨率。 | <resolution> 无限 | 媒体查询级别 5 |
脚本
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
脚本 | 检查设备是否允许使用脚本(即 JavaScript),其中 enabled 允许使用脚本,iniital-only | 启用 仅初始 | 媒体查询级别 5 |
用户偏好
特征 | 摘要 | 值 | 添加 |
---|---|---|---|
首选减少运动 | 检测用户的系统设置是否设置为减少页面上的运动,这是一个 很棒的辅助功能检查。 | 无偏好 减少 | 媒体查询级别 5 |
首选减少透明度 | 检测用户的系统设置是否阻止元素之间的透明度。 | 无偏好 减少 | 媒体查询级别 5 |
首选对比度 | 检测用户的系统设置是否设置为增加或减少颜色之间的对比度。 | 无偏好 高 低 强制 | 媒体查询级别 5 |
首选颜色方案 | 检测用户是否更喜欢浅色或深色配色方案,这是一种快速增长的方式来 创建“暗黑模式”界面。 | 浅色 深色 | 媒体查询级别 5 |
强制颜色 | 测试浏览器是否限制可用的颜色(可以是 none 或 active ) | 激活 none | 媒体查询级别 5 |
首选减少数据 | 检测用户是否更喜欢使用更少的数据来呈现页面。 | 无偏好 减少 | 媒体查询级别 5 |
已弃用
名称 | 摘要 | 已删除 |
---|---|---|
设备纵横比 | 输出设备的宽高比。 | 媒体查询级别 4 |
设备高度 | 设备表面显示渲染元素的高度。 | 媒体查询级别 4 |
设备宽度 | 设备表面显示渲染元素的宽度。 | 媒体查询级别 4 |
运算符
媒体查询支持与许多编程语言类似的逻辑运算符,以便我们可以根据特定条件匹配媒体类型。@media
规则本身是一个逻辑运算符,它基本上表示“如果”以下类型和特征匹配,那么执行一些操作。
and
但是,如果我们想定位一定范围宽度内的屏幕,可以使用 and
运算符。
/* Matches screen between 320px AND 768px */
@media screen (min-width: 320px) and (max-width: 768px) {
.element {
/* Styles! */
}
}
or
(或以逗号分隔)
我们还可以用逗号分隔功能,作为使用 or
运算符匹配不同功能的方式。
/*
Matches screens where either the user prefers dark mode or the screen is at least 1200px wide */
@media screen (prefers-color-scheme: dark), (min-width 1200px) {
.element {
/* Styles! */
}
}
not
也许我们想根据设备不支持或不匹配的内容来定位设备。此声明在设备为打印机且只能显示一种颜色时会移除主体背景颜色。
@media print and ( not(color) ) {
body {
background-color: none;
}
}
想了解更多?查看 DigitalOcean 社区中的 “CSS 媒体查询:快速参考和指南”,了解更多遵循媒体查询语法的示例。
你真的需要 CSS 媒体查询吗?
媒体查询是 CSS 工具箱中的一个强大工具,拥有令人兴奋的隐藏宝石。但是,如果你为每种可能的情况调整你的设计,你最终会得到一个代码库,它太复杂而无法维护,而且众所周知,CSS 就像一只熊宝宝:可爱且无害,但当它长大后,它会把你吃掉。
这就是为什么我建议遵循 Ranald Mace 的通用设计概念,即“设计产品使其尽可能地适用于所有人,无需适应或专门设计。”
在 “人人享有无障碍” 中,Laura Kalbag 解释说,无障碍设计和通用设计之间的差异很细微,但很重要。无障碍设计师会为轮椅使用者创建一个大的门供他们进入,而通用设计师会创造一个适合任何人的入口,无论他们的能力如何。
我知道谈论网络上的通用设计很难,几乎听起来很乌托邦,但想想看,大约有 150 种不同的浏览器,大约 50 种不同的用户偏好组合,以及我们之前提到的仅 Android 设备就有 24000 多种不同的独特设备。
这意味着至少有 1800 万种可能的情况,你的内容可能会在其中显示。用奇妙的 Miriam Suzanne 的话说,“CSS 正在尝试在未知的画布上进行未知内容的图形设计,跨越操作系统、界面和语言。我们中没有一个人可能知道自己在做什么。”
这就是为什么假设真的很危险,所以当你设计、开发和思考你的产品时,抛开假设,使用媒体查询确保你的内容在任何联系和任何用户面前都能正确显示。
匹配值范围
上一节概述的许多媒体特性,包括width
、height
、color
和color-index
,都可以加上min-
或max-
前缀来表示最小或最大约束。我们在许多示例中已经看到过这些,但重点是我们可以创建一个值范围来匹配,而不用声明特定值。
在下面的代码片段中,当视窗宽度大于 30em 且小于 80em 时,我们将身体背景设置为紫色。如果视窗宽度不匹配该范围的值,则将回退到白色。
body {
background-color: #fff;
}
@media (min-width: 30em) and (max-width: 80em) {
body {
background-color: purple;
}
}
媒体查询级别 4 指定了使用小于 (<
)、大于 (>
) 和等于 (=
) 运算符的一种新的更简单的语法。因此,最后一个示例可以转换为新的语法,如下所示
@media (30em <= width <= 80em) {
/* ... */
}
嵌套和复杂决策
CSS 允许您使用括号嵌套 at 规则或分组语句,使您可以根据需要深入评估复杂操作。
@media (min-width: 20em), not all and (min-height: 40em) {
@media not all and (pointer: none) { ... }
@media screen and ( (min-width: 50em) and (orientation: landscape) ), print and ( not (color) ) { ... }
}
小心!虽然可以创建功能强大且复杂的表达式,但最终您可能会得到一个非常主观的、难以维护的查询。正如 Brad Frost所说:“我们的界面越复杂,我们就需要投入越多思考才能妥善维护它们。”
无障碍性
媒体查询级别 4 中添加的许多特性都围绕着无障碍性。
prefers-reduced-motion
prefers-reduced-motion
检测用户是否启用了减少运动偏好,以最大程度减少运动和动画的数量。它接受两个值
no-preference
:表示用户未向系统表明任何偏好。reduce
:表示用户已通知系统他们偏好最大程度减少运动或动画的界面,最好是消除所有非必要的运动。
此偏好通常由患有前庭障碍或眩晕症的人使用,其中不同的运动会导致失去平衡、偏头痛、恶心或听力损失。如果您曾经尝试快速旋转并感到头晕,您就会知道这种感觉。
在 Eric Bailey 的一篇很棒的文章中,他建议使用以下代码停止所有动画
@media screen and (prefers-reduced-motion: reduce) {
* {
/* Very short durations means JavaScript that relies on events still works */
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
}
像Bootstrap 这样的流行框架默认情况下启用了此功能。我认为没有理由不使用 prefers-reduced-motion
- 只管使用它。
prefers-contrast
prefers-contrast
特性会通知用户是否已在系统偏好设置或浏览器设置中选择增加或减少对比度。它接受三个值
no-preference
:当用户未向系统表明任何偏好时。如果您将其用作布尔值,它将评估为false
。high
:当用户选择显示更高对比度的选项时。low
:当用户选择显示更低对比度的选项时。
在撰写本文时,此功能不受任何浏览器支持。Microsoft 已经使用 -ms-high-contrast
特性做了一个非标准的早期实现,它只在 Microsoft Edge v18 或更早版本(但不包括基于 Chromium 的版本)上有效。
.button {
background-color: #0958d8;
color: #fff;
}
@media (prefers-contrast: high) {
.button {
background-color: #0a0db7;
}
}
此示例在用户打开高对比度时,将类 button 的对比度从 AA 增加到 AAA。
inverted-colors
inverted-colors
特性会通知用户是否已在系统偏好设置或浏览器设置中选择反转颜色。有时此选项用作高对比度的替代方案。它接受三个值
none
:当颜色正常显示时inverted
:当用户选择反转颜色的选项时
反转颜色的问题是它也会反转图像和视频的颜色,使它们看起来像 X 光图像。通过使用 CSS 反转过滤器,您可以选择所有图像和视频并将其反转回来。
@media (inverted-colors) {
img, video {
filter: invert(100%);
}
}
在撰写本文时,此功能仅受 Safari 支持。
prefers-color-scheme
如今,我们越来越常见“深色模式”配色方案,并且借助 prefers-color-scheme
特性,我们可以利用用户的系统或浏览器偏好设置来确定我们是否根据用户的偏好提供“深色”或“浅色”主题。
它接受两个值
light
:当用户选择他们更喜欢浅色主题或没有活动偏好设置时dark
:当用户在设置中选择了深色显示时
body {
--bg-color: white;
--text-color: black;
background-color: var(--bg-color);
color: var(--text-color);
}
@media screen and (prefers-color-scheme: dark) {
body {
--bg-color: black;
--text-color: white;
}
}
正如 Adhuham 在深色模式的完整指南中解释的那样,这不仅仅是改变背景颜色。在您开始使用深色模式之前,请记住,如果您没有一个非常聪明的实现策略,您最终可能会得到一个非常难以维护的代码库。CSS 变量 可以为此发挥神奇的作用,但这将是另一篇文章的主题。
未来展望
媒体查询级别 5 目前处于工作草案状态,这意味着从现在到它成为推荐标准之间可能会发生很多变化。但它包含一些值得一提的有趣特性,因为它们开辟了新的方法来定位屏幕并将设计调整到非常具体的条件。
用户偏好媒体特性
嘿,我们刚刚在上一节中介绍了这些!好吧。这些特性令人兴奋,因为它们是根据用户的实际设置来确定的,无论是来自用户代理还是操作系统级别的设置。
检测强制颜色调色板
这很不错。一些浏览器会限制渲染样式时可用的颜色数量。这被称为“强制颜色模式”,如果在浏览器设置中启用,用户可以选择在页面上使用的有限颜色集。因此,用户能够定义颜色组合和对比度,从而使内容更易于阅读。
forced-colors
特性允许我们使用 active
值检测是否使用了强制颜色调色板。如果匹配,浏览器必须通过 CSS 系统颜色提供所需的调色板。浏览器还可以自行决定页面背景颜色是浅色还是深色,如果合适,则触发相应的 prefers-color-scheme
值,以便我们可以调整页面。
检测最大亮度、色深和对比度
某些设备(和浏览器)能够显示超亮显示屏,呈现广泛的颜色范围,以及颜色之间的高对比度。我们可以使用dynamic-range
功能检测这些设备,其中high
关键字匹配这些设备,而standard
匹配其他所有设备。
我们可能会看到对这一点的更改,因为截至目前,关于什么测量构成“高”亮度和对比度水平仍然存在不确定性。浏览器可能会做出该决定。
视频前缀功能
该规范讨论了一些屏幕(如电视),这些屏幕能够在单独的“平面”上显示视频和图形,这可能是区分视频帧和屏幕上其他元素的一种方式。因此,媒体查询级别 5 正在提出旨在检测视频特征的一组新媒体功能,包括色域和动态范围。
也有一些提案来检测视频高度、宽度和分辨率,但陪审团还在外是否这些是解决视频的正确方法。
浏览器支持
浏览器不断发展,当您阅读这篇文章时,此功能的浏览器支持可能已经发生变化,请查看MDN 更新的浏览器兼容性表。
关于容器查询的说明
如果组件能够根据自己的大小而不是浏览器的自身大小进行调整,那不是很好吗?这就是CSS 容器查询的概念。我们目前只有浏览器屏幕可以通过媒体查询来进行这些更改。
这很不幸,因为视口并不总是与元素本身的大小直接相关。想象一个在网站上多种不同上下文中呈现的小部件:有时在侧边栏中,有时在全宽页脚中,有时在列数未知的网格中。
这就是容器查询试图解决的问题。理想情况下,我们可以根据元素本身的大小而不是视口的大小来调整元素的样式。Chrome 105 发布了对 CSS 容器查询的支持。Safari 16.1 也是如此。截至撰写本文时,我们真正等待的是 Firefox,以便获得广泛支持。
此浏览器支持数据来自Caniuse,其中有更多详细信息。数字表示浏览器在该版本及其更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
106 | 110 | 否 | 106 | 16.0 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 16.0 |
示例
让我们看一下媒体查询的示例。媒体类型、特征和运算符的组合很多,我们能展示的可能性非常多。相反,我们将重点介绍一些基于特定媒体特征的示例。
在不同的视口宽度下调整布局
更多信息
这可能是使用最广泛的媒体特征。它提供浏览器的视口宽度,包括滚动条。它解锁了 Ethan Marcotte 闻名于世的响应式设计的 CSS 实现:一个使用流体网格、灵活图像和响应式排版组合,使设计根据视口大小做出响应的过程。
后来,Luke Wroblewski 通过引入术语移动优先发展了响应式设计的概念,鼓励设计师和开发人员首先从小型屏幕体验开始,然后随着屏幕宽度和设备功能的扩展,逐渐增强体验。
移动优先通常可以通过使用min-width
而不是max-width
来识别。如果我们从min-width
开始,我们实际上是在说,“嘿,浏览器,从这里开始向上扩展。” 相反,max-width
有点像优先考虑更大的屏幕。
通过宽度定义断点的一种方法是使用标准设备的尺寸,例如 iPhone 的精确像素宽度。但是,有许多、许多(许多)、许多不同的手机、平板电脑、笔记本电脑和台式机。仅看 Android,截至 2015 年 8 月,就有超过 24,000 种视口大小、分辨率、操作系统和浏览器的变体。
因此,虽然针对特定设备的精确宽度可能有助于故障排除或一次性修复,但这可能不是维护响应式架构的最稳健解决方案。这并不是一个新想法。早在 2013 年,Brad Frost 就已经在其文章“7 种高效媒体查询的习惯”中宣扬了让内容(而不是设备)决定断点的优点。
尽管媒体查询仍然是创建响应式界面的有效工具,但在许多情况下,可以完全避免使用宽度。现代 CSS 允许我们使用 CSS 网格和 flex 创建灵活的布局,这些布局会根据视口大小调整我们的内容,而无需添加断点。例如,这是一个网格布局,它会根据没有任何媒体查询调整它将具有的列数。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
有很多关于超越宽度的文章,几年前我写过关于这方面的文章,我建议查看 Una Kravet 的一行 CSS 中的十种现代布局。
暗模式
更多信息
此示例直接摘自我们的Web 暗模式指南。这个想法是我们可以使用prefers-color-scheme
功能检测用户的系统设置是否配置为亮模式或暗模式,然后为渲染的 UI 定义一组备用颜色。
将此技术与 CSS 自定义属性结合使用会使事情变得更加容易,因为它们就像变量,我们只需要定义一次,然后在整个代码中使用。需要交换颜色吗?更改自定义属性值,它将在所有地方更新。这正是prefers-color-scheme
所做的。我们将一组颜色定义为自定义属性,然后使用prefer-color-scheme
功能在媒体查询中重新定义它们,以根据用户的设置更改颜色。
检测响应式卡片库的方位、悬停和移动
更多信息
此画廊是响应式的,无需使用width
特征。
它检测视口的orientation
。如果它是portrait
视口,侧边栏将变成标题;如果它是landscape
,它将保留在一边。
使用pointer
媒体特征,它会判断主输入设备是coarse
(如手指)还是fine
(如鼠标光标),以设置复选框可点击区域的大小。
然后,通过使用hover
媒体特征,该示例检查设备是否能够悬停(如鼠标光标),并在每个卡片中显示一个复选框。
当prefers-reduced-motion
设置为reduce
时,动画将被删除。
您注意到什么了吗?我们实际上没有使用媒体查询来进行卡片的实际布局和大小调整!这通过在.container
元素上使用minmax()
函数来处理,以展示响应式设计并不总是意味着使用媒体查询。
简而言之,这是一个完全响应式的应用程序,而无需测量width
或进行假设。
以横屏模式定位 iPhone
/* iPhone X Landscape */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 812px)
and (-webkit-min-device-pixel-ratio: 3)
and (orientation: landscape) {
/* Styles! */
}
更多信息
orientation
媒体特征测试设备是横向旋转(横屏)还是纵向旋转(竖屏)。
虽然媒体查询无法准确知道正在使用的设备,但我们可以使用特定设备的精确尺寸。上面的代码片段针对的是 iPhone X。
为大型视窗应用粘性头部
更多信息
在上面的示例中,我们使用height
来分离固定元素,避免在屏幕过短时占用太多屏幕空间。当屏幕较高时,水平导航栏处于固定位置,但在较短的屏幕上会分离自己。
与width
功能类似,height
检测视窗的高度,包括滚动条。我们中的许多人在具有狭窄视窗的小型设备上浏览网页,这使得针对不同高度进行设计比以往任何时候都更加重要。Anthony Colangelo 描述了苹果如何使用height
媒体特征以有意义的方式处理英雄图像的大小,因为视窗的高度发生变化。
响应式(流体)排版
更多信息
字体看起来可能太大或太小,具体取决于显示它的屏幕大小。如果我们在小屏幕上工作,那么我们可能希望使用比在大屏幕上使用的字体更小的字体。
这里的想法是我们使用浏览器的宽度来缩放字体大小。我们在<html>
上设置默认字体大小,作为“小”字体大小,然后使用媒体查询设置另一个字体大小,作为“大”字体大小。在中间?我们再次设置字体大小,但位于另一个媒体查询中,该查询根据浏览器宽度计算大小。
这很美妙,因为它允许字体大小根据浏览器宽度调整,但绝不会超过或低于特定大小。但是,由于更新的 CSS 功能,比如min()
、max()
和clamp()
,有一个更简单的方法,完全不需要媒体查询。
course
指针时提供更大的触摸目标
当设备有更多信息
你有没有访问过一个网站,网站上有很多超小按钮?我们有些人手指很粗,难以准确点击一个对象,而不会意外点击其他对象。
当然,我们可以依靠width
特性来判断我们是否在使用小屏幕,但我们也可以检测设备是否能够悬停在元素上。如果不是,那么它可能是一个触摸设备,或者可能是一个同时支持触摸和悬停的设备,比如 Microsoft Surface。
上面的演示使用复选框作为示例。在小屏幕上查看复选框时,点击复选框可能很痛苦,因此我们增加了复选框的大小,并且如果设备不支持hover
事件,则不需要悬停。
同样,这种方法并不总是准确的。查看Patrick Lauke 的详细文章,文章详细介绍了使用hover
、pointer
、any-hover
和any-pointer
时的潜在问题。
规范
特别感谢 Sarah Rambacher 帮助审查本指南。
我最近了解到 add Listener 已弃用,我们应该使用 addeventListener 代替。
感谢您精彩的解释。在实施过程中,我在您 JavaScript 示例中的“if ( mediaQuery”之后遇到了缺少“matches”的问题
// 检查媒体查询是否为真
if ( mediaQuery ) {
// 然后将以下消息记录到控制台
console.log(‘媒体查询匹配!’)
}
此评论编辑器不允许我像我希望的那样格式化我的评论。
这对我有用
// 检查媒体查询是否为真
if ( mediaQuery.matches ) {
// 然后将以下消息记录到控制台
console.log(‘媒体查询匹配!’)
}
if (mediaQuery.matches)
感谢您的分享!
副标题
“@media screen (min-width: 320px) and (max-width: 768px)”
在“媒体查询的剖析”中具有误导性。
根据 MDN 的语法,在“screen”之后应该有一个“and”,所以您可能需要将其更正为:“@media screen and (min-width: 320px) and (max-width: 768px)”。
您可以在“使用 min 和 max 匹配值范围”部分的末尾添加指向https://caniuse.cn/mdn-css_at-rules_media_range_syntax 的链接。
感谢您,我实际上一直在想媒体查询是否开始变得无关紧要了,因为在 Web 开发中,理想的做法是始终遵循下一个大趋势。