我们无法不谈论响应式设计,就谈论 web 开发。这在如今已经成为常识,并且已经存在多年了。媒体查询 是响应式设计的一部分,并且不会消失。自媒体查询出现以来(从字面上来说是几十年前),CSS 已经发展到足以提供许多技巧来帮助我们大幅减少媒体查询的使用。在某些情况下,我将向您展示如何用一个 CSS 声明来替换多个媒体查询。这些方法可以减少代码量,更易于维护,并且与手头的内容更加紧密地结合在一起。
让我们首先看看一些广泛使用的方法,这些方法可以在没有媒体查询的情况下构建响应式布局。这里没有什么惊喜——这些方法与 flexbox 和 grid 相关。
flex
和 flex-wrap
使用 在上面的演示中,flex: 400px
为网格中的每个元素设置了一个基本宽度,等于 400px
。如果当前行没有足够的空间容纳元素,则每个元素都会换行。同时,每行上的元素会增长/拉伸以填充容器中剩余的任何空间(如果该行无法容纳另一个 400px
元素,并且如果确实可以挤进另一个 400px
元素,则它们会缩小到 400px
)。
我们也要记住,flex: 400px
是一个简写形式,等同于 flex: 1 1 400px
(flex-grow: 1
、flex-shrink: 1
、flex-basis: 400px
)。
我们目前的状况
- ✔️ 只有两行代码
- ❌ 页脚中元素宽度一致
- ❌ 控制每行项目数量
- ❌ 控制项目换行的时间
auto-fit
和 minmax
使用 与之前的方法类似,我们正在设置一个基本宽度——感谢 repeat(auto-fit, minmax(400px, 1fr))
——并且如果我们的项目有足够的空间,它们就会换行。但是,这次我们正在使用 CSS Grid。这意味着每行上的元素也会增长以填充剩余的任何空间,但与 flexbox 配置不同的是,最后一行保持与其他元素相同的宽度。
因此,我们改进了一个需求并解决了另一个需求,但也引入了一个新问题,因为我们的项目无法缩小到低于 400px
,这可能会导致一些溢出。
- ✔️ 只有 一行 代码
- ✔️ 页脚中元素宽度一致
- ❌ 控制每行项目数量
- ❌ 项目增长,但不缩小
- ❌ 控制项目换行的时间
我们刚刚查看的两种技术都很不错,但我们也发现它们有一些缺点。但是我们可以通过一些 CSS 技巧来克服这些缺点。
控制每行项目数量
让我们以第一个示例为例,将 flex: 400px
更改为 flex: max(400px, (100% - 20px)/3)
。
调整屏幕大小并注意,即使在超宽屏幕上,每行也永远不会超过三个项目。我们已将每行限制为最多三个元素,这意味着每行在任何给定时间只包含一到三个项目。
让我们分解一下代码
- 当屏幕宽度增加时,我们的容器宽度也会增加,这意味着
100%/3
在某个时刻会大于400px
。 - 由于我们使用
max()
函数作为宽度,并在其中将100%
除以3
,因此单个元素的最大值仅为容器总宽度的三分之一。因此,每行最多有三个元素。 - 当屏幕宽度较小时,
400px
会占据主导地位,我们就会得到初始行为。
您可能还会问:公式中的 20px
值到底是什么?
它是网格模板的 gap
值的两倍,即 10px
乘以二。当一行上有三个项目时,元素之间有两个间隙(中间元素的左侧和右侧各有一个),因此对于 N
个项目,我们应该使用 max(400px, (100% - (N - 1) * gap)/N)
。是的,我们需要在定义宽度时考虑 gap
,但不要担心,我们仍然可以优化公式以将其删除!
我们可以使用 max(400px, 100%/(N + 1) + 0.1%)
。逻辑是:我们告诉浏览器每个项目的宽度等于 100%/(N + 1)
,因此每行 N + 1
个项目,但我们添加了一个很小的百分比(0.1%
)——因此其中一个项目会换行,最终只有 N
个项目在一行上。很聪明,对吧?不必再担心间隙了!
现在我们可以控制每行项目的**最大**数量,这为我们提供了对每行项目数量的部分控制。
同样的方法也可以应用于 CSS Grid 方法。
请注意,这里我引入了 自定义属性 来控制不同的值。
我们越来越接近了!
- ✔️ 只有 一行 代码
- ✔️ 页脚中元素宽度一致
- ⚠️ 对每行项目数量的 部分控制
- ❌ 项目增长,但不缩小
- ❌ 控制项目换行的时间
项目增长,但不缩小
我们之前提到,如果基本宽度大于容器宽度,使用网格方法会导致溢出。为了克服这个问题,我们将更改
max(400px, 100%/(N + 1) + 0.1%)
…为
clamp(100%/(N + 1) + 0.1%, 400px, 100%)
分解一下
- 当屏幕宽度较大时,
400px
被钳制到100%/(N + 1) + 0.1%
,保持我们对每行项目最大数量的控制。 - 当屏幕宽度较小时,
400px
被钳制到100%
,因此我们的项目永远不会超过容器宽度。
我们越来越接近了!
- ✔️ 只有 一行 代码
- ✔️ 页脚中元素宽度一致
- ⚠️ 对每行项目数量的 部分控制
- ✔️ 项目增长和缩小
- ❌ 控制项目换行的时间
控制项目换行的时间
到目前为止,我们无法控制元素从一行换到另一行的时机。我们并不真正知道它何时发生,因为这取决于许多因素,比如基本宽度、间隙、容器宽度等等。为了控制这一点,我们将更改最后一个 clamp()
公式,从这个
clamp(100%/(N + 1) + 0.1%, 400px, 100%)
…为
clamp(100%/(N + 1) + 0.1%, (400px - 100vw)*1000, 100%)
我能听到你在尖叫,说这个公式看起来很疯狂,但是请耐心点。其实它比你想象的要简单。下面是发生的事情
- 当屏幕宽度 (
100vw
) 大于400px
时,(400px - 100vw)
会产生一个负值,并且会被钳制到100%/(N + 1) + 0.1%
,这是一个正值。这使我们每行有 N 个项目。 - 当屏幕宽度 (
100vw
) 小于400px
时,(400px - 100vw)
是一个正值,并乘以一个被钳制到100%
的大值。这会导致每行有 一个 全宽度元素。
嘿,我们创建了第一个没有真正媒体查询的媒体查询!通过 clamp()
公式,我们正在将每行项目数量从 N 更新为 1。需要注意的是,400px
在这种情况下充当断点。
那么:从每行 N 个项目到每行 M 个项目?
我们可以通过更新容器的钳制宽度来做到这一点
clamp(100%/(N + 1) + 0.1%, (400px - 100vw)*1000, 100%/(M + 1) + 0.1%)
我想你现在可能已经明白了诀窍。当屏幕宽度大于 400px
时,我们会进入第一个规则(每行 N
个项目)。当屏幕宽度小于 400px
时,我们会进入第二个规则(每行 M
个项目)。
完成了!现在我们可以控制每行项目数量,以及该数量何时应该更改——只需使用 CSS 自定义属性和一个 CSS 声明即可。
- ✔️ 只有 一行 代码
- ✔️ 页脚中元素宽度一致
- ✔️ 完全控制每行项目数量
- ✔️ 项目增长和缩小
- ✔️ 控制项目换行的时间
更多示例!
控制两个值之间的项目数量很好,但对多个值进行控制会更好!让我们尝试从每行 N
个项目到每行 M
个项目,再到每行一个项目。
我们的公式变为
clamp(clamp(100%/(N + 1) + 0.1%, (W1 - 100vw)*1000,100%/(M + 1) + 0.1%), (W2 - 100vw)*1000, 100%)
在 clamp()
中使用 clamp()
?没错,这会让代码变得很长很复杂,但仍然很容易理解。请注意其中的 W1
和 W2
变量。由于我们在三个值之间更改每行的项目数量,因此需要两个“断点”(从 N
到 M
,以及从 M
到 1
)。
以下是发生的事情
- 当屏幕宽度小于
W2
时,我们将限制为100%
,即**每行一个项目**。 - 当屏幕宽度大于
W2
时,我们将限制为第一个clamp()
。 - 在第一个限制中,当屏幕宽度小于
W1
时,我们将限制为100%/(M + 1) + 0.1%)
,即**每行 M 个项目**。 - 在第一个限制中,当屏幕宽度大于
W1
时,我们将限制为100%/(N + 1) + 0.1%)
,即**每行 N 个项目**。
我们使用一个 CSS 声明创建了两个媒体查询!不仅如此,我们还可以通过 CSS 自定义属性调整该声明,这意味着我们可以为不同的容器设置不同的断点和不同的列数。
上面的例子中我们有多少个媒体查询?太多数不过来,但我们不会就此止步。我们可以嵌套另一个 clamp()
来创建更多媒体查询,从而实现**从 N 列到 M 列到 P 列到一列**的布局。(😱)
clamp(
clamp(
clamp(100%/(var(--n) + 1) + 0.1%, (var(--w1) - 100vw)*1000,
100%/(var(--m) + 1) + 0.1%),(var(--w2) - 100vw)*1000,
100%/(var(--p) + 1) + 0.1%),(var(--w3) - 100vw)*1000,
100%), 1fr))

N
列到 M
列到 P
列到 1 列正如我在本文开头提到的,我们创建了一个响应式布局,它不使用任何媒体查询,只使用一个 CSS 声明——当然,这是一个很长的声明,但仍然算作一个声明。
以下是我们所做的简要总结
- ✔️ 只有 一行 代码
- ✔️ 页脚中元素宽度一致
- ✔️ 完全控制每行项目数量
- ✔️ 项目增长和缩小
- ✔️ 控制项目换行的时间
- ✔️ 使用 CSS 自定义属性易于更新
让我们模拟容器查询
每个人都对容器查询感到兴奋! 它们之所以很酷,是因为它们考虑的是元素的宽度,而不是视窗/屏幕的宽度。其理念是,元素可以根据其父容器的宽度进行调整,从而更精细地控制元素对不同上下文的响应。
在撰写本文时,容器查询还没有得到任何地方的正式支持,但我们当然可以使用我们的策略来模仿它们。如果我们在整个代码中将 100vw
替换为 100%
,那么所有内容都将基于 .container
元素的宽度,而不是视窗宽度。就这么简单!
调整下面容器的大小,看看神奇的效果
列数会根据容器宽度进行变化,这意味着我们正在模拟容器查询!我们实际上只是通过将视窗单位更改为相对百分比值来实现这一点。
更多技巧!
既然我们可以控制列数,那么让我们来探索更多技巧,这些技巧可以让我们根据屏幕大小(或元素大小)创建条件 CSS。
条件背景颜色
不久前,StackOverflo 上的某个人问过 是否可以根据元素的宽度或高度更改其颜色。许多人说这是不可能的,或者需要使用媒体查询。
但我发现了一个无需使用媒体查询就能实现此功能的技巧
div {
background:
linear-gradient(green 0 0) 0 / max(0px,100px - 100%) 1px,
red;
}
- 我们有一个线性渐变层,其宽度等于
max(0px,100px - 100%)
,高度等于1px
。高度并不重要,因为渐变默认情况下会重复。此外,它是一个单色渐变,因此任何高度都可以满足要求。 100%
指的是元素的宽度。如果100%
计算得出的值大于100px
,则max()
会返回0px
,这意味着渐变不会显示,但用逗号分隔的red
背景会显示。- 如果
100%
计算得出的值小于100px
,则渐变会显示,我们将会得到一个green
背景。
换句话说,我们根据元素的宽度与 100px
的比较创建了一个条件!
此演示在撰写本文时支持 Chrome、Edge 和 Firefox。
我们可以通过重新排列 1px
值的位置来根据元素的高度而不是宽度来实现相同的逻辑:1px max(0px,100px - 100%)
。我们还可以通过使用 vh
或 vw
而不是 %
来考虑屏幕尺寸。我们甚至可以添加更多渐变层来使用两种以上的颜色。
div {
background:
linear-gradient(purple 0 0) 0 /max(0px,100px - 100%) 1px,
linear-gradient(blue 0 0) 0 /max(0px,300px - 100%) 1px,
linear-gradient(green 0 0) 0 /max(0px,500px - 100%) 1px,
red;
}

切换元素的可见性
为了根据屏幕大小显示/隐藏元素,我们通常会使用媒体查询,并在其中放置一个经典的 display: none
。以下是一种模拟相同行为的方法,但无需使用媒体查询
div {
max-width: clamp(0px, (100vw - 500px) * 1000, 100%);
max-height: clamp(0px, (100vw - 500px) * 1000, 1000px);
overflow: hidden;
}
根据屏幕宽度 (100vw
),我们将 max-height
和 max-width
限制为 0px
值(表示元素隐藏),或者限制为 100%
(表示元素可见,且永远不会大于全宽)。我们之所以没有使用百分比作为 max-height
,是因为它会失败。因此,我们使用了较大的像素值 (1000px
)。
请注意,绿色元素在小屏幕上会消失
需要注意的是,此方法并不等同于切换 display 值。这更像是让元素的尺寸变为 0×0,从而使其不可见。它可能并不适合所有情况,因此请谨慎使用!这更像是一个用于装饰性元素的技巧,我们不会遇到可访问性问题。Chris 曾经写过关于如何负责任地隐藏内容。
重要的是要注意,我在 clamp()
和 max()
中使用的是 0px
,而不是 0
。后者会使属性失效。我不会深入研究这一点,但我在一个与这个怪癖相关的 Stack Overflow 问题中回答过这个问题,如果你想了解更多细节,可以查看一下。
更改元素的位置
当我们处理固定位置或绝对位置的元素时,以下技巧很有用。这里不同的是,我们需要根据屏幕宽度更新位置。与前面的技巧一样,我们仍然依赖于 clamp()
和一个看起来像这样的公式:clamp(X1,(100vw - W)*1000, X2)
。
基本上,我们将根据 100vw - W
的差值在 X1
和 X2
值之间切换,其中 W
是模拟断点的宽度。
举个例子,我们希望将一个 div 放在左侧边缘 (top: 50%; left:0
),当屏幕大小小于 400px
时,并在其他地方 (例如 top: 10%; left: 40%
) 放置它,否则。
div {
--c:(100vw - 400px); /* we define our condition */
top: clamp(10%, var(--c) * -1000, 50%);
left: clamp(0px, var(--c) * 1000, 40%);
}
首先,我使用 CSS 自定义属性定义了条件,以避免重复。请注意,我还将其与之前看到的背景颜色切换技巧一起使用——我们既可以使用 (100vw - 400px)
,也可以使用 (400px - 100vw)
,但请注意后面的计算,因为两者符号不同。
然后,在每个 clamp()
中,我们始终从每个属性的最小值开始。不要错误地认为我们需要先放置小屏幕的值!
最后,我们定义每个条件的符号。我选择了 (100vw - 400px)
,这意味着当屏幕宽度小于 400px
时,此值将为负值,而当屏幕宽度大于 400px
时,此值将为正值。如果需要 clamp()
的最小值在 400px
以下被考虑在内,那么我不会对条件的符号做任何修改(保持其为正值),但如果需要在 400px
以上考虑最小值,那么我需要反转条件的符号。这就是你看到 (100vw - 400px)*-1000
与 top
属性一起使用的原因。
好的,我明白了。这不是最容易理解的概念,所以让我们反过来推理,并跟踪我们的步骤,以便更好地理解我们正在做什么。
对于 top
,我们有 clamp(10%,(100vw - 400px)*-1000,50%)
,所以…
- 如果屏幕宽度 (
100vw
) 小于400px
,那么差值 (100vw - 400px
) 将为负值。我们将其乘以另一个大的负值 (本例中为-1000
),以获得一个大的正值,该值被限制为50%
:这意味着当屏幕大小小于400px
时,我们将得到top: 50%
。 - 如果屏幕宽度 (
100vw
) 大于400px
,那么我们将得到:top: 10%
。
相同的逻辑适用于我们在 left
属性中声明的内容。唯一的区别是我们乘以 1000
而不是 -1000
。
这里有一个秘密:你并不真的需要所有的数学运算。你可以不断尝试,直到找到合适的数值,但为了本文的解释,我需要以一种能带来一致行为的方式来解释事情。
需要注意的是,像这样的技巧适用于任何接受长度值的属性(padding
、margin
、border-width
、translate
等)。我们并不局限于更改 position
,还可以更改其他属性。
演示!
你们中大多数人可能想知道,这些概念是否能在现实世界的用例中实际应用。让我向你们展示一些例子,它们(希望)能说服你们,这些概念是可行的。
进度条
背景颜色改变的技巧可以制作一个很棒的进度条,或者任何需要根据进度显示不同颜色的类似元素。
此演示在撰写本文时支持 Chrome、Edge 和 Firefox。
那个演示是一个非常简单的例子,我在其中定义了三个范围
- 红色: [
0% 30%]
- 橙色: [
30% 60%]
- 绿色: [
60% 100%]
没有疯狂的 CSS 或 JavaScript 来更新颜色。一个“神奇”的背景属性使我们能够拥有一个动态颜色,它根据计算的值而改变。
可编辑内容
通常会给用户提供一种编辑内容的方式。我们可以根据输入的内容来更新颜色。
在下面的例子中,当输入超过三行文本时,我们会得到一个黄色的“警告”,如果超过六行,则会得到一个红色的“警告”。这可以是一种减少需要检测高度然后添加/删除特定类的 JavaScript 的方法。
此演示在撰写本文时支持 Chrome、Edge 和 Firefox。
时间轴布局
时间轴是可视化时间关键时刻的绝佳模式。这种实现使用了三个技巧来实现一个没有媒体查询的时间轴。一个技巧是更新列数,另一个是在小屏幕上隐藏一些元素,最后一个是更新背景颜色。同样,没有媒体查询!
当屏幕宽度低于 600px
时,所有伪元素都会被移除,将布局从两列改为一列。然后颜色从蓝色/绿色/绿色/蓝色模式更新为蓝色/绿色/蓝色/绿色模式。
响应式卡片
这是一个响应式卡片方法,其中 CSS 属性根据视窗大小更新。通常,我们可能期望布局从大屏幕上的两列过渡到小屏幕上的单列,其中卡片图片叠放在内容的上方或下方。然而,在这个例子中,我们改变了图片的位置、宽度、高度、填充和边框半径,以获得一个完全不同的布局,其中图片位于卡片标题旁边。
气泡
需要一些好看的评价来展示你的产品或服务吗?这些响应式气泡几乎适用于任何地方,即使没有媒体查询。
固定按钮
你知道那些有时固定在屏幕左侧或右侧边缘的按钮吗?通常用于链接到联系方式或调查?我们可以在大屏幕上使用一个这样的按钮,然后把它转换成一个固定在小屏幕右下角的持续圆形按钮,以方便点击。
固定提醒
再演示一个,这次是关于那些 GDPR cookie 通知的东西。
结论
媒体查询自“响应式设计”这个词诞生以来,一直是响应式设计的一个核心要素。虽然它们肯定不会消失,但我们介绍了一堆更新的 CSS 功能和概念,它们使我们能够减少对媒体查询的依赖,以创建响应式布局。
我们研究了 Flexbox 和 Grid、clamp()
、相对单位,并将它们结合在一起,做各种各样的事情,从根据容器宽度改变元素的背景,到在特定屏幕尺寸下移动位置,甚至模拟尚未发布的容器查询。令人兴奋的事情!而且这一切都没有在 CSS 中使用任何 @media
。
这里的目标不是消除或替换媒体查询,而是更多地优化和减少代码量,尤其是 CSS 已经发展了很多,现在我们有一些强大的工具来创建条件样式。换句话说,看到 CSS 功能集在让我们的前端开发工作更容易的同时,赋予我们控制设计行为的能力,这真是太棒了。
这里有一些巧妙的东西,但是……
也许它太巧妙了?
有时编写更具表现力、更易读的代码会更好。尤其是在大型团队或能力/技能范围较广的团队中。
媒体查询是自说明的。
我认为上面的例子中的一些需要大量的注释来解释逻辑,而这有点违背了编写更少代码的目的。
但这仅仅是我(谦虚的)意见。;)
这里的目标不是消除或完全替换媒体查询。我正在探索不同的技术/想法,使您能够根据屏幕(或容器)宽度拥有条件 CSS。
在文章的最后,除了媒体查询之外,您将掌握更多技巧,您可以根据需要正确地使用它们。
我不会建议您到处使用
clamp()
来编写意大利面条代码,但在某些情况下,您可以用一个可以使用 CSS 变量调整的clamp()
来替换两个(或更多)媒体查询。为此,您可以在 CSS 变量旁边添加一些注释,您的代码就完美了;)您说“媒体查询是自说明的”,这是因为它们已经使用了十多年了。我正在提出“新的”技巧,任何新的东西都不一定容易消化。实际上,当人们在代码中找到
clamp()
时,他们会感到有点惊讶,但将来它会变得微不足道,通过简单地查看代码,我们就可以轻松地理解那里发生了什么;)再次强调,我不是来告诉您“不要使用媒体查询”。我来告诉您“嘿,您也可以用另一种方式,不使用媒体查询”;)
感谢您的文章!这正是我对一个名为“CSS 技巧”的网站的期望;)
所有这些都是 CSS 创意精通的绝佳例子,但我同意 Kev 的观点,没有您提供的逐步指导,反向工程您的代码可能非常困难;)
无论如何,作为一名热爱 CSS 神奇性质的人,我真的很享受它!
我完全同意“具表现力、易读的代码”,但在这种情况下,您完全可以从它中创建一个 SASS 混合,并为您的开发人员提供良好的使用体验。
我不得不赞同 Kev 的观点。我不会使用它,因为媒体查询/容器查询是为了这种行为而设计的,而
clamp
则不是。尽管如此,我还是喜欢这篇文章。这是一个很酷的技巧,可以尝试一下,而且很高兴知道它的存在,但不要在生产代码中使用它。
在上面的几个例子中,太巧妙了,对于 Safari 来说……但随着时间的推移,它会学会的。
我真正喜欢的是,它将响应性保持在样式规则内。
太多情况下,您会看到与样式规则“附加”在一起的媒体查询/查询在代码中完全与样式规则分离,尤其是在较旧的代码库中。
当有人(咳咳)决定将不同元素的响应式 CSS 合并到一个断点媒体查询中以最大程度地减少相同媒体查询的重复次数以及整体 CSS 大小时,情况会变得更糟。
出于好意,但这很难使用,最适合构建像 postcss-combine-media-query 这样的工具/插件。
没错!此外,除了响应式在样式规则内,我们还可以使用 CSS 变量轻松地调整它,这使我们能够为不同的元素拥有不同的响应式行为,而无需重复任何代码;)
引用《老爸的军队》中的弗雷泽中士的话,“我们完蛋了”。
容器查询将会到来,我们将都会说“哈利路亚”,WebKit 将延迟实施足够长的时间来支撑 App Store 更长的时间,松鼠会疯狂地更新 npm 包和依赖项,事情会崩溃并得到修复,polyfill 会增加,每个人都会在新的代码块下团结起来。
与此同时,这就是您的解决方案。我只是想不出一个合适的原子类名来避免重复。
很棒的文章,我喜欢你解释公式。
我强烈推荐这种方法而不是媒体查询,虽然公式应该始终有很好的注释,否则含义可能会丢失。我不知道是否相信大多数程序员甚至会为此费心。
求求你,上帝,让所有浏览器都支持子网格,这样会让事情变得更容易。他们在等什么?
感谢你进行这次精彩的探索!这确实是高质量的边缘内容。
很棒的帖子!
不过我会将那些非常长且复杂的 CSS 行拆分成具有有意义名称的变量。
太棒了!
通过遵循步骤,我很容易就能看出如何摆脱 Bootstrap 的网格布局。在一个试图使代码更小的世界里,这消除了导入最后一个部分的需要,只需添加一些小的修改。
感谢这篇很棒的文章,我从中学习了很多。
我认为这种响应式方法会让阅读 CSS 更难。使用媒体查询,我们可以获得确切的断点像素,任何人都可以理解,无需阅读代码。
我必须不同意这一点。
“使用媒体查询,我们可以获得确切的断点像素” -> 我也可以像媒体查询一样获得确切的断点像素。我正在使用更少的代码模拟媒体查询的相同行为。
“任何人都可以理解,无需阅读代码。” -> 你这么说,是因为你对媒体查询太熟悉了,而且媒体查询已经存在十多年了。媒体查询被广泛使用,这使得它们“容易”,但仍然没有人能一目了然地理解它们。你无法想象有多少人会对 min-width/max-width 搞混,或者媒体查询语法或媒体查询的顺序感到困惑。我们不要谈论特异性问题。你仍然需要阅读媒体查询的文档才能理解它们,它们并不直观。
我的逻辑比媒体查询“更容易”,但它是一种新事物,任何新事物看起来都很难,因为我们不习惯它。我们需要给它时间,如果人们开始使用它,它就会变得“容易”,因为这种代码将被广泛使用和记录。我们不能忘记我的逻辑依赖于 CSS 变量,因此你所要做的就是更新这些变量。如果它们有良好的文档记录,你甚至不需要检查代码。我们不能对媒体查询说同样的话。
我发现,当尝试使用 Responsive Card 示例时,如果视窗宽度等于 `--w` 自定义属性值,你将无法获得所有属性在最小和最大 clamp 值之间切换的预期结果。当它们相等时,`--c: (100vw - var(--w))` 为 0px,因此 `var(--c)*-1000` 和 `var(--c)*1000` 的值都相同,为 0px,并且所有属性都使用最小 clamp 值,而不是一个更改为最大值,另一个更改为最小值。
似乎可以使用永远不会等于视窗宽度的值来避免这种情况。也就是说,使用非整数,例如 `--w: 450.1px;`。或者,添加一个很小的百分比,例如 `--c: (100vw - var(--w) + .1%)`;这可能更可取,这样“断点”值仍然是一个不错的整数。
Responsive card 示例中,精确的 450px 怎么办?https://codepen.io/t_afif/pen/abyLYGy 布局坏了。
你可以通过使用诸如 450.05px 或 450.99px 之类的值来避免此问题。浏览器无法使用(或很少使用)的值作为宽度。
嗨,有没有办法在 div 换行到另一行时将它们居中?
在这个 CodePen 中,它们没有居中。https://codepen.io/t_afif/pen/bGqbgYY
不幸的是,使用这种配置和 CSS 网格通常无法实现这一点。你需要尝试使用 Flexbox 的其他方法。
实际上,我还没有看到如何将响应式技巧与居中结合起来。