CSS 教程 / CSS 媒体查询与基于内容的断点

当满足指定的环境条件(例如视口宽度阈值)时,媒体查询会应用 CSS。选择一个实际内容需要不同布局的断点,并考虑组件宽度及周围间距。

结合基础样式和条件样式

媒体查询之外的规则提供基线。当某个条件匹配时,其声明会加入级联;它们不会删除无关的基线声明。在添加断点之前,检查流式尺寸是否可以自然适应内容。请参见 使用 min、max 和 clamp 的流式 CSS 布局 。

.cards { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 33rem) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

在这里,我们使用了相同的选择器并将单列基础样式放在前面,因此后续的条件声明会覆盖该属性。你不应该概括地认为“下面的代码在所有情况下都会生效”。当重要性、级联层的优先级和选择器等相同时,可以比较声明顺序。如果条件为真但没有变化,请在开发者工具中查看目标声明是否被划掉,并找出覆盖它的规则。

根据卡片要求计算断点

首先,检查单张卡片开始变得难以阅读的宽度。在实际操作中,卡片的最小宽度目标(包括边框和内边距)设置为16rem。这不是一个适用于所有网站的标准值,而是本例的设计要求。你应该尝试包括一个较长的标题和描述,并根据实际字体和内容进行调整。

两栏所需的内容宽度为33rem,即16rem×2 加上1rem的列间距。如果文本的左右内边距各为1rem,则所需的视口宽度为35rem。因此,下方完整页面从 35rem 开始显示两列。前面的 33rem 片段只表达两张卡片与一个 gap 所需的内部宽度,没有包含页面左右各 1rem 的内边距。三栏为16rem×3 + 间距1rem×2 + 左右内边距合计 2rem,总共需要52rem。

列 卡片宽度合计 列间距总和 左右内边距合计 断点
1 列 随可用宽度收缩 0 2rem 默认
2 列 32rem 1rem 2rem 35rem
3 列 48rem 2rem 2rem 52rem

我们不将卡片内部的空间加入表格计算的原因是因为我们已经在16rem的最小宽度目标中考虑了它。相反,如果正文与侧边栏共同分配页面宽度,仅凭视口很难保证卡片空间。在这种情况下,请考虑重新计算外部布局条件或使用CSS容器查询为可重用组件确定部分的内部布局。

理解 rem 的基准与包含等号的边界

min-width 在视口宽度大于或等于条件值时匹配,max-width 在视口宽度小于或等于条件值时匹配。如果你的初始字体大小为 16px,35rem 是 560px,而 52rem 是 832px。我们并不总是将 rem 描述为固定的 px 值,因为转换后的值可能会根据用户或浏览器的初始字体设置而有所不同。

在媒体查询中,相对长度使用初始值,而不是页面 CSS 覆盖的字体大小。例如,将 html { font-size: 32px; } 添加到 CSS 并不会自动将 35rem 条件变为 1120px 条件。必须区分文本的 rem 大小变化与媒体条件的变化。 CSS 媒体查询规范:相对单位 详细说明了这一点。

/* Both conditions are true even at 560px. */
@media (max-width: 560px) { /* narrow screen rule */ }
@media (min-width: 560px) { /* wide screen rule */ }

如上所示,具有相同边界的 min 和 max 条件在匹配点处会重叠。您可以通过分阶段添加默认和最小宽度条件来减少这个问题。两栏和三栏条件在大屏幕上也成立,但使用与完整示例中相同的选择器和相同属性,并在之后编写三栏规则,可以产生预期的分步效果。

从一列扩展到两列和三列

将其保存为 media-breakpoint.html 文件,以 UTF-8 编码保存并在浏览器中打开,无需外部文件。示例有三张带标题和链接的卡片,并加入长标题、说明和标识符,便于观察换行。

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>media-breakpoint.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 70rem); margin-inline: auto; padding: 1rem; }
.cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.card { min-width: 0; padding: 1rem; border: 1px solid #789; background: #eef5fa; overflow-wrap: anywhere; }
.card h2 { font-size: 1.25rem; } .card a { display: inline-block; padding: .5rem; }
@media (min-width: 35rem) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 52rem) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
</style>
</head>
<body>
<main class="content"><h1>Choose breakpoints based on the content</h1>
<p>The target minimum card width is 16rem, including the border and padding.</p>
<div class="cards">
<article class="card"><h2>Files and screen settings to prepare</h2><p>The description and link should follow naturally even when the heading wraps onto several lines.</p><a href="#result">Read the first description</a></article>
<article class="card"><h2>Options for narrow screens</h2><p>Reduce the number of columns to make room instead of simply shrinking the text.</p><a href="#result">Read the second description</a></article>
<article class="card"><h2>English identifier</h2><p>ARTICLE_REFERENCE_WITHOUT_SPACES_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p><a href="#result">Read the third description</a></article>
</div><p id="result">Check that links and keyboard focus remain visible on the screen.</p></main>
</body>
</html>

使用 minmax(0, 1fr) 将轨道最小值设为 0,再给卡片设置 min-width: 0,并用 overflow-wrap 处理长字符串,可避免这些最小尺寸约束撑宽布局。然而,这个示例的目的是减少列数,而不是强制字母适应。在最大主体宽度 70rem 下,列不会无限扩展,但三个卡片会分配剩余空间。

比较每个断点前后紧邻的宽度

  1. 在初始字体大小为16px的环境下比较559px、560px和561px。559px应为1列,560px应为2列。
  2. 比较831px、832px和833px。831px应为2列,832px应为3列。在达到精确交界点时确保卡片宽度至少为16rem。
  3. 仅将两个列断点从35rem改为30rem。在480px时,观察卡片宽度是否小于目标且标题行数是否增加,然后恢复为35rem。
  4. 记录显著改变浏览器默认字体设置的条件以及仅改变CSS html字体的条件。不要将其视为相同实验,但要仔细检查每种条件下的宽度和卡片布局。

媒体查询可以测试方向、输入能力以及减少动画的偏好,同时也可以测试宽度。窄屏不一定意味着触摸设备,宽屏也不保证有鼠标。首先完成基于宽度的布局,然后在功能需要时添加其他条件。MDN 使用媒体查询的指南 解释了它们的语法和环境条件。