媒体查询非常适合在不同屏幕尺寸下以突变的方式更改值。 但是,结合calc()
和视口单位(如vw
和vh
)的强大功能,我们可以使布局更加流畅。 为此,我们将使用一种称为线性插值的技术。
线性插值是用于查找直线上两点之间值的公式。 在我们的案例中,这两个点是 CSS 值,例如我们想要在给定视口宽度范围内插值的**字体大小**、**边距**或**宽度**。
我们可能希望在给定视口宽度范围内插值**之间**的原因是,避免在视口更改时创建多个断点来控制内容的流动。 相反,我们让用户的浏览器根据我们的指令计算它获得的值。 让我解释一下。
以下代码段是基于线性插值的 Sass 函数,我们在Aranja中一直将其称为between。
/**
* Computes a CSS calc function that betweens a value from
* A to B over viewport-width A to viewport-width B.
* Requires a media query to cap the value at B.
*/
@function between($from, $to, $fromWidth, $toWidth) {
$slope: ($to - $from) / ($toWidth - $fromWidth);
$base: $from - $slope * $fromWidth;
@return calc(#{$base} + #{100vw * $slope});
}
该函数的使用方法如下
$small: 400px;
$large: 1000px;
.Container {
/* The base (smallest) value. */
padding: 20px;
/* In $small it should be 20px and in $large it should be 100px, */
/* In viewports between that its padding should be calculated */
@media (min-width: $small) {
padding: between(20px, 100px, $small, $large);
}
/* In $large we cap the value at 100px */
@media (min-width: $large) {
padding: 100px;
}
}
上面的代码示例展示了我们如何将容器的填充从“移动设备”尺寸下的 20px 插值到“桌面”尺寸下的 100px。 介于两者之间的任何尺寸都会得到一个介于 20 到 100 像素之间的计算填充量。 为了防止填充超过最大值,我们使用断点对其进行限制。
尝试调整以下演示的大小以查看示例的实际效果
between
函数擅长解决间距问题。 以前我们会手动使用不同的媒体查询来解决这些问题。
示例布局
才华横溢的Carly Sylvester借给了我以下她为志愿消防员网站设计的线框图,以便我能够在此真实世界布局中演示此技术。

设计文档包含网站的桌面版、平板电脑版和移动版,分别为 1440px、720px 和 324px。
实际上,这些不同设备之间的界限并不那么清晰,因此我们将给定的值作为目标点,并使用我们的函数在其之间进行插值。
请注意,桌面版和平板电脑版的布局相似,除了使用了空白和字体大小——我们能够在它们之间平滑地进行插值。 当我们到达最小的目标点时,我们将布局转换为经典的全宽移动布局。
为了进行比较,让我们看看以通常的方式完成的实现,其中使用 3 个主要断点将布局切换到其新值。
演示视频
between
调整布局大小between
调整布局大小尝试在不同的屏幕尺寸下浏览演示,我们的函数的优势应该很明显。 为了使网站的“常规”版本更好,我们需要除了设计文档中的原始三个断点之外添加更多断点,从而导致更多跳跃。
结合 rem 的强大功能
我们可以使用该函数的一个强大技术是between
根font-size
并基于rems设置样式
rem
单位引用根font-size
(在:root
或html
元素上设置的字体大小)以确定其值,而根font-size
引用**视口宽度**以确定其值。 我们将根font-size
在最小值时设置为 10px,在最大值时设置为 18px,结果是在两者之间平滑过渡。 演示中卡片的最小尺寸为 245px(在我们的$small断点处),并且逐渐增大,直到在我们的$large断点处达到峰值 440px。
结束语
我相信,通过利用这项技术,我们可以为在不符合“移动设备”或“平板电脑”尺寸概括的设备上浏览的用户提供更好的网络体验。 至少对我而言,它也使开发过程更加愉快,因为我的表格上减少了与布局相关的错误。
关于浏览器支持——事实上,我们只需要calc()
和vw
就可以使这项技术发挥作用,这使得它在美国和欧洲的普及率约为97%,在全球约为84%。
例如,在上面的演示中,不支持的浏览器(主要是 Opera Mini 和 UC 浏览器)将使用我们的最低(基本)值或最高(限制)值,具体取决于视口宽度。
很棒的文章。 感谢您提供的有用技巧和很棒的 SCSS 函数!
不客气!
喜欢它。 它可以在电子邮件中使用吗?
我很幸运从未编写过电子邮件样式。 我将让其他人回答这个问题。 感谢您的阅读!
不错。 喜欢它在没有 calc 的情况下降级到基本或最大媒体查询值的方式。
我将您的函数包装在一个 mixin 中,以便您可以执行以下操作
.selector { @include between(padding, 20px, 100px); }
它将为您添加媒体查询
http://codepen.io/tobystokes/pen/NjGOde
感谢您提供的 mixin,Toby。
我决定跳过编写它,以便真正了解函数的工作原理。
这就是精神! 这里确实令人鼓舞的调查水平。 我很好奇是否有一个特定的设计问题引发了这项研究,或者它是否仅仅是一种非常方便的开发方式。
这确实是一种非常好的开发方式。
我多年来一直在游戏开发中使用线性插值,但从未想过将其用于此。 感谢您的启发!
我一直在使用类似的 scss mixin,它从我提供的最小 px 到最大 px 进行过渡,并通过 vw 单位在这两者之间进行过渡。 我更喜欢你的! 你的更通用,语法看起来更容易! 很棒的文章!
一项很棒的技术。 感谢您提供的 mixin :)
太棒了! 太棒了。
很棒的文章! 感谢分享 :)
这太棒了,感谢您的分享,David。 移动/平板电脑/桌面类的笨拙程度令人惊叹,这比试图处理基于百分比的解决方案要好得多。 还要感谢 Toby 提供的 mixin!
彻底的开眼界! 我一直在努力解决现在已经解决的问题——感谢您分享!
很高兴能提供帮助
知道这一点真是太好了! 简单的解决方案,但功能强大!
很棒的文章,只是最后关于 rem 的字体大小示例并没有真正显示任何字体大小调整,这很可惜,因为我在使用 rem 进行字体大小调整时遇到问题,并且希望看到一个好的示例。 尽管如此,代码片段仍然很棒!。
CSS Trick 网站上,一如既往地提供了很棒且有趣的内容。
但我很好奇,有多少人在桌面端调整窗口大小……更不用说平板电脑/智能手机了。
我不确定具体比例,但这将是一个有趣的统计数据!
但我认为你这里的重点可能是这只有在用户调整大小的情况下才有用,我认为这不是该方法的初衷。即使用户从未调整过大小,他们进入时的任何尺寸都可能从这种响应式尺寸思考中受益。
Chris 说得对,Serialspeaker。
我从自身经验举个例子:多年来,我一直引入并扩展 Bootstrap 3 网格系统的一部分,但我从未使用过它们的“固定宽度”容器模型。我更希望所有内容都具有流动性(直到某个最大宽度),并确保布局利用了用户窗口或设备的大小。
David Bachmann 这里提供的函数是实现真正流畅布局的一种方法。(很棒的文章和代码片段!感谢发布,CSS Tricks!)也就是说,我不确定我是否认同浏览器窗口/设备宽度应该始终按比例确定垂直间距的想法。在我过去几周看到的非开发人员的浏览器中,似乎每次打开时,高度都不等于显示器的最大高度,这使得巨大的垂直空白区域没有那么有用。我想知道是否可以对这个函数进行修改,以考虑视口高度,以应对这种情况……
我通常在
body
的font-size
上使用它,然后使用我想用em
单位缩放的值。很棒的工具!感谢所有宝贵的建议!
这篇文章确实以一种很好、简单的方式解释了媒体查询,即使是像我这样的平面设计学生也能理解。
有人可以帮我用 Less 写这个函数吗?
我这里有一个 Less 函数:http://codepen.io/MadeByMike/pen/RWJyML,此外,Stylus、Sass 和 PostCSS 以及其他示例可以在此处找到:https://madebymike.com.au/writing/fluid-type-calc-examples/
来自 Luca Rosaldi,在评论关闭后