CSS calc() 的部分指南

前言:周六加了满满一天的班,感觉最近一个月特别累。这几天工作是无趣的,不想让自己今天全部投入工 作而没有其他产出。正好也看到了一些关于 CSS calc 的介绍,平常就用用,这次就来个全面的梳理吧 🏃🏃🏃。

CSS 具有 calc() 执行基本数学运算的特殊功能,比如:

.main-content {
  height: calc(100vh - 80px);
}

一般除去导航栏高度,让 div 铺满整个屏幕。

calc() value

calc() 可以作为很多 CSS 属性的属性值,比如

.el {
  font-size: calc(3vw + 2px);
  width:     calc(100% - 20px);
  height:    calc(100vh - 20px);
  padding:   calc(1vw + 5px);
}

同时,也是可以作为单独的值,作为 CSS 属性值的一部分,比如:

.el {
  margin: 10px calc(2vw + 5px);
  border-radius: 15px calc(15px / 3) 4px 2px;
  transition: transform calc(1s - 120ms);
}

上面两种场景,用的也比较多,特别是第一种,高度和布局这块使用场景也比较多。不过 calc 还有一个更牛逼的地方,是可以作为 CSS 其他工具函数内部的函数值使用,比如颜色渐变:

.el {
  /* 在50%左右位置增加 20px 的过渡效果 */
  background: #1E88E5 linear-gradient(
    to bottom,
    #1E88E5,
    #1E88E5 calc(50% - 10px),
    #3949AB calc(50% + 10px),
    #3949AB
  );
}

calc for CSS length

calc 一般用来计算数字的,因此并不能作为字符串的计算,比如使用 calc('hac'+'hai'),这种肯定会失效,如果有 stylint,也会报错。

CSS 中有很多描述长度的单位,都可以用在 calc 中:

px % em rem in mm cm pt pc ex ch vh vw vmin vmax

当然,无单位数也可以的,例如 line-height: calc(1.2 * 1.2);,以及 transform: rotate(calc(10deg * 5));

calc 不可用于 @media

做自适应的会经常用到媒体查询,一般都是如下:

@media (max-width: 40rem) {
  /* seize the day */
}

但这里的 40rem,如果换成 calc

@media (min-width: calc(40rem + 1px)) {
  /* 不会起作用 */
}

@media 中加上 calc 逻辑是不可行的,不过还有其他办法可以,这块感兴趣的朋友呢,可以参考一下

混合单位

这个比较神奇,在上面列的一些例子都可以看到,CSS 不同长度的单位在 calc 中,是存在混合并且有效的可能性的,比如 width: calc(100% - 20px);

scss\sass\stylus 等预处理器比较

这个功能确实很神奇,导致我在第一次使用的时候,还以为是 Sass 内置的函数,毕竟 Sass 内置了数学功能,比如:

$padding: 1rem;

.el[data-padding="extra"] {
  padding: $padding + 2rem;  
  margin-bottom: $padding * 2;  
}

数字运算符

基本数字运算符就是加减乘除 +-*,和/,但在 calc 中,规定的使用方式还是有一丁点区别的,这块举几个例子吧。

加号(+)和减号(-)要求两个数字均为长度
.el {
  /* Valid 👍 */
  margin: calc(10px + 10px);

  /* Invalid 👎 */
  margin: calc(10px + 5);
}
除(/)要求第二个数字不能为无单位
.el {
  /* Valid 👍 */
  margin: calc(30px / 3);

  /* Invalid 👎 */
  margin: calc(30px / 10px);

  /* Invalid 👎 (can't divide by 0) */
  margin: calc(30px / 0);
}
乘法(*)要求数字之一为无单位
.el {
  /* Valid 👍 */
  margin: calc(10px * 3);

  /* Valid 👍 */
  margin: calc(3 * 10px);

  /* Invalid 👎 */
  margin: calc(30px * 3px);
}

杠精 - 嵌套用

有的东西一旦觉得好用,就会想尽办法使用,就像印度朋友对牛尿的热爱,不管是祈福还是抵抗疫情。calc 是个好东西,有的开发人员为了方便,甚至会在 calc 中嵌套使用,比如:

.el {
  width: calc(
    calc(100% / 3)
    -
    calc(1rem * 2)
  );
}

实际上这是没有必要的,我个人理解这也是事倍功半。因为本身 calc 内部就是单独支持运算的,上面的代码可以优化为:

.el {
  width: calc(
   (100% / 3)
    -
   (1rem * 2)
  );
}
/* 或者 */
.el {
  /* 在这种情况下,即使没有括号,“操作顺序”也会对我们有帮助。*/
  width: calc(100% / 3 - 1rem * 2);
}

CSS 自定义属性和 calc()🎉

除了具有 calc() 混合单位的惊人功能外,接下来最令人敬畏的 calc() 是将其与自定义属性一起使用。自定义属性可以具有随后在计算中使用的值:

html {
  --spacing: 10px;
}

.module {
  padding: calc(var(--spacing) * 2);
}

浏览器支持

方法虽好,使用之前还是得去确定一下浏览器的支持情况,免得产品用户是 ie6,那岂不是白忙活了

截屏 20200328 下午 11.30.48.png

从 canIuse 来看,浏览器支持基本上是没啥问题,满足现代前端产品的述求,可以大胆使用。


希望文章能掉部分朋友有用~🌪 🌈 ☀️ 🌤 ⛅️,晚安

链接


  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    146 引用 • 399 回帖 • 2 关注
  • calc
    1 引用 • 8 回帖
1 操作
Rabbitzzc 在 2020-03-29 13:34:44 更新了该帖
8 回帖
请输入回帖内容...
  • Rabbitzzc 1 1 评论

    给 D 大提个小建议,希望 Markdown 编辑器的代码部分,能够自动填入上次填充选择的语言类型,一篇博客大多数情况下需要注入的代码语言基本上是不太有差距的,这样也避免了每次都需要重新输入一下注入代码的语言类型trollface

    感谢建议,我代你提交了 issue,如果还有建议可直接在 Vditor 项目上提 🙏
    88250
  • Vanessa

    CSS 没有 // 可以使用 scss

    2 回复
  • Rabbitzzc

    写习惯了,已更改 👌

  • WendyBoys 1 评论

    Veditor 默认编辑模式怎么改 默认是所见即所得 我想编辑器初始化完就是分屏预览 看了文档 没找到设置 求助

    该回帖因偏离主题而被折叠
    1 操作
    Vanessa 在 2020-03-30 09:39:34 折叠了该回帖
    options.mode
    Vanessa
  • 233333

    doge 魔法讲堂

  • Lee981265

    nice

  • Lee981265 1 1 评论

    calc( 100% - 10px ) 注意空格 挤在一起写浏览器无法识别

    对的,要是能够评论置顶就好了 🙃
    Rabbitzzc
  • leaf4291 1 评论

    咋了
    Rabbitzzc
请输入回帖内容 ...