CSS counter计数器(content目录序号自动递增)详解
一、CSS計(jì)數(shù)器三角關(guān)系
CSS計(jì)數(shù)器只能跟content屬性在一起的時(shí)候才有作用,而content屬性貌似專(zhuān)門(mén)用在before/after偽元素上的。于是,就有了,“計(jì)數(shù)器↔偽元素↔content屬性”的鐵三角關(guān)系。
二、CSS計(jì)數(shù)器成員
舉例班級(jí)中成員依次報(bào)名
其中有這么幾個(gè)關(guān)鍵點(diǎn):
1. 班級(jí)命名。總不能六脈神劍一指,你,儂,汝來(lái)稱(chēng)呼吧~有個(gè)稱(chēng)呼,如生信4班,就知道誰(shuí)的是誰(shuí)了。
2. 報(bào)數(shù)規(guī)則。1,2,3,4遞增報(bào)數(shù),還是1,2,1,2報(bào)數(shù),讓班級(jí)的人知道。
3. 開(kāi)始報(bào)數(shù)。不發(fā)口令,大眼瞪小眼,會(huì)亂了秩序。
巧的是,以上3個(gè)關(guān)鍵點(diǎn)正好對(duì)應(yīng)CSS計(jì)數(shù)器的2個(gè)屬性和1個(gè)方法,依次是:
1. counter-reset
2. counter-increment
3. counter()/counters()
1. counter-reset
顧名思意,就是“計(jì)數(shù)器-重置”的意思。其實(shí)就是“班級(jí)命名”,主要作用就是給計(jì)數(shù)器起個(gè)名字。如果可能,順便告訴下從哪個(gè)數(shù)字開(kāi)始計(jì)數(shù)。默認(rèn)是0, 注意,默認(rèn)是0而不是1. 可能有同學(xué)回疑惑,尼瑪網(wǎng)上的各種例子默認(rèn)顯示的第1個(gè)數(shù)字不都是1嗎?那是因?yàn)槭芰?code>counter-increment普照的影響,后面會(huì)詳細(xì)講解。
OK, 這里,我們先看兩個(gè)簡(jiǎn)單的counter-reset的例子:
.xxx { counter-reset: small-apple; } /* 計(jì)數(shù)器名稱(chēng)是'small-apple' */
.xxx { counter-reset: small-apple 2; } /* 計(jì)數(shù)器名稱(chēng)是'small-apple', 并且默認(rèn)起始值是2 */
demo:
.contaner1 {
counter-reset: number;
}
.contaner1:before {
content: counter(number);
}
.contaner2 {
counter-reset: number 1;
}
.contaner2:before {
content: counter(number);
}
<div class="row">
<div class="contaner1">定義一個(gè)名稱(chēng)開(kāi)始編號(hào)</div>
</div>
<div class="row">
<div class="contaner2">定義一個(gè)名稱(chēng)開(kāi)始編號(hào),定義初始值為1</div>
</div>
counter-reset的計(jì)數(shù)重置可以是負(fù)數(shù),例如-2。也可以寫(xiě)成小數(shù),例如2.99,不過(guò)就是IE和FireFox都不識(shí)別,認(rèn)為是不合法數(shù)值,直接無(wú)視,當(dāng)作默認(rèn)值0來(lái)處理;不過(guò)Chrome不嫌貧嫉富,任何小數(shù)都是向下取整,如2.99當(dāng)成2處理,于是王小二還是那個(gè)王小二。
到此為止?非也非也!counter-reset還有一手,就是多個(gè)計(jì)數(shù)器同時(shí)命名。例如,王小二和王小三同時(shí)登臺(tái):
demo:
.contaner5 {
counter-reset: number 3 number1 4;
}
.contaner5:before {
content: counter(number) 'A' counter(number1);
}
<div class="row">
<div class="contaner5">定義兩個(gè)計(jì)數(shù)器,第一個(gè)從3開(kāi)始,第二個(gè)從4開(kāi)始</div>
</div>
直接空格分隔,譬如逗號(hào)什么的都不行。
另外,counter-reset還可以設(shè)置為none和inherit. 干掉重置以及繼承重置。你懂的,就不展開(kāi)了。
2. counter-increment
顧名思意,就是“計(jì)數(shù)器-遞增”的意思。值為counter-reset的1個(gè)或多個(gè)關(guān)鍵字。后面可以跟隨數(shù)字,表示每次計(jì)數(shù)的變化值。如果缺省,則使用默認(rèn)變化值1(方便起見(jiàn),下面的都使用默認(rèn)值做說(shuō)明)。
CSS的計(jì)數(shù)器的計(jì)數(shù)是有一套規(guī)則的,我將之形象地稱(chēng)為“普照規(guī)則”。具體來(lái)講就是:普照源(counter-reset)唯一,每普照(counter-increment)1次,普照源增加1次計(jì)數(shù)值。
于是,我們可以解釋上面提到的“默認(rèn)值是0”的問(wèn)題。通常CSS計(jì)數(shù)器應(yīng)用的時(shí)候,我們都會(huì)使用counter-increment, 肯定要用這個(gè),否則怎么遞增呢!而且一般都是1次普照,正好+1,第一個(gè)計(jì)數(shù)的值就是1啦(0+1=1)!
下面,通過(guò)幾個(gè)例子,給大家形象地展示下普照規(guī)則。
Demo相關(guān)核心代碼為:
.contaner3 {
counter-reset: number 1;
counter-increment: number;
}
.contaner3:before {
content: counter(number);
}
<div class="row">
<div class="contaner3">定義一個(gè)名稱(chēng)開(kāi)始編號(hào),定義初始值為1,定義它的編碼規(guī)則 每次自增1(只有父元素)</div>
</div>
這里counter-increment普照了p標(biāo)簽,counter-reset值增加,默認(rèn)遞增1,于是計(jì)數(shù)從設(shè)置的初始值2變成了3,wangxiaoer就是這里的計(jì)數(shù)器,自然偽元素content值counter(wangxiaoer)就是3.
當(dāng)然,也可以普照自身,也就是counter-increment直接設(shè)置在子元素上:
.contaner7 {
counter-reset: number 1;
}
.contaner7:before {
counter-increment: number;
content: counter(number);
}
<div class="row">
<div class="contaner7">定義一個(gè)名稱(chēng)開(kāi)始編號(hào),定義初始值為1,定義它的編碼規(guī)則 每次自增1(只有子元素)</div>
</div>
依然是1次普照,依舊全局的計(jì)數(shù)器+1,所以,顯示的數(shù)值還是3().
趁熱打鐵。如果父元素和子元素都被counter-increment普照1遍,結(jié)果會(huì)如何呢?
很簡(jiǎn)單的,父元素1次普照,子元素1次普照,共兩次普照,counter-reset設(shè)置的計(jì)數(shù)器值增加2次,計(jì)數(shù)起始值是1,于是現(xiàn)實(shí)的數(shù)字就是3啦!
.contaner4 {
counter-reset: number 1;
counter-increment: number;
}
.contaner4:before {
content: counter(number);
counter-increment: number;
}
<div class="row">
<div class="contaner4">定義一個(gè)名稱(chēng)開(kāi)始編號(hào),定義初始值為1,定義它的編碼規(guī)則 每次自增1(父元素和子元素都有)</div>
</div>
總而言之,無(wú)論位置在何方,只要有counter-increment,對(duì)應(yīng)的計(jì)數(shù)器的值就會(huì)變化,counter()只是輸出而已!
理解了“普照規(guī)則”,則以我們通常的計(jì)數(shù)器遞增效果也可以理解了。
考慮下面這兩個(gè)問(wèn)題:
爸爸受到普照,且重置默認(rèn)值0,爸爸有2個(gè)孩子。孩子自身都沒(méi)有普照。兩個(gè)孩子的計(jì)數(shù)值是?
爸爸沒(méi)有普照,重置默認(rèn)值0,爸爸有2個(gè)孩子。孩子自身都接受普照。兩個(gè)孩子的計(jì)數(shù)值是?
答案是:1,1和1,2!
哦?答案居然不一樣,有什么差別呢?
很簡(jiǎn)單。什么爸爸,孩子你都不要關(guān)心。只要看被普照了幾次。情況1就爸爸被普照,因此,計(jì)數(shù)器增加1次,此時(shí)兩個(gè)孩子的counter自然都是1; 情況2,兩個(gè)孩子被普照,普照2次,第1個(gè)孩子普照之時(shí),計(jì)數(shù)器+1,也就是1;第2個(gè)孩子普照之時(shí)再+1,于是就是2. 于是,兩個(gè)孩子的counter輸出就是1,2.
.row4 .contaner6:before {
counter-increment: number;
content: counter(number);
}
.row4 {
counter-reset: number 1;
}
<div class="row4 row">
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
</div>
計(jì)數(shù)器的數(shù)值變化遵循HTML渲染順序,遇到一個(gè)increment計(jì)數(shù)器就變化,什么時(shí)候counter輸出就輸出此時(shí)的計(jì)數(shù)值。看懂了下圖,您自然就會(huì)全然明白“普照規(guī)則”了。
counter-increment其他設(shè)定counter-reset可以一次命名兩個(gè)計(jì)數(shù)器名稱(chēng),counter-increment自然有與之呼應(yīng)的設(shè)定,也是名稱(chēng)留空就可以了。
正如本節(jié)開(kāi)始提到的,這變化的值不一定是1,我們可以靈活設(shè)置。例如:
counter-increment: counter 2
那就是偶數(shù)偶數(shù)的增加。例如下面這個(gè)變身:
還可以是負(fù)數(shù),例如:
counter-increment: counter -1
.row2 {
counter-reset: number 0;
}
.row2 .contaner6:before {
counter-increment: number -1;
content: counter(number);
}
<div class="row2 row ">
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)--遞減--初始值是0(默認(rèn)是0)----每次自減1(默認(rèn)是1)</div>
</div>
就有了遞減排序效果啦!
值還可以是none或者inherit.
3. counter()/counters()
這是個(gè)方法,不是屬性。類(lèi)似CSS3中才calc()計(jì)算。這里作用很單純顯示計(jì)數(shù)。不過(guò)名稱(chēng)、用法有多個(gè):
①目前為止,我們看到的是最簡(jiǎn)單的用法:
counter(name) /* name就是counter-reset的名稱(chēng) */
②那下面這個(gè)語(yǔ)法是什么意思呢?
counter(name, style)
這里的style參數(shù)還有有些名堂的。其支持的關(guān)鍵字值就是list-style-type支持的那些值。作用是,我們遞增遞減可以不一定是數(shù)字,還可以是英文字母,或者羅馬文等。
list-style-type:disc | circle | square | decimal | lower-roman | upper-roman | lower-alpha | upper-alpha | none | armenian | cjk-ideographic | georgian | lower-greek | hebrew | hiragana | hiragana-iroha | katakana | katakana-iroha | lower-latin | upper-latin
.row1 {
counter-reset: number 1;
}
.row1 .contaner6:before {
counter-increment: number;
content: counter(number,upper-roman);
}
<div class="row1 row">
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-遞增---初始值是1---每次自增1(默認(rèn)是1)</div>
</div>
③counter還支持級(jí)聯(lián)。也就是一個(gè)content屬性值可以有多個(gè)counter()方法。
上面CSS源代碼使用'A'使用inline水平元素?fù)Q行,此技術(shù)若有興趣,可參考之前的“使用CSS(Unicode字符)讓inline水平元素?fù)Q行”一文。
④下面介紹下counters()方法。看似值多了個(gè)字母s, 但表意大變身。counters幾乎可以說(shuō)是嵌套計(jì)數(shù)的代名詞。
我們平時(shí)的序號(hào),不可能就只是1,2,3,4,.., 還會(huì)有諸如1.1,1.2,1.3,...等的子序號(hào)。得,前者就是counter()干的事情,后者就是counters()干的事情。
基本用法為:
counters(name, string); /* MDN上說(shuō),要想IE8兼容,這里逗號(hào)后面的空格要去掉,但是鄙人IE11的IE8模式看,無(wú)此問(wèn)題 */
其中,string參數(shù)為字符串(需要引號(hào)包圍的)(必須參數(shù)),表示子序號(hào)的連接字符串。例如1.1的string就是'.',1-1就是'-'.
看上去很簡(jiǎn)單。但是,如果理解不是很深刻,日后在使用肯定會(huì)遇到麻煩——“咦?怎么沒(méi)有子序列,明明語(yǔ)法正確的啊?”首先,記住這一句話,“普照源是唯一的”,所以,如果你在只在body標(biāo)簽上設(shè)置counter-reset,就算里面的子元素嵌套了祖宗十八代,還是不會(huì)有任何嵌套序號(hào)出現(xiàn)的!
所以,要想實(shí)現(xiàn)嵌套,必須讓每一個(gè)列表容器擁有一個(gè)“普照源”,通過(guò)子輩對(duì)父輩的counter-reset重置、配合counters()方法才能實(shí)現(xiàn)計(jì)數(shù)嵌套效果。
.row3{ counter-reset:number 0;}
.row3 .contaner6:before{
counter-increment: number 1;
content:counters(number,"-") '.';
}
<div class="row3 row">
<div class="contaner6">自動(dòng)標(biāo)號(hào)----第一級(jí)
<div class="row3">
<div class="contaner6">
自動(dòng)標(biāo)號(hào)-----第二級(jí)
<div class="row3">
<div class="contaner6">
自動(dòng)標(biāo)號(hào)-----第三級(jí)
<div class="row3">
<div class="contaner6">自動(dòng)標(biāo)號(hào)-----第四級(jí)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-----第四級(jí)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-----第四級(jí)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-----第四級(jí)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)-----第四級(jí)</div>
</div>
</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
</div>
</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
</div>
</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
<div class="contaner6">自動(dòng)標(biāo)號(hào)</div>
</div>
也會(huì)遇到這樣的麻煩——“咦,怎么子序列不按層級(jí)順序來(lái)啊,命名語(yǔ)法正確啊?” 還是要記住這一句話:“一個(gè)容器里的普照源(reset)是唯一的”,所以,
如果你不小心把計(jì)數(shù)顯示和技術(shù)reset元素以兄弟元素形式放在一起(雖然HTML內(nèi)容布局呈現(xiàn)是沒(méi)有異常的),就很可能會(huì)出現(xiàn)計(jì)數(shù)序號(hào)亂入的情況。
會(huì)看到標(biāo)紅的部分的序號(hào)顯示異常了!
為何會(huì)出現(xiàn)這個(gè)問(wèn)題,我們看下HTML(主要是注釋?zhuān)?/p>
<div class="reset">
<div class="counter">我是王小二</div>
<div class="reset"><-- 這里的reset與上面的counter是兄弟關(guān)系,而不是父子關(guān)系。雖然布局渲染上沒(méi)有差異。但是,一個(gè)容器的reset的唯一的,一旦子元素出現(xiàn)reset,會(huì)改變整個(gè)容器的嵌套關(guān)系,于是,后面的“王小三”、“王小四”其實(shí)已經(jīng)進(jìn)入了2級(jí)嵌套,因此顯示的是1-3和1-4 -->
...
</div>
<div class="counter">我是王小三</div>
<div class="counter">我是王小四</div>
<div class="reset">
<div class="counter">我是王小四的大兒子</div>
</div>
</div>
如果上面的注釋沒(méi)看明白,您可以跟前面沒(méi)有問(wèn)題的demo做下HTML結(jié)構(gòu)對(duì)比,或許就會(huì)豁然開(kāi)朗!
⑤counters()也是支持style自定義遞增形式的。
counters(name, string, style)
與counter()的style參數(shù)使用一致,不贅述。
四、CSS計(jì)數(shù)器與display:none
一個(gè)元素,如果設(shè)置了counter-increment, 但是其display的屬性值是none或者含有hidden屬性(針對(duì)支持瀏覽器),則此計(jì)數(shù)值是不會(huì)增加的。而visibility:hidden以及其他聲明不會(huì)有此現(xiàn)象。
五、CSS計(jì)數(shù)器實(shí)際應(yīng)用
相比傳統(tǒng)的ol,ul列表計(jì)數(shù),CSS計(jì)數(shù)器的優(yōu)勢(shì)就在于靈活與強(qiáng)大,不足就是IE6/IE7不支持。
普照規(guī)則第一條,普照源唯一。所以,我們可以在頭尾放兩個(gè)差距甚遠(yuǎn)的列表,然后,這些列表自動(dòng)顯示序號(hào)。而ol/ul只能寫(xiě)死start實(shí)現(xiàn),很不靈活,一旦列表有刪減,就嗝屁了。
由于計(jì)數(shù)器是偽元素控制顯示的。因此,我們幾乎可以應(yīng)用各種CSS樣式,各種定位等。所以,基本上,只要有有序序號(hào)呈現(xiàn)的地方,就能使用CSS計(jì)數(shù)器。
例如,電商首頁(yè)的圖片slide廣告上的1,2,3,4,...序號(hào);
我們做分享時(shí)候使用的HTML5 web在線幻燈片就可以使用CSS計(jì)數(shù)器標(biāo)注頁(yè)數(shù)等;以及一開(kāi)始給小伙伴們做的果汁工具的3個(gè)選擇等。
參考文章
Automatic Numbering With CSS Counters
http://www.w3.org/TR/CSS2/generate.html
counter-reset
counter-increment
Using CSS counters
本文原創(chuàng)地址:http://www.zhangxinxu.com/wordpress/?p=4303
總結(jié)
以上是生活随笔為你收集整理的CSS counter计数器(content目录序号自动递增)详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sess文件编译输出css的四种方式以及
- 下一篇: 简单几招模拟网络超时情况