CSS:calc()数学计算

是什么

calc()CSS 原生支持的数学计算函数,全称是 “calculate”(计算)

它允许你在 CSS 属性值中直接进行加减乘除运算,混合使用不同单位(如 %pxrpxem 等)。

calc()解决了什么问题?

场景:让一个固定宽度的元素水平居中

  • 元素宽:984rpx
  • 父容器宽:100%
  • 想让它绝对定位居中

❌ 错误做法:

left: 50%; /* 元素左边缘在中心 */
/* 结果:元素整体偏右!因为 50% 是从左边开始算的 */

✅正确思路:

把元素向左“拉回”自身宽度的一半
即:left = 50% - (width / 2)

width: 984rpx;
left: calc(50% - 492rpx); /* 984 / 2 = 492 */

✅ 这样,元素的中心点就对齐了父容器的中心!

calc() 语法规则

property: calc(表达式);

运算符 说明 示例
+ 加法 calc(10px + 20px)
- 减法 calc(100% - 20px)
* 乘法 calc(2 * 50px)
/ 除法 calc(100px / 2)
  1. 运算符前后必须有空格
    ✅ 正确:calc(50% - 492rpx)
    ❌ 错误:calc(50%-492rpx)浏览器会忽略整个规则!
  2. 除法的右侧不能是 0,且必须是数值(不能是带单位的量)
    ✅ 正确:calc(100px / 2)
    ❌ 错误:calc(100px / 0)calc(100px / 2px)

使用场景

固定边距的自适应宽度

需求:一个盒子,左右各留 40rpx 边距,中间自适应填满。

效果:无论屏幕多宽,盒子始终距离左右边缘 40rpx。

<template>
  <view class="container">
    <view class="box">自适应宽度</view>
  </view>
</template>

<style scoped>
.container {
  padding: 20rpx;
}

.box {
  /* 宽度 = 100% - 左右边距(40rpx * 2) */
  width: calc(100% - 80rpx);
  height: 100rpx;
  background-color: #4ecdc4;
  border-radius: 16rpx;
}
</style>

绝对定位元素水平居中

需求:一个固定宽度的元素,在页面中水平居中(用 position: absolute)。

效果:红色盒子在灰色区域中水平居中。

<template>
  <view class="page">
    <view class="centered-box">我居中了</view>
  </view>
</template>

<style scoped>
.page {
  position: relative;
  height: 300rpx;
  background-color: #f0f0f0;
}

.centered-box {
  position: absolute;
  width: 200rpx;
  height: 100rpx;
  background-color: #ff6b6b;
  border-radius: 16rpx;
  /* 关键:left = 50% - 自身宽度一半 */
  left: calc(50% - 100rpx); /* 200 / 2 = 100 */
  top: 100rpx;
}
</style>

内容区高度 = 全屏 - 头部高度

需求:页面有固定高度的头部(120rpx),内容区占剩余高度。

效果:绿色内容区自动填满头部下方的所有空间。

<template>
  <view class="page">
    <view class="header">头部(120rpx)</view>
    <view class="content">内容区(自动填满剩余高度)</view>
  </view>
</template>

<style scoped>
.page {
  height: 100vh; /* 全屏高度 */
  display: flex;
  flex-direction: column;
}

.header {
  height: 120rpx;
  background-color: #3498db;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

.content {
  /* 高度 = 全屏 - 头部高度 */
  height: calc(100vh - 120rpx);
  background-color: #2ecc71;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>

输入框左右有图标,中间自适应

需求:左侧图标(60rpx),右侧图标(60rpx),中间输入框填满。

效果:输入框自动适应中间剩余空间,图标固定宽度。

<template>
  <view class="input-wrapper">
    <text class="icon">🔍</text>
    <input class="input" placeholder="请输入..." />
    <text class="icon">✕</text>
  </view>
</template>

<style scoped>
.input-wrapper {
  display: flex;
  align-items: center;
  padding: 20rpx;
  background-color: #fff;
  border: 2rpx solid #ddd;
  border-radius: 20rpx;
}

.icon {
  width: 60rpx;
  text-align: center;
  font-size: 36rpx;
  color: #888;
}

.input {
  /* 宽度 = 100% - 左右图标宽度 */
  width: calc(100% - 120rpx); /* 60 + 60 */
  margin: 0 10rpx;
  padding: 10rpx 0;
  font-size: 28rpx;
}
</style>

两列布局,一列固定,一列自适应

需求:左侧头像(120rpx 宽),右侧信息自适应。

效果:右侧信息区自动填满头像右侧的剩余空间。

<template>
  <view class="user-card">
    <view class="avatar"></view>
    <view class="info">
      <view class="name">张三</view>
      <view class="desc">前端工程师</view>
    </view>
  </view>
</template>

<style scoped>
.user-card {
  display: flex;
  padding: 20rpx;
  background-color: #f8f9fa;
  border-radius: 20rpx;
}

.avatar {
  width: 120rpx;
  height: 120rpx;
  background-color: #ccc;
  border-radius: 50%;
}

.info {
  /* 宽度 = 100% - 头像宽度 - 间距 */
  width: calc(100% - 120rpx - 20rpx);
  margin-left: 20rpx;
}

.name {
  font-size: 32rpx;
  font-weight: bold;
}

.desc {
  font-size: 28rpx;
  color: #666;
  margin-top: 10rpx;
}
</style>

×

喜欢就点赞,疼爱就打赏