calc-size() 是一个 CSS 函数,用于对 auto、min-content 和 fit-content 等固有尺寸关键字执行数学运算。强制性:仅在需要通过计算或约束修改固有尺寸时使用 calc-size();对于简单的基于关键字的动画(例如 0 到 auto),必须使用 interpolate-size: allow-keywords。
实施步骤
- 确定内在基础:确定应以哪个内在关键字(
auto、min-content等)作为计算基础。 - 定义限制条件:在第二个参数中使用
clamp()、min()或max()等 CSS 数学函数,对固有尺寸施加设计限制。 - 强制性:提供后备方案:请务必在使用
calc-size()的属性之前立即声明标准大小调整关键字或长度,以确保布局在不受支持的浏览器中仍能正常运行。 - 应用逻辑属性:默认使用
inline-size或block-size等逻辑属性,以确保计算结果遵循文档的书写模式。 - 可选:渐进增强:将复杂的布局逻辑或动画封装在
@supports (inline-size: calc-size(auto, size + 0px))代码块中,以便仅向支持这些功能的浏览器提供高级功能。
基本语法
/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
/* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
inline-size: min-content;
/* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
inline-size: calc-size(min-content, size + 2rem);
}
有效的基准参数 (<calc-size-basis>)
第一个参数定义计算的“基准”大小。
标准关键字:
auto:元素的默认大小。min-content:元素在不溢出的情况下可以采用的最小尺寸。max-content:元素在一行中容纳所有内容所需的大小。fit-content:相当于clamp(min-content, auto, max-content)。content:仅当在flex-basis属性中使用calc-size()时有效。
特殊参数:
any:在特定固有类型未知或嵌套计算时使用的通用基础。- 嵌套
calc-size():支持多步或条件计算。 <calc-sum>:特定长度、百分比或数学表达式(例如100px或20%)。当使用固定值作为基准时,size关键字仍然可用(但仅在第二个参数中),并表示该基准的解析值。
强制性:size 关键字在第一个参数 (<calc-size-basis>) 本身中无效。它是一个局部变量,仅用于在第二个实参 (<calc-sum>) 中引用基数。
有效计算参数 (<calc-sum>)
第二个参数是数学表达式。
- 它通常使用
size关键字来引用基准的值。 - 虽然
size关键字在技术上是可选的,但省略它意味着计算将解析为固定值,完全忽略基准。 - 可以包含标准数学运算符(
+、-、*、/)。 - 它可以包含 CSS 数学函数,例如
clamp()、min()、max()和round()。 - 强制性:
calc-size()在每次计算中仅允许使用一个固有尺寸值(基准)。您不能在同一calc-size()调用中混合使用内在尺寸关键字。
使用场景
添加向固有尺寸过渡和从固有尺寸过渡的动画效果
默认情况下,浏览器无法在长度(例如 0px)和固有关键字(例如 auto)之间进行插值。将关键字封装在 calc-size() 中可使其成为可插值的值。
选择合适的动画工具
强制:使用
interpolate-size: allow-keywords:适用于在不进行任何数学修改的情况下,在固有尺寸(例如height: 0到height: auto)之间进行简单动画。这是简单关键字插值的必需方法,最好通过:root全局应用。:root { /* Best practice: Enable keyword interpolation globally */ interpolate-size: allow-keywords; } .item { height: 0; transition: height 0.3s ease; } .item.open { /* Simple interpolation from 0 to auto now works without calc-size() */ height: auto; }使用
calc-size():仅当您需要在过渡期间对固有尺寸执行数学计算(例如,添加内边距或限制尺寸)时。
.accordion-content {
display: block;
overflow: hidden;
/* MANDATORY: Fallback value for closed state */
block-size: 0;
transition: block-size 0.3s ease-out;
}
.accordion-content.open {
/* MANDATORY: Fallback value for open state */
block-size: auto;
/*
DO: Use calc-size(auto, ...) to enable animation from 0 to the element's
intrinsic size while doing a calculation (in this case, adding a space of 2rem).
*/
block-size: calc-size(auto, size + 2rem);
}
强制性:无法直接在两个固有尺寸关键字之间进行插值。过渡的一端必须是长度或百分比。
尊重用户的动作偏好设置
对于患有前庭障碍的用户来说,改变大布局区域大小的动画可能会造成特别大的干扰。强制性要求:始终尊重用户的动画偏好设置,使用 prefers-reduced-motion 媒体查询来简化或尽量减少非必要的动画。常见策略包括完全停用动画、缩短动画时长,或将布局偏移替换为细微的不透明度过渡。
.accordion-content {
opacity: 0;
transition: block-size 0.3s ease, opacity 0.3s ease;
}
.accordion-content.open {
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.accordion-content {
/*
EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
Setting the block-size instantly and transitioning opacity
provides a clear state change without large-scale motion.
*/
transition: opacity 1.5s ease;
}
.accordion-content.open {
/* Jump the size instantly */
block-size: auto;
}
}
对固有尺寸应用限制
您可以将 calc-size() 与任何 CSS 数学函数(例如 min()、max()、clamp() 或 round())搭配使用,以确保元素的固有大小保持在设计边界内。
.dynamic-container {
/* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
inline-size: fit-content;
/*
DO: Establish a dynamic size based on content, while:
1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
2. Modifying the intrinsic size with fixed or relative offsets
*/
inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}
重要考虑因素
- 百分比陷阱:
<calc-sum>内的百分比是根据容器的大小(而非size关键字)解析的。例如,calc-size(auto, size + 10%)会将父级宽度的 10% 添加到元素的auto宽度,这可能会导致意外结果或溢出。 - 计算要求:强制性:对于简单动画(例如
0到auto),请使用interpolate-size: allow-keywords,而不是calc-size()。只有在布局需要对固有基数进行动态数学调整时,才应使用calc-size()。 - 性能说明:为
inline-size或block-size等盒模型属性添加动画效果会触发布局重新计算,这可能会产生高昂的开销。主要针对对布局至关重要的元素使用calc-size()动画,因为非布局替代方案不足以满足需求。
后备策略
calc-size() 和 interpolate-size 是渐进增强。在不支持这些属性的浏览器中,这些属性会被忽略,布局仍可正常运行,但针对固有关键字的动画会跳过过渡效果。请务必提供标准关键字或长度作为后备。
.element {
/* Fallback for browsers that don't support calc-size() */
inline-size: fit-content;
/* Modern browsers will override the fallback */
inline-size: calc-size(fit-content, size + 2rem);
}
动画和过渡回退
在不支持 calc-size() 或 interpolate-size 的浏览器中,涉及固有尺寸关键字的过渡将无法插值。
- 优雅降级:默认后备方案是状态之间的“即时跳转”(例如,从
0跳转到auto)。这通常是可以接受的,因为布局仍可正常运行。 - 增强体验:使用
@supports应用复杂的布局逻辑或额外的样式,这些逻辑或样式只有在可以实现流畅的固有动画时才有意义。 - 避免使用基于 JS 的测量:虽然您可以使用 JavaScript 来测量元素并手动为其尺寸添加动画效果,但这通常是不必要的,并且可能会导致布局抖动。对于现代 Web 应用,建议采用原生“即时跳转”作为后备方案。
对于动画,后备体验将是瞬间跳转到最终尺寸。如需在 CSS 或 JavaScript 中检测支持情况,请执行以下操作:
/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
.element {
/* Apply advanced logic only when supported */
}
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
// Apply advanced sizing or animations
}