这啥?CSS calc-size和interpolate-size,真学不动了

这篇文章发布于 2024年11月14日,星期四,21:54,归类于 CSS相关。 阅读 2234 次, 今日 3 次 4 条评论

 

水果动画封面占位图

就算每周学习一个前端新特性,我发现我都来不及学习。

都没有时间钓鱼了,苦啊。

这不,又出了个啥calc-size()函数和interpolate-size属性。

没关系,我还学得动,快扶我起来。

扶我起来

一、非固定尺寸也能动画

calc-size()函数和interpolate-size属性的设计初衷是一致的,就是可以让width、height等尺寸相关的属性即使值是auto,也能有transition过渡动画效果。

最具代表性的就是height:auto的过渡动画实现。

例如:

<button onClick="this.classList.toggle('active');">点击我</button>
<p>
    <img src="html-book.jpeg" width="256" />
</p>
p {
    height: 0;
    transition: height .25s;
    overflow: hidden;
}
.active + p {
    height: auto;
    height: calc-size(auto, size);
}

此时,在Chrome 129及其以上版本浏览器下,点击按钮,就可以看到图片以切片动画的形式呈现了,如下GIF动图所示:

height:auto动画

眼见为实,您可以狠狠地点击这里:CSS calc-size()实现height:auto动画demo

二、interpolate-size用法更简单

其实,要让height:auto支持transition过渡动画,还有个更简单的方法,就是在祖先容器上设置:

interpolate-size: allow-keywords;

interpolate是插入,篡改的意思,连起来表示尺寸插值变化允许关键字。

例如,我们狠一点,直接在根元素上是设置:

:root {
  interpolate-size: allow-keywords;
}

那么,页面上,所有的元素都能触发height:auto的过渡动画效果,无需专门的calc-size()设置。

换句话说,calc-size()函数是专门单独设置,而interpolate-size是全局批量设置。

元素设置了calc-size()值,浏览器会自动设置其interpolate-size属性的计算值是allow-keywords

interpolate-size语法

语法示意:

interpolate-size: allow-keywords;
interpolate-size: numeric-only;

其中,值numeric-only就是默认的差值计算规则,表示仅数值类型的属性值才运行差值计算。

来看一个使用案例,这次我们使用宽度示意,相关的HTML和CSS代码如下:

<button onClick="this.classList.toggle('active');">点击我</button>
<figure>
    <img src="html-book.jpeg" width="256" />
</figure>
figure {
    width: 320px;
    padding: 1em;
    transition: width .25s;
    interpolate-size: allow-keywords;
    background: deepskyblue;
}
.active + figure {
    width: fit-content;
}

效果参见如下GIF录屏:

宽度fit-content过渡动画

眼见为实,您可以狠狠地点击这里:CSS interpolate-size实现width:fit-content动画demo

三、calc-size的语法

calc-size()函数支持的能力还挺丰富的,使用参考:

/* 单值设置 */
calc-size(auto, size)
calc-size(fit-content, size)

/* 执行计算 */
calc-size(min-content, size + 100px)
calc-size(max-content, size - 80em)
calc-size(fit-content, size / 2)

/* 函数计算 */
calc-size(auto, round(up, size, 50px))

关键字size表示函数第一个关键字值对应的计算尺寸,如果是图片,则表示图片的原始尺寸。

例如,希望点击图片缩略图,图片以动画形式放大到原始尺寸的1/2,那么就不需要JavaScript代码参与了,使用示意:

<img 
  src="1.jpg" 
  onClick="this.classList.toggle('active');" 
/>
img {
    transition: .3s;
    width: 128px;
}
img.active {
    width: calc-size(fit-content, size / 2);
}

MP4录屏效果参见(不动点击播放):

眼见为实,您可以狠狠地点击这里:CSS calc-size()实现图片原始尺寸放大demo

另外,这里出现的round()函数还是挺实用的,参见不久前我撰写的这篇文章:“时隔两年,Chrome也支持round等CSS数学函数了

四、并非适用所有CSS属性

需要注意的是,无论是calc-size()函数还是interpolate-size属性,都只适用于与尺寸相关的些CSS属性。

举个例子,一个block水平元素,默认margin:0,然后设置margin:auto让其居中,希望有动画,那么下面的用法是无效的:

.element {
    margin: calc-size(auto, size);
}

控制台显示不合法,如下截图所示:

margin使用calc-size属性无效

五、温故知新display:none动画

之前transition动画的两个痛点,一个是height:auto,另外一个就是display:none

display:none其实也有专门的新特性解决此痛点,是CSS transition-behavior属性和@starting-style规则。

感兴趣的可以访问这篇文章:“CSS transition-behavior让display none也有动画效果

之前height:auto动画实现

一种是使用足够大的max-height值,这个是最老的方法了。

后来是使用Grid布局中的fr单位特性实现,原理就是0fr→1fr,案例示意:

<button onClick="this.classList.toggle('active');">点击我</button>
<figure>
    <img src="html-book.jpeg" width="256" />
</figure>
figure {
    display: grid;
    grid-template-rows: 0fr;
    transition: .25s;
    overflow: hidden;
}
figure img {
    min-height: 0;
}
.active + figure {
    grid-template-rows: 1fr;
}

GIF效果截图:

height:auto动画

眼见为实,您可以狠狠地点击这里:CSS Grid fr单位实现height:auto动画demo

六、兼容性及碎碎念

calc-size()函数和interpolate-size属性都是从Chrome 129版本开始支持的:

calc-size兼容性截图

不过并不影响我们的使用,毕竟是渐进增强特性。

一看时间,还早,再扯点其他东西吧。

文字版博客现在看得人越来越少了,HTML新书出版之后,算是有了点先功夫,就弄了个抖音账号,名叫“张鑫旭本人”,唉,老人家,后知后觉,没有提前把名称占好位置。

张鑫旭本人

目前每周更新2~3个视频的节奏,全是与前端开发相关的,偶然也会讲下人文,八卦相关的东西。

欢迎关注哈!

另外,用了6年的云数据库到期了,不续了,6年前前端大热,网站流量巅峰,不堪重负,于是将数据库独立出去了,1年千把块钱。

现在的访问量也就巅峰时候的1/10,我一看数据库的资源占用,奶奶个熊,CPU只用了1%~2%,严重浪费。

所以,趁这次到期,又和之前一样,直接在云服务器上使用本地数据库,好家伙,这页面加载速度,明显快多了,秒开,云服务器压力也不大,省钱了,开心。

好,就这么多吧,感谢阅读,欢迎,圣女为你点赞。

圣女

(本篇完)

分享到:


发表评论(目前4 条评论)

  1. 咕咕嘎说道:

    感谢大神的文章 让我一个不会代码的设计也能经过阅读参考勉强写一些东西👍

  2. nord说道:

    文字版可千万别断更呀,老人还是喜欢文字版的😆

  3. Kevin说道:

    是因为用了RSS订阅导致页面PV变少的吗😂

    • 张 鑫旭说道:

      原因之一,主要还是百度搜不到了,好像是做百家号那时候改变策略了,资源往内收,不给外部中小网站了。