当我们给一个元素设置最小、最大宽度,我们自然而然会想到使用 min-width 和 max-width 这两个CSS属性。前缀 min 和 max 分别是最小、最大之意。实际上,CSS 有 min 函数和 max 函数,使用它们我们不仅仅可以设置元素的尺寸,凡可用数值参与表达的属性,都可以通过它们设置最小值和最大值。先来看看 min 函数:
width: min(50%, 200px);
width: min(50%, 400px);
min() 函数支持单值或多值,如果是多值,下一个值与上一个值之间用逗号隔开。多值的时候,浏览器会在这些值当中选取最小的那个值渲染元素对应属性 。例如上例,由于受到父元素 600px 的宽度限制,棕褐色 div 所提供的 min(50%, 200px) 两个值当中,50% 为 300px,显然大于 200px,浏览器选择 200px 作为棕褐色盒子的最终宽度。而粉红色的 div min() 函数参数值是 50% 和 400px,后者大于 50% 所得的 300px,故浏览器以二者中最小的 50% 即 300px渲染粉红色盒子的宽度。上例中,可以尝试拖曳父元素右下角缩小其宽度,我们会发现两个子元素最终均以父元素 50% 的宽度呈现,这是因为 min() 函数的第二个参数值大于 50% 计算出来的值,所以只能以 50% 为最终宽度;往大里拖曳父元素,粉红色尺寸也会发生改变,直到其宽度等于 400px,这是因为当父元素的宽度的一般大于 400px 时,粉红色盒子使用最小的 min() 函数参数值作为自己的最终宽度。
从功能上看,min() 函数用来限制元素指定属性的最小渲染值,函数在执行的时候,浏览器在函数参数值中选取值最小的值返回给元素。max() 函数也是此理,不同的是,它用于限制元素指定属性的最大值、浏览器会从中选取值最大的那个返回给元素。看演示:
width: max(50%, 200px);
width: max(50%, 400px);
上述演示,棕褐色盒子使用 max(50%, 200px) 来限制盒子的最终宽度:当 50% 小于 200px,返回 200px 给元素,反之,当 50% 换算后大于 200px,则返回 50% 给元素。粉红色使用的是 max(50%, 400px),原理与上同。可以尝试改变父元素的宽高查看 50% 与 200px、400px 的大小关系以及元素总是以最大那个值渲染宽度的原则。
可以嵌套使用 min()、max() 函数来规定一个元素的最小值和最大值。以下演示,银白色的盒子使用 max 函数提供两个值宽度值,红色部分是其中的一个值,浏览器将在这两个值之间选取最大的那个;红色值实际上是不确定的,它由 min 函数提供,浏览器将在其内两个值之间选取最小的那一个给前面的 max 函数作比较,最终才定夺使用哪一个值渲染盒子的宽度,可以拉大父元素观察效果:
width: max(350px, min(50%, 500px) );
而实现上面的效果,CSS有专门的函数,clamp(最小值, 首选值, 最大值 ):
clamp(350px, 50%, 500px);
不要被 clamp 函数第二个参数名称 首选值 所误导,它实际上是最小值和最大值之间的弹性值。具体来说,浏览器这样做检测:当 50% 换算所得的值小于最小值,就返回最小值,当 50% 换算所得的值大于最大值,就返回最大值,若 50% 换算所得值在最小值和最大值之间,就返回 50% 换算值。所以,缩小父元素,浅蓝色盒子保持最低宽度为 350px,放宽父元素,在父元素宽度的一半没有达到 500px 之前,子盒子都在加大自己的长度,直至加到 500px 就不会再加。
上述两个演示是等效的,但在 clamp 函数出生以前,老前端程序员们能够使用的唯一方法是 min、max 的嵌套组合。
min、max、clamp 等函数有着广泛的应用场景。我们以 clamp 为例,通过它,希望帖子最小尺寸为 800 * 400、最大尺寸为 1400 * 760,并能在这二者间自适应。看代码:
<style>
#tz {
position: absolute;
width: clamp(800px, 90vw, 1400px);
height: clamp(460px, 90vh, 760px);
left: 50%;
transform: translate(-50%, 20px);
background: #eee;
border: 2px solid teal;
}
</style>
<div id="tz"></div>
点击查看效果
最后强调:使用 min、max、clamp 这三个函数的元素是基于父元素的,就是说,它们的参照为父元素的相关属性设置。父元素可以是上一层的某个 HTML 标签,例如,div、body 等。