为什么CSS中的calc函数可能会不生效?
前言
在早期如果想要对某一些样式进行动态计算,绝大多数的做法都是使用JavaScript来进行,当时的CSS在面对这种场景显得有点无能为力。但是,当CSS3中新增了calc
函数时,面对这种场景,JavaScript不再是我们的第一选择,我们只用 CSS 就可以进行相当复杂的计算了。在使用calc
的过程中,相信大家或多或少都遇到过下面这些“坑”。
如果这篇文章有帮助到你,️关注+点赞️鼓励一下作者,文章公众号首发,关注 前端南玖
第一时间获取最新文章~
常见的“坑”
先来介绍css使用calc
无效的两种常见情况:
运算符之间没加空格
/*错误写法*/
div{
width: calc(100%-50px);
}
/*正确写法*/
div{
width: calc(100% - 50px);
}
这里错误写法中-
两边没加空格,导致width不生效。但并不是所有运算符间都需要加空格,只有 +
和 -
需要加空格,因为运算允许负数的出现,如:
div{
width: calc(100% + -50px);
}
所以,为了统一,建议所有运算符都加上空格,防止记忆混淆。
运算值没带单位
我们都知道在写css时,如果数值为0我们一般会省略它的单位,比如:0px
我们一般会直接写成0
。但是在calc()
函数中如果0不带单位,也会导致不生效。
/*错误写法*/
div{
width: calc(0 + 100px);
}
/*正确写法*/
div{
width: calc(0px + 100px);
}
这里上面的不带单位的写法也是不生效的。这里我相信很多人都会有疑问,为什么0还需要带个单位?
这是因为calc()
函数传入的是一个数学表达式,而表达式的值可以有多种类型,如长度、百分比、角度等。那如果你传个 0 进去,没单位的话,怎么知道这个 0 是属于什么类型?
低版本less处理calc冲突
以下代码在低版本less中会被编译成你意想不到的结果:
.box {
width: calc(100% - 50px)
}
编译后:
.box {
width: calc(50%)
}
导致这个结果的原因在于less中有一套自己的运算规则:
less运算(Operations)
算术运算符 +
、-
、*
、/
可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。
// 所有操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm
// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // 结果是 4px
// example with variables
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%
乘法和除法不作转换。因为这两种运算在大多数情况下都没有意义,一个长度乘以一个长度就得到一个区域,而 CSS 是不支持指定区域的。Less 将按数字的原样进行操作,并将为计算结果指定明确的单位类型。
所以上面的less会被进行如下处理:
- 由于100%与50px单位不同,会被转换成相同的单位%(以最左侧操作数的单位类型为准)
- 再进行减法运算得到50%
解决方案
- 转义
转义(Escaping)允许你使用任意字符串作为属性或变量值。任何
~"anything"
或~'anything'
形式的内容都将按原样输出,除非 interpolation。
我们希望less不要帮我们处理,所以这里我们可以使用less的转义语法让calc
函数原样输出就好了
.box {
width: calc(~"100% - 50px")
}
- 升级
less
和less-loader
了解calc函数
CSS calc 函数用于在指定 CSS 属性值时执行计算。它可以用于可以使用任何数值的地方。它将表达式作为参数,并将结果用作使用它的 CSS 属性的值。我们可以用它进行加法
+
、减法-
、乘法*
和除法/
。
语法
/* property: calc(expression) */
width: calc(100% - 80px);
calc() 函数用一个表达式作为它的参数,用这个表达式的结果作为值。这个表达式可以是任何如下操作符的组合,采用标准操作符处理法则的简单表达式。
+
加法-
减法*
乘法,乘数中至少有一个是 number/
除法,除数必须是number
规则
+
和-
运算符的两边必须要有空白字符。 比如,calc(50% -8px)
会被解析成为一个无效的表达式,解析结果是:一个百分比 后跟一个负数长度值。而加有空白字符的、有效的表达式calc(8px + -50%)
会被解析成为:一个长度 后跟一个加号 再跟一个负百分比。*
和/
这两个运算符前后不需要空白字符,但如果考虑到统一性,仍然推荐加上空白符。- 用 0 作除数会使 HTML 解析器抛出异常。
- 涉及自动布局和固定布局的表格中的表列、表列组、表行、表行组和表单元格的宽度和高度百分比的数学表达式,
auto
可视为已指定。 calc()
函数支持嵌套,但支持的方式是:把被嵌套的calc()
函数全当成普通的括号。
解惑
想要了解前面那些坑产生的原因,我们得先了解CSS中的基础语法与数据类型:
DIMENSION语法
DIMENSION {num}{ident}
这里的num
值的是数字,那么ident
代表什么呢,这个我们也可以在CSS规范中找到答案
ident
ident [-]?{nmstart}{nmchar}*
nmstart和nmchar
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
解惑calc(100%-50px)
了解完CSS的基础语法与数据结构,我们现在可以来看看解析器是如何解析calc(100%-50px)
的。
- 首先DIMENSION语法,{num}{ident}会将其分割为
num:100
、ident:%和-100px
%
是单位,这个应该没有疑问-100px
这个符合nmchar语法,所以没有将其拆开,而是保留作为单位解析,但CSS中没有-100px
这个单位,所以这个表达式不会生效
兼容性
calc 函数具有惊人的浏览器支持,一直到 IE9。如果你用旧版浏览器或 Opera Mini 编写代码,请考虑使用数值作为后备。
最后
喜欢的同学欢迎点个赞呀,想要查看源码的同学快来公众号回复碎片吧~
我是南玖,我们下期见!!!
为什么CSS中的calc函数可能会不生效?的更多相关文章
- CSS中常用的函数
一.CSS函数的用法 设置css的属性值时可以使用css函数,如果color:rgba(20,30,50,0.5),css中有很多这样的函数. 二.常用的CSS函数 a.calc()函数 这个函数 ...
- 分类器是如何做检测的?——CascadeClassifier中的detectMultiScale函数解读
原地址:http://blog.csdn.net/delltdk/article/details/9186875 在进入detectMultiScal函数之前,首先需要对CascadeClassifi ...
- 关于CSS中的定位使用子绝父相(子类绝对位置和父类相对位置)
关于CSS中的定位使用子绝父相(子类绝对位置和父类相对位置) 欢迎转发,但是请填写原博客地址https://www.cnblogs.com/JNovice/p/9536910.html 前言:最近在 ...
- CSS中的偏僻知识点
一.css中的calc 在CSS中有calc属性用于尺寸的计算,可以让百分比和像素值进行运算. div {width : calc(100% - 30px);} 为了兼容性 /*Firefox*/ - ...
- CSS 中 calc() 函数用法
CSS calc() 函数 calc() 函数用于动态计算长度值. 注意,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px): 任何长度值都可以使用calc()函数进 ...
- 理解CSS中的数学表达式calc()
前面的话 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路.本文将介绍calc()的相关内容 定义 数学表达式calc()是calculat ...
- CSS中新属性calc()
CSS3的calc()使用 原文: http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html © w3cplus.com calc( ...
- css中的数学表达式calc()
前言 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路. 概念 数学表达式calc()是calculate计算的缩写,它允许使用+.-.*. ...
- css绘制特殊图形,meida查询,display inline-box间隙问题以及calc()函数
本文同时发表于本人个人网站 www.yaoxiaowen.com 距离上一篇文章已经一个月了,相比于写代码,发现写文章的确是更需要坚持的事情.言归正传,梳理一下这一个月来,在写ife任务时,有必要记录 ...
随机推荐
- C++ 漫谈哈夫曼树
1. 前言 什么是哈夫曼树? 把权值不同的n个结点构造成一棵二叉树,如果此树满足以下几个条件: 此 n 个结点为二叉树的叶结点 . 权值较大的结点离根结点较近,权值较小的结点离根结点较远. 该树的带权 ...
- 一例智能网卡(mellanox)的网卡故障分析
一例智能网卡(mellanox)的网卡故障分析 背景:这个是在centos 7.6.1810的环境上复现的,智能网卡是目前很多 云服务器上的网卡标配,在oppo主要用于vpc等场景,智能网卡的代码随着 ...
- Navicat的使用与python中使用MySQL的基本方法
Navicat的使用与python中使用MySQL的基本方法 Navicat的下载及安装 下载地址 http://www.navicat.com.cn/download/navicat-premium ...
- 每个开发人员都应该关注的7个优秀的GitHub仓库
目录 1. FreeCodeCamp 2. Developer Roadmap 3. Awesome 4. Build Your Own X 5. Git Ignore 6. System Desig ...
- ARC125E - Snack (网络流)
题面 有 N N N 种糖果, M M M 个小孩子,第 i i i 种糖果有 A i A_i Ai 个,第 i i i 个孩子不能有超过 B i B_i Bi 个同种类型的糖果,第 i i i ...
- 第五十一篇:webpack中的loader(二) --less-loader
好家伙 先扩充一下知识点: 什么是.less文件? 作为一名前端开发的同学,很多时候我们都无法避免地要去写大量的 CSS 代码, 而且耗费的时间还不少,所以学习一种能够提升开发效率的 CSS 预处理器 ...
- vue3中defineComponent 的作用
vue3中,新增了 defineComponent ,它并没有实现任何的逻辑,只是把接收的 Object 直接返回,它的存在是完全让传入的整个对象获得对应的类型,它的存在就是完全为了服务 TypeSc ...
- MyBatis标签之Select resultType和resultMap
摘要:介绍MyBatis 中Select标签的两个属性resultType和resultMap及其区别. 1 MyBatis动态SQL之if 语句 2 MyBatis动态sql之where标签|转 3 ...
- 如何使用Arthas定位问题
在我们日常的工作中,经常会遇到一些线上才会遇到的问题.Arthas无疑是我们在工作中,定位线上问题的神奇.下面,我将介绍一下我们在工作中经常用到的一些功能. dashboard 首先我们可以通过das ...
- 配置Kubelet的垃圾回收
文章转载自:https://www.kuboard.cn/learning/k8s-advanced/gc.html Kubelet的垃圾回收功能可以清理不再使用的容器和镜像,kubelet对容器进行 ...