CSS progress() 函数:使用方法和实际例子
在前端开发中,我们经常需要让页面有更流畅、能响应变化的视觉效果。比如:页面宽度变窄时,背景图片慢慢变淡让文字更容易读;或者卡片随着窗口变大稍微放大,带来更好的交互感受。以前要实现这些效果,通常要用复杂的calc()计算或者JavaScript。现在有了css新增的progress()函数,这些需求可以用更直观、更简单的方式实现。
什么是progress()?
progress()是CSS中的一个新函数,用来计算某个数值在一个范围内的"进度比例"。你可以把它理解成一个内置的"百分比计算器"——它能把任意范围的值,转换成0到1之间的小数,方便后面用来控制动画、透明度、颜色渐变等效果。
语法:
progress(<当前值>, <开始值>, <结束值>)<当前值>:要测量的数值(比如宽度、滚动距离、某个CSS变量等)
<开始值>:范围的起始值
<结束值>:范围的结束值
返回结果永远是0到1之间的小数。计算规则是:
当当前值小于或等于开始值时,返回0
当当前值大于或等于结束值时,返回1
当当前值在两者之间时,返回按比例计算的小数
计算公式是:(当前值 - 开始值) ÷ (结束值 - 开始值)
一个简单的例子
progress(800px, 480px, 1200px)参数说明:
800px:当前窗口宽度(随着用户调整浏览器窗口会实时变化)
480px:样式变化的起点——窗口宽度≤480px时,进度为0
1200px:样式变化的终点——窗口宽度≥1200px时,进度为1
计算步骤:
范围长度 = 1200px - 480px = 720px
当前位置 = 800px - 480px = 320px
进度 = 320 ÷ 720 ≈ 0.44
结果0.44表示当前值已经完成了整个范围的44%。
实际使用例子
1. 背景图片随窗口变窄逐渐变淡
.hero img {
/* 当窗口从1200px缩小到480px时,透明度从1逐渐降到0.4 */
opacity: clamp(0.4, 1 - progress(100vw, 480px, 1200px) * 0.6, 1);
}解释:
窗口宽度≤480px时,progress()返回0,透明度 = 1 - 0×0.6 = 1
窗口宽度≥1200px时,progress()返回1,透明度 = 1 - 1×0.6 = 0.4
在两者之间时,透明度会平滑变化
这里用了clamp()函数,它用来确保一个值在最小值和最大值之间:
第一个参数是最小值
第二个参数是首选值(浏览器尽量用这个)
第三个参数是最大值
clamp(0.4, X, 1)的意思是:把X限制在0.4到1之间。
2. 文字大小随窗口变化
h1 {
/* 窗口宽度在480px到1200px之间时,字体大小从2rem渐变到3rem */
font-size: calc(2rem + progress(100vw, 480px, 1200px) * 1rem);
}3. 卡片阴影效果变化
.card {
/* 窗口越大,阴影越明显 */
box-shadow: 0 calc(2px + progress(100vw, 480px, 1200px) * 6px) 8px rgba(0,0,0,0.1);
}4. 根据滚动位置改变样式
.header {
/* 滚动距离在0到200px之间时,背景透明度从透明到半透明 */
background-color: rgba(255, 255, 255, progress(var(--scroll), 0, 200px));
}更多实用示例
响应式边距调整
.container {
/* 小屏时边距小,大屏时边距大 */
padding: calc(1rem + progress(100vw, 480px, 1200px) * 2rem);
}颜色渐变过渡
.button {
/* 根据窗口宽度从蓝色渐变到紫色 */
--color-progress: progress(100vw, 480px, 1200px);
background-color: color-mix(
in srgb,
blue,
purple calc(var(--color-progress) * 100%)
);
}圆角变化效果
.avatar {
/* 小屏时圆角大,大屏时圆角小 */
border-radius: calc(20px - progress(100vw, 480px, 1200px) * 10px);
}网格列数自适应
.grid {
/* 根据窗口宽度计算最小列宽 */
grid-template-columns: repeat(
auto-fit,
minmax(calc(150px + progress(100vw, 480px, 1200px) * 100px), 1fr)
);
}浏览器兼容性
目前progress()函数在最新版的Chrome浏览器和Safari 26中已经支持。不过Firefox浏览器还不支持这个函数。
如果你的网站需要在Firefox中正常显示,建议准备备用方案:
/* 兼容方案 */
.element {
/* 新浏览器用progress() */
opacity: clamp(0.4, 1 - progress(100vw, 480px, 1200px) * 0.6, 1);
/* 旧浏览器用calc() */
opacity: clamp(0.4, calc(1 - (100vw - 480px) / (1200px - 480px) * 0.6), 1);
}或者用@supports检测浏览器是否支持:
.element {
/* 默认值 */
opacity: 1;
}
@supports (opacity: progress(100vw, 480px, 1200px)) {
.element {
opacity: clamp(0.4, 1 - progress(100vw, 480px, 1200px) * 0.6, 1);
}
}适用场景
下面是一些适合使用progress()的场景:
随窗口变化的视觉效果
背景图片逐渐变淡
文字阴影强度变化
字体间距调整
自适应布局调整
小屏幕时卡片更紧凑
大屏幕时元素间距更大
容器内边距自适应变化
滚动驱动的动画效果
根据滚动位置改变透明度
滚动时调整滤镜强度
滚动时缩放元素大小
基于数据的样式变化
根据评分(0-100)调整颜色
根据音量(0-1)调整大小
根据进度值改变透明度
主题切换过渡
暗色模式和亮色模式平滑切换
颜色混合过渡效果
与传统方法的对比
以前的做法:
/* 用多个媒体查询 */
.element {
opacity: 1;
}
@media (max-width: 480px) {
.element {
opacity: 1;
}
}
@media (min-width: 1200px) {
.element {
opacity: 0.4;
}
}
@media (min-width: 481px) and (max-width: 1199px) {
.element {
/* 需要复杂计算 */
opacity: calc(1 - (100vw - 480px) / (1200px - 480px) * 0.6);
}
}现在的做法:
/* 一行代码搞定 */
.element {
opacity: clamp(0.4, 1 - progress(100vw, 480px, 1200px) * 0.6, 1);
}使用建议
从简单效果开始
先尝试简单的透明度变化或大小调整,熟悉函数用法。结合clamp()使用
用clamp()限制范围,避免数值超出合理范围。测试不同窗口大小
检查在各种窗口尺寸下的显示效果。准备备用方案
为不支持progress()的浏览器提供兼容代码。合理使用CSS变量
把progress()计算结果存到CSS变量里,方便多处使用。
总结
如果你想让页面在不同设备或状态下表现得更"自然",而不是通过生硬的@media断点突然变化,那么progress()函数是一个值得尝试的新工具。它语法清晰、代码简洁、效果平滑。
只要注意浏览器兼容性问题(特别是Firefox),并做好适配方案,就可以在项目中放心使用。progress()让CSS响应式设计变得更加简单和强大。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!