2026-08-28 18:14:29
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12309
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
Chrome 150+之后,可以通过开启#canvas-draw-element特性体验HTML-in-Canvas的神奇效果。
Chrome地址栏输入下面代码可开启:
chrome://flags/#canvas-draw-element

通常Web新特性都都要等浏览器正式支持才介绍。
但是这次的这个特性,实在是等不及了。
在过去,Canvas里面实现元素动效是麻烦的,啰嗦的,往往需要借助第三方的组件。
而CSS实现动画动效非常方便。
现在,有了HTML-in-Canvas,所有的Web动效,包括SVG动效,都可以无缝接入到Canvas中,Canvas的应用能力直接飙升。
比方说HTML原生的<dialog>弹框使用非常方便,于是,过去,WebGL/Canvas 游戏中的弹窗和提示面板就可以直接使用HTML <dialog>元素,而无需像以前一样重写一套游戏 UI 交互:
又比如HTML转图片这个功能。
之前我们大多使用 html2canvas 这个项目,简单点的会借助SVG <forginObject>元素实现(详见“SVG foreignObject简介与截图等应用”此文)。
但是html2canvas还有不支持CSS锥形渐变,一些CSS混合模式效果不支持的问题。
现在又了HTML-in-Canvas,等于原生有了HTML转图片的能力,既全面,又高性能,html2canvas直接可以说拜拜了。
将HTML绘制在Canvas上的代码非常简单,几行代码的事情。
最核心的一行代码就是:
canvas.getContext('2d').drawElementImage(htmlElement, 0, 0);
就可以了。
Chrome开发者社区提供了很多HTML-in-Canvas的案例:https://chrome.dev/html-in-canvas/

可以看到,无论是Video视频、Form表单还是iframe内嵌框架,都可以绘制在Canvas画布上。
而且目前主流的前端3D开发框架,如There.js、Pixi.js都已经加入了对HTML-in-Canvas的支持。
所谓实践出真知,看别人写的Demo,不如自己写个Demo。
脑筋一转,不妨试试看能不能把LuLu UI的表单验证直接搬到Canvas画布上。
您可以狠狠地点击这里:HTML in Canvas 绘制LuLu UI表单组件演示页面
可以看到,表单不仅渲染了,特么的自定义的JS验证UI居然也一起带到Canvas里面去了。
真是牛了个大发了!

相关的代码如下所示:
<canvas id="canvas" style="width: 100%;" layoutsubtree>
<form id="validateForm" is-validate>
...略...
</form>
</canvas>
<script>
const pixelRatio = window.devicePixelRatio || 1;
const canvas = document.getElementById('canvas');
const validateForm = document.getElementById('validateForm');
canvas.style.width = validateForm.offsetWidth + 'px';
canvas.style.height = validateForm.offsetHeight + 'px';
canvas.width = canvas.clientWidth * pixelRatio;
canvas.height = canvas.clientHeight * pixelRatio;
const ctx = canvas.getContext('2d');
canvas.onpaint = () => {
ctx.reset();
ctx.drawElementImage(validateForm, 0, 0);
};
</script>
JS主要做两件事情,其一,设置合适的尺寸;其二,渲染。
然后就没有然后了,就这么Easy!

– <canvas>元素上设置的layoutsubtree属性是必须的,这个千万不能删除,否则是没有实时渲染效果的。
– 我看到不少案例,包括官方案例,都在表单元素上设置了drawable属性,但是根据自己的实践,此属性不设置似乎不影响效果。但是暂时又没有改属性相关的资料,所以,其最终作用,暂时我也不清楚。
AI编程时代,技术细节没必要深究,加上本身目前兼容性还不太好,我觉得了解这么多就好了。
静待浏览器大规模支持吧!
最后,想问下大家,目前还有哪些前端周刊还在更新的吗❓
发现AI编码来了之后,很多都停更了,难道前端这个行业这是自此不再上进了吗?
🤔
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12309
(本篇完)
2026-08-21 18:02:33
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12348
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
我博客的每篇文章的标题的font-size都是动态的。
比方说“前端快讯:setHTML()和Element.startViewTransition已支持”这篇文章,可以看到字号明显小(需要PC端查看),如下截图所示:

但若是标题文字内容少的文章,那么标题尺寸就会很大!
例如“CSS新单位dvh、lvmin、vi、cqb等初解”这篇文章。

为何会有这种区别?
因为我不希望标题换行。
标题字号比较大,一旦换行,排版就很丑陋。
于是,我在PHP输出标题的时候,动态计算了字符数,然后进行了动态设置:
<h2 class="single-h" style="--length:30.533333333333"> 前端快讯:setHTML()和Element.startViewTransition已支持 </h2>
.single-h {
font-size: clamp(1.25rem, calc(100cqw / var(--length, 20)), 2.4rem);
}

虽然说面前实现了预期的排版效果,但是并不完美。
因为每个英文字符占据的宽度是不一样的,标题使用的并不是等宽字体,导致标题文字并不能充分利用容器宽度。
此需求,一直是我心中的一个刺,扎了自己快10年。
结果,哈哈哈,结果,现在居然有原生了CSS属性可以解决此问题了,哈哈哈!

如果希望一段长度不固定,但是范围可控的文字,永远一行显示,同时尽可能填满整行,很简单,两行CSS代码的事情,先设置一个足够小的font-size尺寸。
h2 {
font-size: 12px;
text-fit: grow;
}
此时,标题正好占满一行容器的宽度,绝赞!

语法如下,支持两种类型的关键字值:
text-fit: <fit-type> <fit-target>
其中:
<fit-type>(缩放类型):
none:不进行自动适配。grow:放大文本以填满较短的行或空间。shrink:缩小过长的文本防止溢出。<fit-target>(适配目标):
per-line:逐行单独计算,让每行各自填满容器。per-line-all:所有行共同参与、强制填满。consistent:整体按统一的缩放比例调整,保持相对一致的字体大小。<fit-type>类型是很好理解的,毕竟大家都是学过Flex布局的,对flex-grow和flex-shrink属性肯定有所了解。
比较有挑战的是搞懂<fit-target>类型各个值的区别。
一图胜千言。
如果text-fit的属性值是grow per-line,那么,除了最后一行,前面没一行各自填满容器,如下截图所示:

如果是text-fit: grow per-line-all,那么最后一行文案,也会放大到充分利用容器宽度,如下示意图:

如果是text-fit: grow consistent,为了确保每一行的字号大小都一样,整个字号的变化其实并不是很明显,不知道下面的对比图大家能否看出区别。

估计很难看出来,这样吧,直接实操,我直接把Demo嵌入到了博客页面(RSS阅读器会看不到效果),如果您的浏览器版本足够,可以通过选择下面的下拉框,切身感受text-fit的渲染效果。
缩放类型:
缩放目标:
虽然近些年CSS更新了很多文本相关的CSS新特性,但让我眼前一亮的,只有这个 text-fit 属性,因为其实现的排版效果具有JS不可替代性。
也就是无法使用JavaScript代码轻松模拟text-fit 属性所能实现的效果。
可惜啊可惜,特么的来的太晚了,目前仅 Chrome 150版本发布,😭😭😭😭

再加上现在大家都氛围编程了,哪怕特性再逆天,也无法在社区激起一丝波澜。
捶足顿胸,你怎么不早来10年了,哪怕5年也好啊!
罢了罢了,自己先玩玩吧,我先把自己博客改造下。
大家有兴趣了,不妨打开控制台,看看我的文章标题是如何设置的。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12348
(本篇完)
2026-08-14 19:20:25
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12345
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
之前大家数组求和,肯定多半都是使用的数组的reduce方法.
例如:
const sum = [1, 2, 3, 4, 5, 6].reduce((a, b) => a + b, 0); // 结果 sum: 21
如下截图所示:
![]()
在大多数时候,上面的求和计算是没问题的。
但是,如果计算的数值超大,超过了JS的整数范围;或者是小数,就可能出问题。
比方说:
const arr = [0.1, 0.2, 0.3]; // reduce求和 const sum = arr.reduce((prev, curr) => prev + curr, 0); console.log(sum); // 预期:0.6 // 实际输出:0.6000000000000001
const values = [1e20, 0.1, -1e20];
const sum = values.reduce((a, b) => a + b, 0);
console.log("sum", sum);
// 预期:sum 0.1
// 实际:sum 0
这怎么弄?
在过去,开发人员会把数组每一项都乘以100,1000这种,然后再计算,例如:
const sum = [0.1, 0.2, 0.3].reduce((prev, curr) => prev + curr * 100, 0) / 100; console.log(sum); // 预期:0.6 // 实际输出:0.6
或者使用Number.toPrecision()方法对输出值进行精度格式化处理。
例如:
const moneyList = [0.1, 0.2, 0.7, 0.3]; const total = moneyList.reduce((s, v) => s + v, 0); console.log(total); // 预期:1.3 // 实际:1.2999999999999998 console.log(Number(total.toPrecision(16))); // 预期:1.3 // 实际:1.3
然而,上面这些方法都不是完全之策,例如 toPrecision() 方法在下面这个案例中就是无效的:
[1e20, 0.1, -1e20].reduce((s, v) => s + v, 0).toPrecision(16) // 结果还是0.000000000000000 ❌
那怎么办呢?
有没有什么一了百了的方法呢?
有!
那就是Math对象新增的sumPrecise()方法。
一键求和,同时保证精度。
从今往后,数组求和,再也无需使用reduce()方法了,直接Math.sumPrecise()方法一把梭。
使用非常简单,例如:
const sum = Math.sumPrecise([1, 2, 3, 4, 5, 6]); // 结果 sum: 21
同时,再也没有小数计算精度不准的问题了。
const sum = Math.sumPrecise([0.1, 0.2, 0.3]); // 结果 sum: 0.6
超大的整数计算也不会有问题了!
const values = [1e20, 0.1, -1e20];
const sum = Math.sumPrecise(values);
console.log("sum", sum);
// sumTwo 0.1

各大浏览器对Math.sumPrecise()方法的支持非常积极,目前领先的几个版本都已经支持。

对于不兼容的浏览器,可以引入Polyfill代码,参考示意:
if (typeof Math.sumPrecise !== 'function') {
Object.defineProperty(Math, 'sumPrecise', {
value: function sumPrecise(items) {
// 参数校验
if (items == null) {
throw new TypeError('Math.sumPrecise requires an iterable argument.');
}
if (typeof items[Symbol.iterator] !== 'function') {
throw new TypeError('Math.sumPrecise: argument is not iterable.');
}
var sum = 0;
var compensation = 0; // Neumaier 补偿值
var count = 0;
var hasNegZero = false;
var hasNonZero = false;
for (var value of items) {
var num = Number(value);
// 任意元素为 NaN,直接返回 NaN
if (Number.isNaN(num)) {
return NaN;
}
// 任意元素为 ±Infinity,处理无穷大相消问题
if (!isFinite(num)) {
if (sum === Infinity && num === -Infinity) return NaN;
if (sum === -Infinity && num === Infinity) return NaN;
sum = num;
hasNonZero = true;
count++;
continue;
}
// 记录 -0
if (num === 0) {
if (!isFinite(sum) || hasNonZero) {
// 有实际数值时 -0 不影响结果
} else if (Object.is(num, -0)) {
hasNegZero = true;
}
count++;
continue;
}
hasNonZero = true;
// Neumaier 补偿求和核心
var t = sum + num;
if (Math.abs(sum) >= Math.abs(num)) {
compensation += (sum - t) + num;
} else {
compensation += (num - t) + sum;
}
sum = t;
count++;
if (count > 2 ** 53) {
throw new RangeError('Math.sumPrecise: iterable is too large.');
}
}
// 全是零(含 -0)的情况
if (!hasNonZero) {
return hasNegZero ? -0 : 0;
}
// 有无穷大时,补偿值无意义,直接返回
if (!isFinite(sum)) {
return sum;
}
return sum + compensation;
},
writable: true,
configurable: true,
});
}
边界测试用例:
// 精度问题
Math.sumPrecise([0.1, 0.2, 0.3]) // 0.6
Math.sumPrecise([0.1, 0.1, 0.1, 0.1,
0.1, 0.1, 0.1, 0.1,
0.1, 0.1]) // 1
// 特殊值
Math.sumPrecise([]) // 0
Math.sumPrecise([-0]) // -0
Math.sumPrecise([-0, -0]) // -0
Math.sumPrecise([-0, 0]) // 0(正零优先)
Math.sumPrecise([Infinity, -Infinity]) // NaN
Math.sumPrecise([NaN, 1]) // NaN
Math.sumPrecise([Infinity, 1, 2]) // Infinity
// 非数组可迭代
Math.sumPrecise(new Set([1, 2, 3])) // 6
Math.sumPrecise((function*() {
yield 0.1; yield 0.2; yield 0.3;
})()) // 0.6
补充:与原生规范的差异
原生 Math.sumPrecise(TC39 提案)要求实现完全精确的浮点归约,理论上可以超越 Neumaier 的精度上限(如使用任意精度中间表示)。此 polyfill 在绝大多数实际场景下足够可靠,但对于极端的大数组或数值范围极端悬殊的情况,结果可能与原生实现存在最后一位的差异。
——
好了,就说这么多吧。
大家周末愉快。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12345
(本篇完)
2026-08-06 20:24:54
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12341
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
在过去,渐变边框的主要实现方法,一是嵌套或伪元素模拟嵌套,二是使用border-image属性,相关实现在“被低估的border-image属性”一文中有介绍。
但是border-image属性实现渐变边框有个知名的弱点,那就是不支持圆角!

如果支持圆角,哪怕border-image属性的语法再难以理解,也还是与应用场景的。
本以为这件事情就到此为止了,没想到峰回路转,background-clip属性升级了,居然可以用来实现边框背景效果了,那自然将边框背景设置成渐变不再话下,需要用到全新的属性值 border-area.
例如:
<style>
canvas {
border: 1em solid #0000;
background: linear-gradient(deepskyblue, deeppink);
background-origin: border-box;
background-clip: border-area;
border-radius: 20px;
}
</style>
<canvas></canvas>
就可以得到如下图所示的圆角渐变边框效果了:

效果很赞!
这里有一些细节需要说明。
当值border-area值合写的时候,background-origin属性是可以省略的,也就是:
canvas {
border: 1em solid #0000;
background: linear-gradient(deepskyblue, deeppink) border-area;
border-radius: 20px;
}
但是如果分开书写,就必须设置background-origin:border-box,否则按照默认的padding-box渲染,渐变边框的效果会比较奇怪,会像下面这样。

目前Chrome和Safari都已经支持边框背景图了。

上上个月介绍了全新的CSS border-shape属性,可以轻松实现不规则边框效果,于是可以强强联合,实现不规则图形的特殊边框效果。
例如:
<style>
.star {
width: 150px;
aspect-ratio: 1;
border: 10px dotted #0000;
border-shape: polygon(
50% 5%,
61.8% 34.5%,
95% 34.5%,
68.9% 57.3%,
79.4% 90.45%,
50% 69.1%,
20.6% 90.45%,
31.1% 57.3%,
5% 34.5%,
38.2% 34.5%
);
box-shadow: 2px 2px 4px #0008;
background: conic-gradient(from -36deg,
deepskyblue 72deg,
deeppink 0 144deg,
rebeccapurple 0 216deg,
orange 0 288deg,
green 0
) border-area;
}
</style>
<canvas class="star"></canvas>
此时,就可以得到如下图所示的五角色值都不一样的图像效果了:

除了边框支持背景,文本也支持背景了。
实际上,在Chrome浏览器诞生之初,其就支持background-clip:text了,不过那时候还是私有特性,非Web标准。
现在迎来了好消息,自Chrome 120之后,background-clip:text无需私有前缀了,已经晋升为CSS标准属性了。

于是乎,我们就可以将边框背景和文字背景结合起来使用,实现更加炫酷的按钮效果。
例如:
<style>
.button {
font-size: 14px;
padding: 6px 12px;
border: 1px solid #0000;
border-radius: 4px;
color: transparent;
background: linear-gradient(deepskyblue, deeppink) border-area text,
linear-gradient(#fff, #fe000005);
&:active {
filter: brightness(0.95);
}
}
</style>
<button class="button">我是按钮</button>
实时渲染效果如下(需要Chrome 150+):

没啥好说的,是个相当实用的特性,要是10年前出现,肯定会有很多讨论,朋友圈也可以看到相关文章的转发。
现在么,就像是路边的石头,无人问津。
最后,炫一下周末的渔获吧。
周六老鬼垂钓农家乐,特价108元8小时,钓了32斤;周日天天渔场,188元6小时,钓了七八十斤,两个鱼护。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12341
(本篇完)
2026-08-03 21:20:14
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12316
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
间隙装饰线其实由来已久,在大多数前端从业人员还未入行的时候就已经支持了,大家如果查看 column-rule 属性的兼容性,会发现极佳。

但是,请注意,column-rule 属性生效是有前提的,那就是只能在Columns布局中有效。
而Columns布局我已经快10年没有在实际项目中使用了。
同时,之前的column-rule 属性所设置的装饰线某种程度上和border属性类似,不能设置缩进,不支持多属性,算不得强大。
所以,column-rule 属性可谓名存实亡。
只有抱紧Flex布局和Grid布局的大腿,column-rule 属性才可以真正迎来春天。
等啊等,等啊等,在2026年的某天,终于,全新的装饰线效果可以在Flex/Grid布局中生效了。
比方说这个演示页面:使用 Gap 装饰实现分屏布局demo
核心CSS代码:
.flex-split {
gap: 1px;
column-rule-width: 2px;
column-rule-style: dashed, solid;
column-rule-color: #d4d0c8;
row-rule-width: 2px;
row-rule-style: dashed, solid;
row-rule-color: #d4d0c8;
}
@media (width
于是,在宽屏下,垂直装饰线效果生效:

手机设备下,则是水平方向的装饰线效果:

比之前使用伪元素,或者插入分隔线元素实现简单多了。
除了基本的分隔线装饰效果,还顺便带来了众多其他强大的特性,例如支持多属性值、交点处如何中断、间距边缘距离控制、repeat()函数语法、动画支持等。
我们一个一个来看下。
二、多属性值和 repeat() 语法
如今,无论是column-rule属性,row-rule属性,亦或是他们的子属性,都支持同时设置多个值,分别表示从开始到结束各自的分隔线样式效果。
且看一个极为简单的案例,HTML和CSS代码如下:
<ul>
<li>《CSS世界》</li>
<li>《CSS选择器世界》</li>
<li>《CSS新世界》</li>
<li>《HTML并不简单》</li>
</ul>
ul {
display: flex;
flex-direction: column;
gap: .5em;
row-rule: 2px dashed, dotted;
row-rule-color: red, blue, green;
}
此时,可见如下图所示的分隔线效果:

我们来看下属性值是如何生效的。
先看row-rule属性。
列表共有四项,所有会有3道分隔线。
-
2px dashed显然对应第一条线;
-
dotted则对应第二条,然后这里的宽度规则和border属性一致,默认都是medium尺寸,也就是3px,因此,这里实际渲染等同于 3px dotter;
-
row-rule/column-rule的多值属性走的是平铺规则。也就是:
- 如果仅一个值,那所有的gap线都使用该值;
- 如果是2个值,则两两循环匹配;
- 更多数量的值一样不断循环平铺渲染。
所以,这里,第三条线的样式也是2px dashed。
再看row-rule-color属性,这个很好理解,三条线分别三个颜色,一次是红蓝绿。
那么问题来了,如果我设置4个颜色值,会怎么样呢?
答案是:不会怎么样,超出数量的属性值会被忽略。
repeat()函数
如果分隔线的数量很多,我们一个一个值去设置,会累死人的,代码也啰嗦,此时可以使用repeat()函数简化我们的属性设置。
比方说下面这个案例:row-rule应用repeat()函数demo
核心CSS代码参见下方:
.flex-settings {
row-gap: 1px;
row-rule: 1px solid #243352;
row-rule-width: repeat(2, 1px), 4px;
rule-inset-start: 16px;
}
可得到如下图所示的效果,可以看到,风格线的宽度有着 1px 1px 4px 不断循环渲染的效果。

三、rule-break与交叉中断控制
在一个二维布局中,例如Grid布局,或者设置了flex-wrap:wrap出现换行的Flex布局,同时出现纵向分隔线和横向分隔线是再正常不过的事情。
于是就会出现纵线和横线互相交叉相遇的场景。
默认情况下,两线是相交的,但很多时候,纵横相交的效果并不好快,最好希望互相保留安全距离。
则可以使用CSS rule-break属性,设置rule-break:intersection声明就好了。
请看案例:
<section>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
</section>
section {
display: grid;
width: 300px;
grid: 1fr 1fr / 1fr 1fr 1fr;
gap: 1rem;
canvas {
aspect-ratio: 1;
background: deepskyblue;
width: 100%;
}
column-rule: solid red;
row-rule: solid green;
/* rule-break: intersection */
}
此时可以看到水平方向和垂直方向的分隔线相交了。

此时,我们给section元素设置rule-break:intersection,原本交叉的地方互相留白了,如下截图所示:

四、分隔线的扩展与收缩
column-rule-inset 和 row-rule-inset 属性用于控制装饰在间距内的扩展距离。
如果无需区分水平和垂直距离,或者水平和垂直距离一致,也可以直接使用 rule-inset 属性。
默认情况下,rule-inset 属性设置的缩进距离是对称的,如果开发者希望变化的距离是不对称的,那么可以使用以下两个CSS属性。
一例胜千言,还是上面的案例,我们分别设置rule-inset-cap和rule-inset-junction的值,来看看最终的渲染效果。
关键CSS代码如下:
section {
column-rule: solid red;
row-rule: solid green;
rule-break: intersection;
rule-inset-cap: 5px;
rule-inset-junction: 20px;
}
可以看到,交叉点位置的缩进极大,而四边的端点缩进为5px,明显小一圈,即所谓的不对称缩进。

无论是rule-inset-cap还是rule-inset-junction属性都支持负值,此时装饰线就不是缩进,而是扩张效果。
另外,如果只是希望调整某一个方向的装饰线的缩放效果,可以加上 column- 或者 row- 前缀,例如 column-rule-inset-cap 和 column-rule-inset-junction 属性。
还是上面的案例,区别在于Grid布局的子元素只有4项,此时,间隙装饰线的效果就会让人感到困惑。
明明没有元素项,结果却凭空出现了分隔装饰线。

此时就轮到 column-rule-visibility-items 和 row-rule-visibility-items 属性出马了。
如果无需区分方向,则可以使用合写属性 rule-visibility-items,其语法如下:
normal(默认):取决于容器类型。根据我的测试,大多数场景下效果和 all 一致。all:规则显示在每个间距中,即使是没有元素的间距也是如此。around:只要存有一个或多个相邻项,间隙线就会显示。between:间隙线仅会出现在两个相邻项之间。下图示意了 around 和 between 这两个属性值的区别。

相信还是很好理解的。
间隙分隔线的宽度、颜色和交叉缩进都是可添加动画效果的,具体不展示,这个懂的都懂,设置transition过渡,自然可以看到效果。
下面说下兼容性,Gap装饰是相当新的一个特性,目前只有Chrome 149+ 浏览器才支持,如下截图所示:

唉,东西虽好,但现在还没命享用啊,等过几年兼容性跟上了,前端圈子还不知道变成什么样子呢!
好了,就说这么多吧。
参考文章:

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12316
(本篇完)