CSS 数学函数:calc、min、max、clamp

已发表: 2022-03-20
简介 »所有现代 Web 浏览器都支持 CSS 逻辑函数calc()clamp()min()max() 。 但是,尽管很容易获得——一个简单的 GitHub 搜索告诉我们,这些功能的采用速度很慢。 那么,我们究竟如何使用它们来构建流畅和响应式的布局体验呢? 让我们来了解一下。

目录
  • 计算()
  • 分钟()
  • 最大限度()
  • 夹钳()
  • 使用网格创建响应式侧边栏
  • 为 Flexbox 布局应用响应式间隙
  • 我可以使用:支持在那里
  • 结论

我知道你可能在想什么, “数学?! 呸。 把它从我的视线中移开。” . 但是,问问自己——你是否有意志力抵制完美对齐的嵌套容器的满足感?

你知道,在我写了一篇关于各种 CSS 技巧的文章(它被一些出版物采纳)之后,我看到网站的流量是针对诸如“如何使 div 元素居中”之类的关键字,这很有趣,因为我在文章具体。 但这表明开发人员需要访问可以轻松重新实现的快速片段。

因此,这将是本教程的前提。

 更新:我已经开始写一篇详细的教程,用于在 CSS 中居中元素。

在实现各种布局结果的背景下,我将专注于 CSS 数学函数的主题。 例如,如何使用几行 CSS 创建一个响应式容器,如何添加自适应填充,以及如何让侧边栏真正表现得像侧边栏。

我们来看一下。


计算()

calc() 函数支持四种算术运算:加法 (+)、减法 (-)、乘法 (*) 和除法 (/)。 该函数主要用于计算容器的动态宽度和高度,以创建自适应布局体验。

代码示例

.calc { background: #c8e6f5; padding: 10px 20px; width: calc(100% - 200px); } .no-calc { background: #c8e6f5; padding: 10px 20px; margin-top: 10px; } <div class="calc">100% – 200px</div> <div class="no-calc">Default container width</div>

这将是结果:

100% – 200 像素
默认容器宽度

但是, calc()最突出的地方是它用于安排具有特定值的元素。 通常,通过查找特定断点然后单独编写它们的逻辑来实现响应式设计。 使用calc() ——我们可以实现一个响应式布局,只需要一个规范,这使得它更易于维护。

让我们看一个使用display: flex;的具体例子。 . 我们的目标是创建 3 个并排的元素,这些元素与容器的宽度 (100%) 相关联。 我们还想在每个元素之间添加 30px 的间隙,当然,我们需要它是响应式的!

代码示例

<style> .calc-container-flex { display: flex; justify-content: center; } .calc-container-style .item { background: #fff2ea; padding: 20px 0; width: calc((100% - 90px)/3); text-align: center; } .calc-container-style .item + .item { margin-left: 30px; } </style> <div class="calc-container-flex calc-container-style"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div>

在这里你可以调整结果的大小来看看它是如何工作的:

1
2
3

因为我们希望每个元素之间有 30px 的间隙,所以我们从初始容器宽度 (100%) 中减去 90px 并将其除以 3 以指定我们有多少元素。

当您调整上述结果的大小时,您会注意到所有元素都尊重它们各自的间隙,同时保持对容器宽度的响应。 挺整洁的。


分钟()

min() 函数用于设置可接受的最小值。 它采用逗号分隔的 2 个不同规范,并支持算术表达式。

假设您指定font-size: min(25px,1vw); – 在这个例子中,font-size 永远不会大于 25px,并且会根据视口大小缩小到 1vw。

我们还可以使用min()来操作容器元素的宽度。

代码示例

.min-sample-box-container { width: 100%; max-width: 1000px; } .min-sample-box { background: #fff2ea; padding: 15px 30px; width: min(70%, 800px); } <div class="min-sample-box-container"> <div class="min-sample-box">min() example - 800px limit</div> </div>

尝试调整大小:

min() 示例 – 800px 限制

在这种情况下,尽管容器的最大宽度为 1000 像素,但我们容器内的 div 元素的宽度不能超过 800 像素。


最大限度()

max() 函数让我们完全相反。 在这两个值中,我们在max()中指定——最大的一个将被优先考虑。

代码示例

.max-sample-box-container { width: 100%; max-width: 1000px; } .max-sample-box { background: #fff2ea; padding: 15px 30px; width: max(70%, 200px); } <div class="max-sample-box-container"> <div class="max-sample-box">max() example - 200px limit</div> </div>

尝试将其调整为较小的容器,看看会发生什么:

max() 示例 – 200px 限制

正如你所看到的——容器尊重width: 100%; 但不会低于指定的 200px 标记,因为它是容器的最大值。

max()功能在应用响应式边距时特别有用。 通常情况下,当您在布局中使用大量较小的元素时,它们会在调整大小后堵塞屏幕。 使用max()我们可以优先考虑特定的边距以尊重容器宽度。

代码示例

.max-margin-container { display: flex; flex-wrap: wrap; width: 100%; } .max-margin-container li { background: #fff2ea; color: #fff; padding: 3px 25px; min-width: 60px; text-align: center; margin: 0 max(4px,1vw) max(4px,1vw) 0; } <ul class="max-margin-container"><li>calc()</li><li>min()</li><li>max()</li><li>clamp()</li> <li>sin()</li><li>cos()</li><li>tan()</li><li>acos()</li><li>asin()</li><li>atan()</li> <li>atan2()</li><li>hypot()</li><li>sqrt()</li><li>pow()</li></ul>

尝试调整列表的大小以查看它的实际效果:

  • 计算()
  • 分钟()
  • 最大限度()
  • 夹钳()
  • 罪()
  • 余弦()
  • tan()
  • acos()
  • 阿辛()
  • 晒黑()
  • atan2()
  • 假设()
  • sqrt()
  • 战俘()

更改浏览器视口是此演示的一个更好的示例。 而且,是的,这些实际上是 CSS 中所有可用的数学函数!

如您所见,尽管视口的宽度发生了变化,但按钮始终保持 4px 的边距。


夹钳()

clamp() 函数用于定义布局元素的各种值的可接受范围:最小值首选最大值。 最常见的是, clamp()用于为排版设置一系列可接受的值,以创建流畅的排版效果。

本质上,它是min()max()功能的巅峰之作。

一个例子:

font-size: clamp(1rem, 4vw + 1rem, 4rem);

这是它的样子:

CSS 钳位函数示例

在这种情况下,我们将h2标题设置为最小值1rem ,最大值4rem ,并将首选大小设置为4vw (视口单位)+ 1rem 。 正如您从上面的演示中看到的那样,随着我们的视口发生变化,标题的字体大小也会发生变化。

这也结束了我们对 CSS 中最广泛支持的数学函数的介绍。

下一节将专门介绍可以应用这些功能的示例和各种用例。 总的来说,我们的重点是创建响应式设计元素,否则这些元素需要通过媒体查询来编写。

使用网格创建响应式侧边栏

你能用两行 CSS 实现一个功能齐全的响应式侧边栏吗?

绝对地。

对于这个演示,我们将使用display: grid;创建一个响应式侧边栏。 并使用grid-template-columns自定义响应能力。 具体来说,我们将使用fit-contentminmax()函数来设置我们的约束。

代码示例

.grid-sidebar-demo { display: grid; grid-template-columns: fit-content(25ch) minmax(min(55vw, 35ch), 1fr) }

结果如下:

侧边栏内容您的页面内容

让我们了解这里发生了什么。

首先,我们应用fit-content来声明侧边栏的首选大小。 我们在此处指定的值将推动侧边栏增大(基于视口大小)或在较小的屏幕上缩小。 一直在考虑侧边栏中的内容

之后,我们应用minmax()因为我们不希望侧边栏与页面内容区域重叠。 在我们的例子中,湿设置值55vw将用于移动显示, 35ch将用于更大的视口。 最后,当视口允许时,我们应用网格特定的分数单​​位来填充空间。

为 Flexbox 布局应用响应式间隙

这是一个与我们之前看到的响应式填充类似的示例。 但是对于这个演示,我们使用了flexboxgap属性以及clamp()

代码示例

.gap-boxes-container { display: flex; flex-wrap: wrap; gap: clamp(5px, 1vw, 25px); place-content: center; } .gap-box { display: inline-flex; width: 100px; height: 100px; background-color: #fff2ea; align-items: center; justify-content: center; } <div class="gap-boxes-container"> <div class="gap-box">1</div> <div class="gap-box">2</div> <div class="gap-box">3</div> <div class="gap-box">4</div> </div>

试试看:

1
2
3
4

再一次,当您调整实际浏览器视口的大小时,此演示效果最佳。

通过指定gap: clamp(5px, 1vw, 25px); 我们告诉浏览器根据视口大小调整每列之间的间隙。 因此,如果窗口超过 1vw - 间隙将增加到 25px,而小视口会将其减小到 5px(例如在移动设备上)。

顺便说一句,您可能已经注意到我使用了一个有趣的属性来使容器框居中,它是place-content: center; . 这是一个简写属性,支持在各个方向上定位内容。 你可以在 MDN 上阅读更多关于它的信息。

我可以使用:支持在那里

结论

您是否很高兴在您的下一个项目中尝试这些概念?

我不得不说,自 2010 年代初以来,CSS 已经走过了漫长的道路。 事实上,如果我们可以在没有媒体查询的情况下完成大部分响应式样式,它将吸引更多想要编写代码而不担心各种设备之间兼容性的开发人员。

感谢阅读,玩得开心!