现代CSS解决方案:CSS数学函数Calc
时间:2023-03-20 13:51:06
科技观察
在CSS中,其实有各种各样的函数。具体分为:变换函数[1]数学函数[2]过滤函数[3]颜色函数[4]图像函数[5]计数器函数[6]字体函数[7]形状函数[8]参考函数[9]CSSgridfunctions[10]本文将专门介绍四种已被浏览器大规模支持的CSS数学函数(Mathfunctions):calc()min()max()clamp()为什么说支持浏览器?大规模支持?因为除了这四个已经被大规模支持的数学函数外,其实规范CSSValuesandUnitsModuleLevel4[11]已经定义了sin(),cos(),tan()等函数等。指数函数与pow()、sqrt()等数学函数相关,但目前处于实验室阶段,还没有浏览器支持,还需要给它们一些时间。Calc()calc()这个CSS[12]函数允许在声明CSS属性值时执行一些计算。语法类似于:{width:calc(100%-80px);}需要注意的几点:+和-运算符的两边必须有空白字符。例如,calc(50%-8px)将被解析为无效表达式,必须写为calc(8px+-50%)。*和/这两个操作符不需要前后有空格,但如果考虑统一性,还是建议加上空格。除以0将导致HTML解析器抛出异常。自动布局和固定布局的表格中涉及表格列、表格列组、表格行、表格行组、表格单元格的宽高百分比的数学表达式,auto可以按指定处理。calc()函数支持嵌套,但支持的方法是:将嵌套的calc()函数视为普通括号。(因此,只需在函数内直接使用括号即可。)calc()支持与CSS变量混合。看一个最常见的例子,页面结构如下:Content
Footer 页面g-footer的高度为80px。我们希望无论页面有多长,g-content部分都能把剩余的空间填满,像这样:这种布局利用flex灵活的布局很容易实现。当然,也可以用calc()来实现:.g-container{height:100vh;}.g-content{height:calc(100vh-80px);}.g-footer{height:80px;}下面是一些Calc()函数的高级技能。Calc中加减乘除的区别注意calc()中加减乘除的区别:{font-size:calc(1rem+10px);width:calc(100px+10%);}可以看出,加减两边的操作数需要单位,而乘除需要一个无单位的数,只代表一个乘数:{width:calc(100%/7);animation-delay:calc(1s*3);}calc的嵌套calc()函数可以嵌套,像这样:{width:calc(100vw-calc(100%-64px));}这时候内部的calc()function可以退化写成括号(),所以上面的代码等价于:{width:calc(100vw-(100%-64px));},即嵌套了calc(),和几个函数calc的字符可以省略。Calc中不同单位的混合计算calc()支持不同单位的混合计算。对于length,只要是长度相关的单位,都可以进行混合计算,包括这些:px%emreminmmcmptpxchvhvwvminvmax这里有个有意思的地方,计算一定是consumption,在性能方面,早年有这么一段直接让Chrome浏览器崩溃的CSS代码Crash:
CSS样式如下:div{--initial-level-0:calc(1vh+1%+1px+1em+1vw+1cm);--level-1:calc(var(--initial-level-0)+var(--initial-level-0));--level-2:calc(var(--level-1)+var(--level-1));--level-3:计算(var(--level-2)+var(--level-2));--level-4:计算(var(--level-3)+var(--level-3));--level-5:计算(var(--level-4)+var(--level-4));--level-6:计算(var(--level-5)+var(--level-5));--level-7:计算(var(--level-6)+var(--level-6));--level-8:计算(var(--level-7)+var(--level-7));--level-9:计算(var(--level-8)+var(--level-8));--level-10:计算(var(--level-9)+var(--level-9));--level-11:计算(var(--level-10)+var(--level-10));--level-12:计算(var(--level-11)+var(--level-11));--level-13:计算(var(--level-12)+var(--level-12));-等级-14:计算(var(--level-13)+var(--level-13));--level-15:计算(var(--level-14)+var(--level-14));--level-16:计算(var(--level-15)+var(--level-15));--level-17:计算(var(--level-16)+var(--level-16));--level-18:计算(var(--level-17)+var(--level-17));--level-19:计算(var(--level-18)+var(--level-18));--level-20:计算(var(--level-19)+var(--level-19));--level-21:计算(var(--level-20)+var(--level-20));--level-22:计算(var(--level-21)+var(--level-21));--level-23:计算(var(--level-22)+var(--level-22));--level-24:计算(var(--level-23)+var(--level-23));--level-25:计算(var(--level-24)+var(--level-24));--level-26:计算(var(--level-25)+var(--level-25));--level-27:计算(var(--level-26)+var(--level-26));--level-28:计算(var(--level-27)+var(--level-27));--level-29:计算(var(--level-28)+var(--level-28));--level-30:计算(var(--level-29)+var(--level-29));--level-final:calc(var(--level-30)+1px);博尔der-width:var(--level-final);border-style:solid;}可以看出,从--level-1到--level-30,每次的计算量翻倍,最后到--level-final变量,展开会有2^30=1073741824--initial-level-0表达式的内容以及对于每个--initial-level-0表达式--calc(1vh+1%+1px+1em+1vw+1cm),它已经足够复杂了当浏览器解析它时。混合在一起,导致浏览器(Chrome70之前的版本)的BOOM。为了看效果,我们将上面的样式赋值给一个元素,悬停时得到如下效果:css-crash当然,这个BUG现在已经修复了。我们也可以借鉴这个小DEMO。一是calc可以进行不同单元的混合运算。另外就是要注意,如果使用时计算量巨大,可能会导致较大的性能损失。消耗。当然,不要混合使用长度单位和非长度单位,像这样:{animation-delay:calc(1s+1px);}CalcwithCSScustomvariables使用calc()函数的一个非常重要的特性是它可以和CSSCustom和CSS@property变量一起使用。最简单的DEMO::root{--width:10px;}div{width:calc(var(--width));}当然,完全不是这个样子,好像没什么意义。在实际应用场景中,会比上面的DEMO稍微复杂一些。假设我们要实现这样一个加载动画效果,一开始只有3个球:可能的写法是这样的,我们给3个球都加上相同的旋转动画,然后分别控制它们的animation-delay: