CSS伪元素(content与counter)
前面介绍过CSS里的::before和::after这两个伪元素,以及content相关的用法,这篇将针对content搭配counter(计数器)进行一些有趣的应用,相信熟练之后搞不好很好玩也说不定。
counter基本用法
在CSS里头,counter是个很有意思的功能,最常见得就是如果我们使用list清单,样式选择decimal十进制,当清单变多的时候数字也会跟着增加,底层貌似就是使用counter来做的,也因为counter所产生的数值并不存在于网页的元素内,所以如果我们要在清单元素之外使用,就必须透过::before或::after的content来实现。
counter最的基本用法一定要有一个父元素和子元素(类似list的原理,使用ul包着li),所以长相会类似下面这段html:
<div> <span>钢铁人</span> <span>美国队长</span> <span>雷神索尔</span> </div>
在CSS里头,先针对div父元素使用counter-reset:num;进行计数器归零的设置,里面num是计数器累加数值的变数,接着可以在span::before里面看到counter-increment:num;这一段,这段的作用是把num累加上去,预设数值为加1,接着就透过content显示出来。
计数器预设的显示语法为:counter(计数器名称,list-style-type)
div{ counter-reset:num; } span{ display:block; } span::before{ counter-increment:num; content:counter(num) '. '; }
透过指定一开始counter-reset的起始数值,还有counter-increment累加的间隔数值,就可以做出从某个数值开始或只显示偶数、奇数的效果。
div{ counter-reset:num 3; } span{ display:block; } span::before{ counter-increment:num 2; content:counter(num) '. '; }
如果要更换数字的样式,也可以透过计数器的第二个设定值list-style-type来更改,下面的例子就是将样式更改为georgian。
div{ counter-reset:num; } span{ display:block; } span::before{ counter-increment:num; content:counter(num, georgian) '. '; }
counter进阶用法
除了指定单一个变数外,counter也可以同时指定多个变数,例如下面这段HTML,有三个类别在里面,我分别用span、i和b来分类。
<div> <span>钢铁人</span> <span>美国队长</span> <span>雷神索尔</span> <i>宙斯盾局</i> <i>神鬼局</i> <i>神经局</i> <b>九头蛇</b> <b>九头牛</b> <b>九头猪</b> </div>
CSS一开始counter-reset可以指定多个变数,透过一个空白字元分隔,如果空白字元后面接着数字则是起始值,没有数字预设为0,当这样设定之后,就可以看到不同类别的数字代号就不同。
如果遇到了巢状结构,需要一层层的展开(例如:1 > 1.1 > 1.1.1),采用上述的作法可能就会复杂许多,好在counter还提供了另外一个counters的功能,目的就是来解决巢状结构的麻烦事,在开始前可以先看看透过ul和li组合的清单长相:
<ul> <li>第一层 <ul> <li>第二层 <ul> <li>第三层</li> <li>第三层</li> <li>第三层</li> </ul> </li> <li>第二层</li> <li>第二层</li> </ul> </li> <li>第一层</li> <ul> <li>第二层</li> <li>第二层</li> </ul> </ul>
传统的清单如果将list-style设为decimal,同样可以具备数字接续的功能,但相对来说要做一些特殊变化就办不到了。
li{ list-style:decimal; }
透过content和counters的搭配,我们就可以告别预设值的困扰,甚至可以在不使用清单ul和li的状况下,实现和清单一模一样的效果,举例来说,我们纯粹透过div模拟一个清单的长相(状态仍然必须是有父元素和子元素的概念),里面的样式b就等于是ul,样式a就等于是li:
<div class="a">第一层 <div class="b"> <div class="a">第二层 <div class="b"> <div class="a">第三层</div> <div class="a">第三层</div> <div class="a">第三层</div> </div> </div> <div class="a">第二层</div> <div class="a">第二层</div> </div> </div> <div class="a">第一层 <div class="b"> <div class="a">第二层</div> <div class="a">第二层</div> </div> </div>
由于b的外层没有东西,所以一开始要把body和b都进行counter reset的动作,接着透过counters的使用,让计数器的数值可以一个接着一个放进去,如此一来就可以做到原本清单不容易实现的效果了。
counters使用语法:counters(计数器名称,分隔字,list-style-type)
body, .b{ counter-reset:c; } .a::before{ content:counters(c, ".") ":"; counter-increment:c; } div{ margin-left:10px; }
了解原理之后,透过 ::before 和 ::after 的交互应用,就可以做出颇具特色的列表效果。
body, .b{ counter-reset:c; } .a{ box-sizing:border-box; position:relative; line-height:40px; } .a .a{ padding-left:30px; } .a::after{ content:''; box-sizing:border-box; display:inline-block; position:absolute; z-index:-1; top:0; left:0; width:100%; height:40px; margin-left:30px; box-shadow:inset 0 2px #666; background:#eee; } .a::before{ content:counter(c, upper-roman); counter-increment:c; display:inline-block; width:30px; height:40px; background:#666; color:#fff; text-align:center; margin-right:5px; }