写在前面
本文部分知识需要有一定的 CSS3 基础,如果有疑问,建议随时 Google 或者联系本人~
写这边文章的起因是前段时间做了一个需求,要求改变 Ant Design 的 TreeSelect 组件的选中事件,要求是如果选中的是父节点,那么就是展开当前节点的子节点,但不能 执行选中自己的事件,一开始纠结了很久去使用官方文档的事件去各种骚操作,后来突然想到了可以使用 content 属性加定位给干出来这种效果,先看看代码:
.ant-select-tree-switcher {
position: relative;
}
.ant-select-tree-switcher_open::before, .ant-select-tree-switcher_close::before {
content: '';
position: absolute;
right: -310px;
top: 0;
left: 0;
bottom: 0;
}
写完以后突然想到 content 这个小家伙到底还能做什么,顺道重新了解了一下 content 属性,发现这个小家伙还真的是四两拨千斤,具体如下~
一. 认识
首先来看一下官方对于 content 属性的介绍:
该属性用于定义元素之前或之后放置的生成内容。默认地,这往往是行内内容,不过该内容创建的框类型可以用属性 display 控制。 content 属性与 :before 及 :after 伪元素配合使用,来插入生成内容。
是不是第一眼看过去,会感觉这哥们平平无奇,但是(重点来了),经本工具人验证,这哥们可以在 Chrome 浏览器中应用在任何元素后面,而不是仅仅只应用在伪类元素后面,鉴于公司业务目前还是主营 Chrome 浏览器,所以。。。(真香警告⚠️)
二. 使用
2.1 默认属性(String 类型皆可)
首先来看一眼 Ant Design 关于表单必填项的提示吧,如下图:
是不是出人意料?它的名称前面的竟然不是 Icon,就是这么普普通通的一个,而且名称之后的冒号也是相同的用法,我们在之前的文章分享关于 CSS 变量时,使用过该属性,可以在页面中动态的点击展示我们想要的信息。效果和代码如下图:
CSS 代码如下:
body:active::after {
transform: translate(-50%, -100%);
opacity: 0.5;
transition: 0s;
left: -999px;
}
body::after {
content: 'hi~我是内容';
position:fixed;
z-index: 999;
left: calc(var(--clientx, -999) * 1px);
top: calc(var(--clienty, -999) * 1px);
transform: translate(-50%, calc(-100% - 20px));
opacity: 0;
transition: transform .3s, opacity .5s;
}
JS 代码如下:
document.addEventListener('mousedown', function (event) {
var html = document.documentElement;
// 设置自定义属性值
html.style.setProperty('--clientx', event.clientX);
html.style.setProperty('--clienty', event.clientY);
});
2.2 HTML 自定义属性
.main label::before {
content: attr(number) " : ";
}
.main label{
display: block;
}
<form class="main">
<label class="item" number="1">我是一号</label>
<label class="item" number="2">我是二号</label>
<label class="item" number="3">我是三号</label>
<label class="item" number="4">我是四号</label>
<label class="item" number="5">我是五号</label>
</form>
知识点来了,content 属性可以获取到 HTML 的自定义属性中的数据,这样一来,我们就可以通过 HTML 标签的自定义属性,来动态的修改每个元素的数据,达到我们想要的类似有序列表的效果。类似原理的关于数字顺序的需求、关于表单的内容都可以使用这种方式去做到~
2.3 counter 计数器
首先来了解一下这个新的小伙伴,看一下官方解释和浏览器兼容性:
CSS 函数 counter(),返回一个代表计数器的当前值的字符串。它通常和伪元素搭配使用,但是理论上可以在支持值的任何地方使用。 一个计数器本身没有可见的效果,而是通过
counter()函数(和counters()函数)返回开发人员定义的字符串(或图像) 从而使计数器拥有很棒的作用。
/* 简单使用 */
counter(计数器名称);
/* 更改计数器显示 */
counter(countername, upper-roman)
只看概念,很多人会没有比较好的体感,但是如果你看过刚才链接的文章,就会发现它的强大之处,话不多说,直接上 demo。
<div class="main">
<p>进度1 : </p>
<div class="item" style="--scale: 80;--background: #52c41a"></div>
<p>进度2 : </p>
<div class="item" style="--scale: 60;--background: #1890ff"></div>
<p>进度3 : </p>
<div class="item" style="--scale: 40;--background: #faad14"></div>
<p>进度4 : </p>
<div class="item" style="--scale: 20;--background: #ff4d4f"></div>
</div>
.main {
width: 400px;
border: 1px solid #ccc;
border-radius: 7px;
padding: 8px;
margin: 10px auto;
}
.item {
height: 20px;
width: 300px;
background-color: #eee;
margin-bottom: 10px;
border-radius: 20px;
}
.item::before {
/* 用于将 CSS计数器 重置为制定值 progress代表进度条 */
counter-reset: progress var(--scale);
/*
\00a0 表示
详情请见: https://css-tricks.com/snippets/html/glyphs/
PS:同样是为了右侧距离,设置一下padding-left试一下?
*/
content: counter(progress) '%\00a0';
width: calc(300px * var(--scale) / 100);
color: #fff;
background-color: var(--background);
display: block;
font-size: 12px;
border-radius: 20px;
height: 20px;
line-height: 20px;
text-align: right;
overflow: hidden;
}
当然了,要实现这个需求不仅仅需要 counter 和 content 这兄弟俩,还需要使用到 CSS 变量,墙裂建议去看一下之前的文章,对于计数器会有一个更佳的体感。counter 仅仅使用单一属性就可以做到这种效果,但是这个小伙伴还有个强大的地方在于它不止可以接受一个属性,可以接受多个,继续看下去~
div {
counter-reset: one 1 two 2 three 3;
}
div:before {
content: counter(one) "/" counter(two) "/" counter(three);
}
<div></div>
顾名思义,计数器,所以 counter 方法中接受的参数只能是数字,例如上面的代码,当数字 1 变为字符串"1"时,页面上的效果就会展示为 0/0/0,因为它的默认数据就是 0,同样的,我们一开始做的利用自定义属性做的有序列表,也可以使用该属性做到,代码如下:
.main{
counter-reset: counter;
}
.main .item::before {
counter-increment: counter;
content: counter(counter) " : ";
}
.main .item{
display: block;
}
<form class="main">
<label class="item">我是一号</label>
<label class="item">我是二号</label>
<label class="item">我是三号</label>
<label class="item">我是四号</label>
<label class="item">我是五号</label>
</form>
作为程序猿和游戏宅男,肯定要奔着搞事情的思想继续使劲磨砺 counter 小伙伴,官方介绍里面有这么一句话:
/* 更改计数器显示 */ counter(countername, upper-roman)
后面这个参数我们目前还没有使用道,继续搞起~
这个小伙伴的第二个属性,目前可以支持的包括 disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | none | inherit,我们继续把刚才的有序列表再美化美化,效果如下:
在此仅展示 CSS 代码:
.main{
counter-reset: counter;
}
.main .item::before {
counter-increment: counter;
content: counter(counter, upper-latin) " : ";
}
.main .item{
display: block;
}
再换一个~
.main{
counter-reset: counter;
}
.main .item::before {
counter-increment: counter;
content: counter(counter, georgian) " : ";
}
.main .item{
display: block;
}
emmm,差不多了,不玩了,它毕竟还是个孩子🐶~ 有兴趣的小伙伴可以挨个尝试一下,扩宽自己的知识的广度,万一以后用到了呢?😊
三. 总结
看了这么久,应该对 content 这个小伙伴有一个大致的体感了,其实我们在产品迭代过程中,牵扯到一些常规化的需求时,不妨尝试一下这些比较有趣的操作,可以大大的提升我们做产品迭代的乐趣,鉴于本人目前了解的范围还比较有限,有任何问题或者想法欢迎随时沟通和评论呀~