目前在CSS中有四个支持良好的数学函数。我发现它们中的每一个在我的日常工作中都非常有用。这些CSS函数的使用方式可能出乎意料,比如在梯度和颜色函数中使用,以及与CSS自定义属性结合使用。我们将学习每个函数的语法,观看其功能的基本演示,并探索实际的使用案例。
跳到。
calc()#
calc()的实际用途:执行基本的数学运算,具有在单位类型之间插值的能力(例如:rem到vw)。
这个数学函数在我们探索的四个函数中具有最长的跨浏览器支持。它有广泛的用途,任何时候你都想在你的样式中进行客户端数学运算。
例如,你可能想让某些东西占据大部分视口的高度,除了导航的高度。为此,你可以混合单位来传递一个相对的vh (视图高度)单位和一个绝对的像素单位。
.content { height: calc(100vh - 60px);}
随着视口大小的调整或用户在更大或更小的设备上访问,100vh 的值将动态更新,因此计算也将动态更新。
calc()的好处是允许你避免硬编码一系列神奇的数字,或添加一个JavaScript解决方案来计算所需的值,以应用它作为一个内联样式。
使用calc() ,生成调色板#。
我们可以通过传入CSS自定义属性来扩展calc() 的功能。
一个非常有用的例子是使用hsl() (代表色调、饱和度和亮度)创建一个一致的调色板。给出饱和度、亮度和起始色调的值,我们可以计算出互补的值来建立一个完整的调色板。由于饱和度和亮度值之间的共性,调色板会感觉很有凝聚力。
"使用calc()创建HSL调色板 "的CSS
.colors { --base-hue: 140; --saturation: 95%; --lightness: 80%; --rotation: 60; color: #222; text-align: center;}.color { padding: 0.25rem; background-color: hsl(var(--hue), var(--saturation), var(--lightness));}.color1 { --hue: calc(var(--base-hue));}.color2 { --hue: calc(var(--base-hue) + var(--rotation));}.color3 { --hue: calc(var(--base-hue) + var(--rotation) * 2);}
.color-397 { --base-hue: 140; --saturation: 95%; --lightness: 80%; --rotation:60; 颜色。#222; text-align: center; } .color-397 { padding:0.25rem; background-color: hsl(var(-hue), var(-saturation), var(-lightness)); } .color1-397 { --色调: calc(var(-base-hue)); } .color2-397 { --色调: calc(var(-base-hue) + var(--rotation)) ; } .color3-397 { --色调: calc(var(-base-hue) + var(--rotation) * 2) ; }
- 颜色1
- 颜色2
- 颜色3
clamp()#
clamp()的实际目的:在可接受的数值范围内设置界限。
clamp() 函数需要三个值,而且顺序很重要。第一个是你范围内的最低值,中间是你的理想值,第三个是你范围内的最高值。
你可能已经遇到过使用clamp() 的一个领域,那就是流体排版。其基本概念是,font-size 的值可以根据视口的大小而流动调整。这样做的目的是为了防止大标题触发溢出,或占用太多的视口。
一个非常基本的流体h1 样式的定义。
h1 { font-size: clamp(1.75rem, 4vw + 1rem, 3rem);}
你可以在《现代CSS》第12集中阅读更多关于生成流体类型的内容。
使用clamp()#的相对响应填充。
另一个例子是我在SmolCSS中关于响应式填充的演示。使用百分比填充的有趣之处在于,它是相对于元素的宽度而言的。这意味着它有点像一个相对于容器的单位,我们可以使用类似于你可能认为的vw 。
SmolCSS的例子使用了以下的padding定义,其中padding将相对于元素的宽度增长和缩小。它永远不会小于1rem ,也不会大于3rem 。
.element { padding: 1.5rem clamp(1rem, 5%, 3rem);}
你可能已经意识到,这又消除了一些你以前可能会伸手的媒体查询的场景。你可以为响应式过渡设置合理的准则,而不是对这个间距进行微观管理,或者担心严格遵守一个像素斜率(例如8、12、24、36)。
与媒体查询相比,这里最重要的好处是,由于这个填充定义是相对于元素的,当元素在页面上有更多的空间时,它就会变大,而如果,例如,它被放置在一个狭窄的列中,就会变小。这将需要与基于媒体查询的实用类进行大量的协调!
min()#
min()的实际目的:以包含元素的响应性上下文的方式为最大允许值设定界限。
这是正确的--尽管是min() 函数,其结果是提供的值将作为属性的_最大_允许值。
给定width: min(80ch, 100vw) ,结果是在一个较大的视口上,80ch 将被选中,因为它是两个选项中较小的值,但它却_像_一个基于上下文可用空间的最大值。一旦视口缩小,100vw 将被使用,因为它被计算为_比_ 80ch小,但它实际上是为元素的宽度提供了一个_最大_边界。
现代CSS.container 类#
刚刚提供的例子是我喜欢的定义.container 的方式,只是做了一个小小的调整。min() 函数允许嵌套的基本数学运算,这意味着我们可以翻转到减去一些空间作为定义左右填充的交换,如下所示。
.container { width: min(80ch, 100vw - 2rem);}
在较大的视口上,该元素可以增长到_最大的_ 80ch ,而一旦视口缩小到该宽度以下,它将被允许增长到100vw - 2rem 。这个定义有效地在元素的两边产生了1rem 的 "padding"。
在这个例子中,你也可以换成100% ,而不是vw ,以使元素的宽度在_父容器_中得到响应,就像这个演示中使用的那样。
现代CSS .container类 "的CSS
.container { width: min(40ch, 100% - 2rem); margin-right: auto; margin-left: auto; outline: 1px dashed;}
.container-521 { width: min(40ch, 100% - 2rem); margin-right: auto; margin-left: auto; padding:1rem; color:#222; 轮廓: 1px 虚线; }
Lorem ipsum dolor sit, amet consectetur adipisicing elit.因此,一个quam labore inventore iste eligendi, quasi velit, qui repellendus voluptatem temporibus nisi.Pariatur nesciunt at dolorum, cumque illum maiores animi?
快速提示:
ch单位等于应用时给定的所有当前font属性的0字符的宽度。这使得它成为一个很好的选择,例如,为了获得更好的阅读体验,它可以近似于行的长度。
有什么好处?_无需_媒体查询的响应式尺寸!这似乎是这些函数的一个共同主题 😉
min() 函数是我最常用的数学函数。让我们来看看一些更神奇的实际场景的升级。
使用min()#的响应式元素大小
任何时候你想响应地调整一个元素的大小,min() 都是一个不错的选择。例如,我在Modern CSS第26集探讨了使用min() 来控制评论线程中头像的大小。
在头像的例子中,我们最终应用了_三个_不同单位的值:min(64px, 15%, 10vw) 。另一种解读方式是,头像的大小在任何时候都不会超过其中一个值,浏览器会选择_最小的_计算值。
这个定义意味着头像永远不会大于64px 。特别是在放大的情况下,10vw ,有助于使尺寸感觉更相对。而15% 则有助于保持与元素的相对大小,在应用10vw 之前,可能会有一个更有视觉吸引力的结果。
你希望在你的收件箱中收到CSS技巧吗? 加入我的时事通讯,获取文章更新、CSS技巧和前端资源吧
在其他属性中使用min() #
CSS数学函数可以在大多数允许使用数字值的属性中使用。有一个独特的地方可以使用它们,就是在background-size 。
为什么?也许你要提供一个由背景颜色和图像组成的分层效果。而不是使用cover 大小值,那会使图像填满空间,你想为图像的增长设置上限。这是一个引入min() 的完美地方。
考虑下面的例子,min() 被用来确保图像不超过600px ,同时通过设置100% ,允许图像与元素一起向下响应。换句话说,它将增长_到_ 600px ,当元素的宽度小于600px ,它就会调整自己的大小以配合元素的宽度。
"现代CSS .container类 "的CSS
.background-image { background: #1F1B1C url(https://source.unsplash.com/RapCPd_mJTU/800x800) no-repeat center; background-size: min(600px, 100%);}
.background-image-877 { display: grid; place-items: center; grid-template-areas:"background"; background:#1F1B1C url(source.unsplash.com/RapCPd\_mJT…) no-repeat center; background-size: min(600px, 100%); box-shadow: inset 600px 600px rgba(0, 0, 0, 0.45); } .background-image-877 p { display: grid; place-content: center; grid-area: background; width: min(600px, 100%); outline: 1px dashed; min-height: 8rem; color: white; padding:1rem; }
Lorem ipsum dolor sit, amet consectetur adipisicing elit.意思是说,如果你的工作是为你自己而做的,那么你的工作就是为你自己而做的,而不是为你自己而做的。
max()#
max()的实际目的:以包含元素的响应环境的方式,为最小允许值设定界限。
是的,max() 与min() 正好相反 !所以现在我们正在为_最小_允许值设置定义。让我们直接进入例子!
使用max()#的上下文边距
在学习了《网络内容可及性指南》(WCAG)关于回流的成功标准1.4.10之后,其中规定用户应该能够使用缩放功能将你的网站放大到400%,我注意到在这种情况下,像素和雷姆成为一个不合格的单位。
鉴于桌面尺寸为1280px,缩放比例为400%,你的内容相当于一个设备的320px。然而--相对于手机而言--方向仍然是横向的。这种尺寸的视口意味着阅读和执行操作的区域大大减少。此外,在手机上看起来合适的尺寸,在放大的窗口中观看时就会变得很大。
幸运的是,max() 给我们提供了一种方法,特别是可以更优雅地处理边距。在我的个人工作中,我避免使用像素值,通常喜欢用rem ,用于较小的空间。但对于旨在分隔内容部分的较大空间,我使用以下方法,它允许高的视口有相对增长,而对于短的视口则减少距离,这也适用于放大的视口。
.element + .element { margin-top: max(8vh, 2rem);}
在较高的视口上,将使用8vh ,而在较小或放大的视口上,将使用2rem 。我鼓励你尝试这个方法,并花一些时间在不同的视口、设备、以及放大或不放大你的布局时进行测试。这个技术是一个小的升级,可以为终端用户带来显著的变化。
在《现代CSS》第27集中,我们将回顾这一场景的扩展示例,并学习更多关于回流的知识。
用max()#防止iOS中输入的浏览器缩放
你有没有遇到过在iOS上聚焦表单输入后浏览器强制缩放的情况?这种情况会发生在任何字体大小小于16px 的输入上。
这就是修复方法,最初是在Modern CSS第21集关于自定义表单输入样式的内容中链接的,这个简单的解决方案完全归功于Dan Burzo。
input { font-size: max(16px, 1rem);}
其中1rem 可以用一个Sass变量或一个CSS自定义属性来代替。这种对max() 的使用确保了无论提供什么其他的值,font-size _至少_是16px ,从而防止浏览器强制缩放。
使用max()#的相对焦点轮廓
我最新添加的CSS重置使用min() ,为焦点轮廓应用相对大小。
这是一个缩小的片段,但通过使用max() ,我们确保了_最小的_轮廓尺寸为2px ,同时通过使用font-relativeem 值,允许它相对于元素_增长_。
a { --outline-size: max(2px, 0.08em); --outline-style: solid; --outline-color: currentColor;}a:focus { outline: var(--outline-size) var(--outline-style) var(--outline-color); outline-offset: var(--outline-size);}
使用max()#的可访问目标尺寸
术语 "目标尺寸 "来自WCAG成功标准(SC)2.5.5,其中 "目标 "指的是将收到指针事件(例如,鼠标点击或触摸点击)的区域。在即将发布的WCAG 2.2中,SC 2.5.5现在是 "增强 "版,它的最小尺寸为44px 。
对于这个准则,可以考虑只使用图标的按钮,或者我们前面的例子中链接到个人资料的头像。或者是一个双行动按钮,其中的下拉箭头是一个独立于主要按钮控制的行动。
在这些情况下,我们可以使用max() ,类似于我们提供护栏来防止输入缩放的情况。我们将设置44px ,作为max() 内的一个值,这样_最低限度_,这就是该元素的尺寸。
.icon-button { width: max(44px, 2em); height: max(44px, 2em);}
需要注意的是,这个标准还考虑了元素周围的空间,如果与元素的实际尺寸相结合,_至少_是44px,那么这个标准就成功通过。就像所有这些技术一样,一定要用你的实际产品和真实的用户来进行测试!
使用max() 作为CSSaspect-ratio#的回避。
我使用max() 的另一种方式是在使用aspect-ratio 时设置一个图像高度,以使那些还不支持该属性的浏览器能够获得可接受的体验。
你可以看到下面的样本完全用于SmolCSS演示中的可组合卡片组件。
img { /* Fallback for `aspect-ratio` of defining a height */ height: max(18vh, 12rem); object-fit: cover; width: 100%;}/* When supported, use `aspect-ratio` */@supports (aspect-ratio: 1) { img { aspect-ratio: var(--img-ratio); height: auto; }}
把它放在一起#
这个最后的演示展示了一个应用多个CSS数学函数的例子,以便在多个属性中实现响应式的大小调整。请注意演示代码旁边的注释。
作者:Stephanie Eckles (@5t3ph)
关于使用这些CSS数学函数和其他现代CSS功能的更多例子,请查看我在YouTube上的CSS Cafe演讲。