CSS3 的 calc 使用
# 什么是 calc ?
学习 calc
之前, 我们有必要先知道 calc
是什么? 只有知道了他是个什么东东? 在实际运用中更好的使用他.
calc
从字面我们可以把他理解为一个函数 function
. 其实 calc
是英文单词 calculate
(计算) 的缩写, 是 css3
的一个新增的功能, 用来指定元素的长度. 比如说, 你可以使用 calc
给元素的 border
、 margin
、 padding
、 font-size
和 width
等属性设置动态值. 为何说是动态值呢? 因为我们使用的表达式来得到的值. 不过 calc
最大的好处就是用在流体布局上, 可以通过 calc
计算得到元素的宽度.
# calc 能做什么?
calc
能让你给元素的做计算, 你可以给一个 div
元素, 使用百分比、 em
、 px
和 rem
单位值计算出其宽度或者高度, 比如说 width:calc(50% + 2em)
, 这样一来你就不用考虑元素 div
的宽度值到底是多少, 而把这个烦人的任务交由浏览器去计算.
# calc 语法
calc
语法非常简单, 就像我们小时候学加(+)、减(-)、乘(*)、除(/)一样, 使用数学表达式来表示:
.elm {
width: calc(expression);
}
2
3
其中 expression
是一个表达式, 用来计算长度的表达式.
# calc 的运算规则
calc
使用通用的数学运算规则, 但是也提供更智能的功能:
- 使用 "+"、"-"、"*" 和 "/" 四则运算;
- 可以使用百分比、px、em、rem 等单位;
- 可以混合使用各种单位进行计算;
- 表达式中有 "+" 和 "-" 时, 其前后必须要有空格, 如 "widht: calc(12%+5em)" 这种没有空格的写法是错误的;
- 表达式中有 "*" 和 "/" 时, 其前后可以没有空格, 但建议留有空格.
# 浏览器的兼容性
浏览器对 calc
的兼容性还算不错, 在 IE9+
、FF4.0+
、Chrome19+
、Safari6+
都得到较好支持, 同样需要在其前面加上各浏览器厂商的识别符, 不过可惜的是, 移动端的浏览器仅有 "firefox for android 14.0
" 支持, 其他的全军覆没.
大家在实际使用时, 同样需要添加浏览器的前缀
.elm {
/*Firefox*/
-moz-calc(expression);
/*chrome safari*/
-webkit-calc(expression);
/*Standard */
calc();
}
2
3
4
5
6
7
8
# 简单的实例
通过上面的了解, 大家对 calc
不再那么陌生, 但对于实际的运用可能还是不太了解, 那么大家就接下来跟我一起动手, 通过实例来了解他吧. 首先我们来看一个最常用的实例:
<div class="demo">
<div class="box"></div>
</div>
2
3
上面的结构很简单, 就是一个 div.demo
的元素中包含了一个 div.box
的元素, 接下来我们一步一步来看其中的变化.
# 第一步: 添加普通样式:
.demo {
width: 300px;
background: #60f;
}
.box {
width: 100%;
background: #f60;
height: 50px;
}
2
3
4
5
6
7
8
9
10
此时的效果很简单, 就是 div.box
完全遮盖了 div.demo
, 如下图所示:
# 第二步, 在 div.box 上添加 border 和 padding
这一步很棘手的事情来了, 在 div.box
上添加 10px
的内距 padding
, 同时添加 5px
的 border
:
.demo {
width: 300px;
background: #60f;
}
.box {
width: 100%;
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
}
2
3
4
5
6
7
8
9
10
11
12
为了更好的说明问题, 我在 div.demo
上添加了一个 padding:3px 0;
.demo {
width: 300px;
background: #60f;
padding: 3px 0;
}
.box {
width: 100%;
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
}
2
3
4
5
6
7
8
9
10
11
12
13
这个时候大家不知道能否想到问题会发生在哪? 其实很简单, 这个时候 div.box
的宽度大于了其容器 div.demo
的总宽度, 从而撑破容器伸出来了, 如图所示:
# 第三步, calc 的运用
为了解决撑破容器的问题, 以前我们只能去计算 div.box
的宽度, 用容器宽度减去 padding
和 border
的值, 但有时候, 我们苦于不知道元素的总宽度, 比如说是自适应的布局, 只知道一个百分值, 但其他的值又是 px
之类的值, 这就是难点, 死卡住了. 随着 CSS3
的出现, 其中利用 box-sizing
来改变元素的盒模型类型实使实现效果, 但今天我们学习的 calc
方法更是方便.
知道总宽度是 100%
, 在这个基础上减去 boder
的宽度( 5px * 2 = 10px
), 再减去 padding
的宽度( 10px * 2 = 20px
), 即 " 100% - (10px + 5px) * 2
" , 最终得到的值就是 div.box
的 width
值:
.demo {
width: 300px;
background: #60f;
padding: 3px 0;
}
.box {
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
width: 90%; /* 写给不支持 calc 的浏览器 */
width: -moz-calc(100% - (10px + 5px) * 2);
width: -webkit-calc(100% - (10px + 5px) * 2);
width: calc(100% - (10px + 5px) * 2);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这样一来, 通过 calc
计算后, div.box
不再会超出其容器 div.demo
的宽度, 如图所示:
# calc 在 less 中的问题
在 less
中 calc(100% - 4rem)
等带单位混合运算会被 less
解析忽略单位, 全部按照数值计算, 此例中的计算被 less
编译成 calc(96%)
.
有三种解决方法如下:
- width: e("calc(100% - 4rem)");
- width: calc(~"100% - 4rem");
- width: ~"calc(100% - 4rem)";
如果有变量, 则需要使用 {}
括起来
div {
@diff : 30px;
width : calc(~"100% - @{diff}");
}
2
3
4
# calc 在 scss 中的问题
要想在 sass
的 calc
中使用变量, 必须对这个变量使用 sass
的插值方法 ( #{$variable}
).
例如:
.app-inner {
display: flex;
height: calc(100% - #{$topbar-height});
}
2
3
4
# 参考资料
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05