惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
宝玉的分享
宝玉的分享
G
Google Developers Blog
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
V
Visual Studio Blog
博客园 - Franky
S
SegmentFault 最新的问题
Jina AI
Jina AI
爱范儿
爱范儿
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
C
Check Point Blog
月光博客
月光博客
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
Martin Fowler
Martin Fowler

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
Polyfill吊炸天的CSS attr()新语法 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2020-10-10 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9535
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

poly小狗 attr()函数 CSS

更新于2025年5月27日

现在Chrome浏览器已经原生支持attr()函数了,详见此文:“震惊,有生之年居然看到CSS attr()全属性支持

一、CSS attr()指定值类型的新语法简介

传统的attr()语法只能让HTML属性作为字符串使用,且只能使用在伪元素中,例如:

<span data-title="提示">按钮</span>
span:hover::after {
    content: attr(data-title);
}

但是全新的attr()语法那可就完全不得了了,可以让HTML属性值转换成任意的CSS数据类型。

例如如下所示的HTML和CSS语句:

<button bgcolor="skyblue" radius="4">按钮</button>
<button bgcolor="#00000040" radius="1rem">按钮</button>
<button bgcolor="red" radius="50%">按钮</button>
<button bgcolor="orange" radius="100% / 50%" title="by zhangxinxu(.com)">按钮</button>
button {
    background-color: attr(bgcolor color);
    border-radius: attr(radius px, 4px);
}

也就是几个按钮的样式使用了新的attr()语法进行设置,平常的按钮颜色、圆角都是在CSS中设定好的,这个例子中则不一样,颜色和圆角全部都是外部的HTML属性控制的。

理论上,上面的代码会有如下图所示的效果。

attr()新语法下的按钮理论效果

可以看出,如果浏览器支持了attr()函数的值类型新语法,那么我们日常的组件开发就会迎来巨大的颠覆,许多组件的接口可以直接交给CSS完成,以及我们的开发会更灵活,可以节省大量的CSS代码和书写CSS的时间,例如:

[ml] { margin-left: attr(ml px, 0); }
[mt] { margin-top: attr(ml px, 0); }
[mr] { margin-right: attr(mr px, 0); }
[mb] { margin-bottom: attr(mb px, 0); }
[pl] { padding-left: attr(pl px, 0); }
[pt] { padding-top: attr(pt px, 0); }
[pr] { padding-right: attr(pr px, 0); }
[pb] { padding-bottom: attr(pb px, 0); }

那么元素的marginpadding设置就不需要专门写在CSS样式中,直接在HTML中设置即可,支持任意的marginpadding大小,例如:

<div mt="10">上间距10px</div>

喔噢,看上去很厉害哦,HTML和CSS会一下子变得非常灵活与高效。

只可惜,attr()函数的新语法目前没有任何浏览器支持,而且在我看来很长一段时间浏览器都不会支持,安全、性能等方面的影响太深远了。

attr()新语法兼容性

不死心的我就琢磨着有没有什么办法让浏览器可以支持CSS attr()函数的这个新语法呢?

然后想到了可以借助CSS变量作为信使实现Polyfill实现。

二、Polyfill attr()新语法

CSS变量有一个特性,那就是CSS自定义属性值支持各种表达式和函数值,哪怕这个表达式是不知所云的东西。

例如随便自定义一个名叫keyword()的函数,然后使用如下所示的CSS调用:

body {
    --keyword: keyword(red, 50%); /* 合法 */
    color: var(--keyword);
}

结果浏览器认为语法是合法的(比方说下图语句没有出现删除线,说明语句是合法的):

CSS变量都是合法的

//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9535(作者张鑫旭)

于是我们就可以利用CSS变量的这个特性Polyfill attr()函数,原理如下。

实现原理

  1. CSS自定义属性作为信使传递attr()函数,保证语法的合法性,例如:
    button {
        --attr-bg: attr(bgcolor color);
        background-color: var(--attr-bg);
    }
  2. 获取⻚⾯所有的包含attr()函数的⾃定义属性;
  3. 遍历并观察所有DOM,如果设置了对应的⾃定义属性,将attr()语法转换成浏览器识别的常规自定义属性语法。

基于上述原理,我写了个JavaScript脚本,大家只需要在页面中引入下面这段HTML代码,就可以畅快自如地使用attr()函数的新语法了。

如何使用

页面头部引入下面下面这个JS文件。

<script src="./css-attr.js"></script>

css-attr.js这个JS文件下载可以访问这里:css-attr.js

然后正常使用CSS变量来实现attr()效果即可,例如——

Polyfill测试

假设已经引入了css-attr.js,然后页面中有如下所示的HTML和CSS代码:

<button bgcolor="skyblue" radius="4">按钮</button>
<button bgcolor="#00000040" radius="1rem">按钮</button>
<button bgcolor="red" radius="50%">按钮</button>
<button bgcolor="orange" radius="100% / 50%">按钮</button>
button {
    border: 0;
    padding: .5em 1em;
}
button {
    --attr-bg: attr(bgcolor color);
    background-color: var(--attr-bg);
    --attr-radius: attr(radius px, 4px);
    border-radius: var(--attr-radius);
}

结果就有如下图所示的效果,按钮表现出了符合预期的效果。

attr()函数Polyfill后的生效示意

同时,如果我们手动修改按钮元素的bgcolorradius属性值,按钮的样式也会同步变化,眼见为实,您可以狠狠地点击这里:attr() polyfill后的按钮demo

实际开发中,按钮元素往往需要一个默认的主样式,此时可以通过属性选择器进行区分,例如:

button {
    color: #fff;
    background-color: deepskyblue;
}
button[bgcolor] {
    --attr-bg: attr(bgcolor color);
    background-color: var(--attr-bg);
}
button[radius] {
    --attr-radius: attr(radius px, 4px);
    border-radius: var(--attr-radius);
}

这样自定义的HTML属性无论设置还是不设置都不会影响按钮的正常显示了。

其他

然后这里还有个测试页面,风格粗犷的那种,您可以狠狠地点击这里:CSS attr() polyfill测试demo

点击按钮会修改HTML属性,大家可以看到样式同步变化了,如下图所示:

按钮颜色变化

补充于2020-12-01

相关JavaScript代码已经在gitee上开源了,地址是:https://gitee.com/zhangxinxu/css-attr-polyfill

也欢迎大家关注我的gitee账号。

三、结束语

CSS var()函数的这种任意表达式特性还适用于CSS自定义语法支持的实现上,关于这个,我会下一篇文章专门介绍,敬请期待。

以上就是自己研究出来的一点小东西,旨在抛砖引玉,欢迎交流!

另外,Polyfill实现的attr()语法比原生的语法要更强大,因此支持复合的HTML属性值,例如:

<div m="10px 20px 30px 40px">上间距10px</div>
[m] {
    --m: attr(m);
    margin: var(--m);
}

可以同时指定多个分享的margin属性。

然后兼容性这块,凡是支持CSS变量的浏览器都支持这里的attr()新语法。

好,就说这么多,

如果你觉得本文的内容还算有趣,欢迎分享。

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9535

(本篇完)