一、挖墳不可恥
CSS計數器不是什么新鮮玩意了,早在10年春暖花開的時候,我寫的“CSS content內容生成技術以及應用”一文就要提到(見下圖),不過當時是作為其中一員介紹。就像例行的溜新同事一樣,雖然黑如焦炭的我在自我介紹的時候給新同事留下了深刻印象,但由於介紹的同事茫茫多,我只是其中一員。很自然,個把月之后,我就會被無情的淡忘,除了那依稀的面龐,因為畢竟長得還算比較抽象。

然而,CSS計數器的斗量顯然不是短短幾句介紹能夠顯露的,所謂人不可貌相。就像我,說不定某年某月,當年像驢子一樣被溜的新同事終於腦袋被門夾了,想起了我的音容笑貌,找我來尋求幫助呢!
我最近就遇到這樣的情況。
給部門同事做點果汁系統的時候,由於果汁店經常會有水果因果品爆發被N多靚妹相中而缺貨,因此,每人可以選擇三種自由搭配的飲品。於是,就有了第1選擇、第2選擇、第3選擇……

本來我是純文字寫在標簽里的。好重好累,感覺不會再愛了!此時,突然眼前一道白光,午休時間結束,阿姨把辦公室的燈打開了。這恍如隔世的念閃讓我突然想起了當年大明湖畔的“CSS計數器”。想當年,移動web還是草莽,IE六七興風作浪。這誘人的技能就算昭告於世也是受制於兼容大環境而腰斬的命。
但是現在不一樣了,我們趕上了一個更好的時代:英語老師從事傳統工業生產錘子,影視明星舍身取義集體赴監獄拍攝大片;以前那些受制於IE6/IE7不兼容而不見天日的高級CSS/JS特性也紛紛走到了台前,CSS計數器就是其中一員。於是,我拿起我平時釣魚挖蚯蚓的小鍬去挖CSS計數器的墳。雖然目前網上已有一些介紹CSS計數器的文章,但大多不夠全面,案例不夠精彩,查閱也不方便。就像是租的房子,雖然也能擋風遮雨,但裝修風格不是自己的,還寄人籬下,保不准房東借個東風就把我吹走了。所以啊,有必要自己留一手,去挖個墳然后建個房。
對於純潔的技術圈而言,挖墳並不可恥。我們重新去挖掘過去的那些文章知識,好像一個考古學家去挖掘塵封的歷史、消失的文明一般,是件很有價值的事情。所以,如果大家對挖掘考古感興趣,就跟我一起去挖挖挖~~

CSS計數器不是什么新鮮玩意了,早在10年春暖花開的時候,我寫的“CSS content內容生成技術以及應用”一文就要提到(見下圖),不過當時是作為其中一員介紹。就像例行的溜新同事一樣,雖然黑如焦炭的我在自我介紹的時候給新同事留下了深刻印象,但由於介紹的同事茫茫多,我只是其中一員。很自然,個把月之后,我就會被無情的淡忘,除了那依稀的面龐,因為畢竟長得還算比較抽象。
然而,CSS計數器的斗量顯然不是短短幾句介紹能夠顯露的,所謂人不可貌相。就像我,說不定某年某月,當年像驢子一樣被溜的新同事終於腦袋被門夾了,想起了我的音容笑貌,找我來尋求幫助呢!
我最近就遇到這樣的情況。
給部門同事做點果汁系統的時候,由於果汁店經常會有水果因果品爆發被N多靚妹相中而缺貨,因此,每人可以選擇三種自由搭配的飲品。於是,就有了第1選擇、第2選擇、第3選擇……
本來我是純文字寫在標簽里的。好重好累,感覺不會再愛了!此時,突然眼前一道白光,午休時間結束,阿姨把辦公室的燈打開了。這恍如隔世的念閃讓我突然想起了當年大明湖畔的“CSS計數器”。想當年,移動web還是草莽,IE六七興風作浪。這誘人的技能就算昭告於世也是受制於兼容大環境而腰斬的命。
但是現在不一樣了,我們趕上了一個更好的時代:英語老師從事傳統工業生產錘子,影視明星舍身取義集體赴監獄拍攝大片;以前那些受制於IE6/IE7不兼容而不見天日的高級CSS/JS特性也紛紛走到了台前,CSS計數器就是其中一員。於是,我拿起我平時釣魚挖蚯蚓的小鍬去挖CSS計數器的墳。雖然目前網上已有一些介紹CSS計數器的文章,但大多不夠全面,案例不夠精彩,查閱也不方便。就像是租的房子,雖然也能擋風遮雨,但裝修風格不是自己的,還寄人籬下,保不准房東借個東風就把我吹走了。所以啊,有必要自己留一手,去挖個墳然后建個房。
對於純潔的技術圈而言,挖墳並不可恥。我們重新去挖掘過去的那些文章知識,好像一個考古學家去挖掘塵封的歷史、消失的文明一般,是件很有價值的事情。所以,如果大家對挖掘考古感興趣,就跟我一起去挖挖挖~~
二、CSS計數器三角關系挖挖挖
CSS計數器只能跟content
屬性在一起的時候才有作用,而content
屬性貌似專門用在before
/after
偽元素上的。於是,就有了,“計數器↔偽元素↔content屬性”的鐵三角關系。
CSS計數器只能跟content
屬性在一起的時候才有作用,而content
屬性貌似專門用在before
/after
偽元素上的。於是,就有了,“計數器↔偽元素↔content屬性”的鐵三角關系。
三、CSS計數器成員挖挖挖
CSS計數就跟我們軍訓報數一樣的!現在,讓我們的靜靜地閉上眼睛,讓思緒飛到青蔥的大學,那個炎熱的夏日,那個寬廣的軍訓場地,你…想到了什么?——“隔壁班的那個妹子長得好水靈好可愛我好喜歡”。囧,還有呢?——“露着大腿的漂亮師姐從面前悠然走過,留下一陣芬芳,擄走我的心房”。……

成心找抽啊!就算色心滿滿,腦袋插滿刀子,也應該想到,帥氣的教官有木有!共苦的基友有木有!嘹亮的口號有木有!犀利的報數有木有!
說到報數,是否想起了教官的嘹亮口號:“生信4班,立正,稍息,開始1,2,3,4報數!”
其中有這么幾個關鍵點:
1. 班級命名。總不能六脈神劍一指,你,儂,汝來稱呼吧~有個稱呼,如生信4班,就知道誰的是誰了。
2. 報數規則。1,2,3,4遞增報數,還是1,2,1,2報數,讓班級的人知道。
3. 開始報數。不發口令,大眼瞪小眼,會亂了秩序。
巧的是,以上3個關鍵點正好對應CSS計數器的2個屬性和1個方法,依次是:
1. counter-reset
2. counter-increment
3. counter()/counters()
依次說來。
1. counter-reset
顧名思意,就是“計數器-重置”的意思。其實就是“班級命名”,主要作用就是給計數器起個名字。如果可能,順便告訴下從哪個數字開始計數。默認是0
, 注意,默認是0
而不是1
. 可能有同學回疑惑,尼瑪網上的各種例子默認顯示的第1個數字不都是1
嗎?那是因為受了counter-increment
普照的影響,后面會詳細講解。
OK, 這里,我們先看兩個簡單的counter-reset
的例子:
.xxx { counter-reset: small-apple; } /* 計數器名稱是'small-apple' */
.xxx { counter-reset: small-apple 2; } /* 計數器名稱是'small-apple', 並且默認起始值是2 */
聞名不如見面,您可以狠狠地點擊這里:counter-reset值為2簡單demo

counter-reset
的計數重置可以是負數,例如-2
。也可以寫成小數,例如2.99
,不過就是IE和FireFox都不識別,認為是不合法數值,直接無視,當作默認值0
來處理;不過Chrome不嫌貧嫉富,任何小數都是向下取整,如2.99
當成2
處理,於是王小二還是那個王小二。
到此為止?非也非也!counter-reset
還有一手,就是多個計數器同時命名。例如,王小二和王小三同時登台:
.xxx { counter-reset: wangxiaoer 2 wangxiaosan 3; }
直接空格分隔,譬如逗號什么的都不行。
聞名不如見面,您可以狠狠地點擊這里:兩個技術名稱並存demo

另外,counter-reset
還可以設置為none
和inherit
. 干掉重置以及繼承重置。你懂的,就不展開了。
2. counter-increment
顧名思意,就是“計數器-遞增”的意思。值為counter-reset
的1個或多個關鍵字。后面可以跟隨數字,表示每次計數的變化值。如果缺省,則使用默認變化值1
(方便起見,下面的都使用默認值做說明)。
CSS的計數器的計數是有一套規則的,我將之形象地稱為“普照規則”。具體來講就是:普照源(counter-reset)唯一,每普照(counter-increment)1次,普照源增加1次計數值。
於是,我們可以解釋上面提到的“默認值是0
”的問題。通常CSS計數器應用的時候,我們都會使用counter-increment
, 肯定要用這個,否則怎么遞增呢!而且一般都是1
次普照,正好+1
,第一個計數的值就是1
啦(0+1=1)!
下面,通過幾個例子,給大家形象地展示下普照規則。
① 您可以狠狠地點擊這里:王小二counter-increment普照成王小三demo
demo中,王小二的counter-reset
值是wangxiaoer 2
,但是,顯示的計數不是小2
而是小3
,王小二變成了王小三!

Demo相關核心代碼為:
.counter { counter-reset: wangxiaoer 2; counter-increment: wangxiaoer; }
.counter:before { content: counter(wangxiaoer); }
<p class="counter"></p>
這里counter-increment
普照了p
標簽,counter-reset
值增加,默認遞增1
,於是計數從設置的初始值2
變成了3
,wangxiaoer
就是這里的計數器,自然偽元素content值counter(wangxiaoer)
就是3
.
② 當然,也可以普照自身,也就是counter-increment
直接設置在偽元素上:
.counter { counter-reset: wangxiaoer 2; }
.counter:before { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p>
依然是1次普照,依舊全局的計數器+1
,所以,顯示的數值還是3
(demo略).
③ 趁熱打鐵。如果父元素和子元素都被counter-increment
普照1遍,結果會如何呢?
很簡單的,父元素1次普照,子元素1次普照,共兩次普照,counter-reset
設置的計數器值增加2次,計數起始值是2,於是現實的數字就是4
啦!
您可以狠狠地點擊這里:counter-increment父子連續普照demo

Demo相關核心代碼為:
.counter { counter-reset: wangxiaoer 2; counter-increment: wangxiaoer; }
.counter:before { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p> // 顯示的是4
總而言之,無論位置在何方,只要有counter-increment
,對應的計數器的值就會變化,counter()
只是輸出而已!
④ 理解了“普照規則”,則以我們通常的計數器遞增效果也可以理解了。
考慮下面這兩個問題:
- 爸爸受到普照,且重置默認值
0
,爸爸有2個孩子。孩子自身都沒有普照。兩個孩子的計數值是?
- 爸爸沒有普照,重置默認值
0
,爸爸有2個孩子。孩子自身都接受普照。兩個孩子的計數值是?
答案是:1,1和1,2!
哦?答案居然不一樣,有什么差別呢?
很簡單。什么爸爸,孩子你都不要關心。只要看被普照了幾次。情況1就爸爸被普照,因此,計數器增加1次,此時兩個孩子的counter
自然都是1
; 情況2,兩個孩子被普照,普照2次,第1個孩子普照之時,計數器+1,也就是1;第2個孩子普照之時再+1,於是就是2. 於是,兩個孩子的counter
輸出就是1,2
.
您可以狠狠地點擊這里:兄弟遞增規則演示demo
上demo對應上面的第2個問題,其結果截圖如下:

核心代碼如下:
.counter { counter-reset: wangxiaoer 2; }
.counter:before,
.counter:after { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p>
計數器的數值變化遵循HTML渲染順序,遇到一個increment
計數器就變化,什么時候counter
輸出就輸出此時的計數值。看懂了下圖,您自然就會全然明白“普照規則”了。

如果上圖看不明白,您可以狠狠地點擊這里查看HTML與CSS源代碼,感受下increment
即遞增的“普照規則”。
counter-increment其他設定
① counter-reset
可以一次命名兩個計數器名稱,counter-increment
自然有與之呼應的設定,也是名稱留空就可以了。
您可以狠狠地點擊這里:counter-increment多名稱同時應用demo

② 正如本節開始提到的,這變化的值不一定是1
,我們可以靈活設置。例如:
counter-increment: counter 2
那就是偶數偶數的增加。例如下面這個變身:

還可以是負數,例如:
counter-increment: counter -1
就有了遞減排序效果啦!
③ 值還可以是none
或者inherit
.
3. counter()/counters()
這是個方法,不是屬性。類似CSS3中才calc()
計算。這里作用很單純顯示計數。不過名稱、用法有多個:

① 目前為止,我們看到的是最簡單的用法:
counter(name) /* name就是counter-reset的名稱 */
② 那下面這個語法是什么意思呢?
counter(name, style)
這里的style
參數還有有些名堂的。其支持的關鍵字值就是list-style-type
支持的那些值。作用是,我們遞增遞減可以不一定是數字,還可以是英文字母,或者羅馬文等。
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
聞名不如見面。您可以狠狠地點擊這里:CSS計數器counter()方法style參數demo
結果見下截圖:

核心CSS代碼為:
content: counter(wangxiaoer, lower-roman); /* 以小寫羅馬數字格式表示當前計數器wangxiaoer的值 */
③ counter還支持級聯。也就是一個content
屬性值可以有多個counter()
方法。
聞名不如見面。您可以狠狠地點擊這里:多個counter級聯並存demo

核心CSS/HTML如下:
.counter { counter-reset: wangxiaoer 2 wangxiaosan 3; }
.counter:before { content: counter(wangxiaoer) '\A' counter(wangxiaosan); white-space: pre; }
<p class="counter"></p>
上面CSS源代碼使用'\A'
使用inline
水平元素換行,此技術若有興趣,可參考之前的“使用CSS(Unicode字符)讓inline水平元素換行”一文。
④ 下面介紹下counters()
方法。看似值多了個字母s
, 但表意大變身。counters
幾乎可以說是嵌套計數的代名詞。
我們平時的序號,不可能就只是1,2,3,4,..
, 還會有諸如 1.1,1.2,1.3,...
等的子序號。得,前者就是counter()
干的事情,后者就是counters()
干的事情。
基本用法為:
counters(name, string); /* MDN上說,要想IE8兼容,這里逗號后面的空格要去掉,但是鄙人IE11的IE8模式看,無此問題 */
其中,string
參數為字符串(需要引號包圍的)(必須參數),表示子序號的連接字符串。例如1.1
的string
就是'.'
,1-1
就是'-'
.
看上去很簡單。但是,如果理解不是很深刻,日后在使用肯定會遇到麻煩——“咦?怎么沒有子序列,明明語法正確的啊?”首先,記住這一句話,“普照源是唯一的”,所以,如果你在只在body
標簽上設置counter-reset
,就算里面的子元素嵌套了祖宗十八代,還是不會有任何嵌套序號出現的!所以,要想實現嵌套,必須讓每一個列表容器擁有一個“普照源”,通過子輩對父輩的counter-reset
重置、配合counters()
方法才能實現計數嵌套效果。
聞名不如見面。您可以狠狠地點擊這里:CSS計數器內嵌demo

也會遇到這樣的麻煩——“咦,怎么子序列不按層級順序來啊,命名語法正確啊?” 還是要記住這一句話:“一個容器里的普照源(reset)是唯一的”,所以,如果你不小心把計數顯示和技術reset元素以兄弟元素形式放在一起(雖然HTML內容布局呈現是沒有異常的),就很可能會出現計數序號亂入的情況。
聞名不如見面。您可以狠狠地點擊這里:CSS計數器counters列表被reset亂入demo
會看到標紅的部分的序號顯示異常了!

為何會出現這個問題,我們看下HTML(主要是注釋):
<div class="reset">
<div class="counter">我是王小二</div>
<div class="reset"><-- 這里的reset與上面的counter是兄弟關系,而不是父子關系。雖然布局渲染上沒有差異。但是,一個容器的reset的唯一的,一旦子元素出現reset,會改變整個容器的嵌套關系,於是,后面的“王小三”、“王小四”其實已經進入了2級嵌套,因此顯示的是1-3和1-4 -->
...
</div>
<div class="counter">我是王小三</div>
<div class="counter">我是王小四</div>
<div class="reset">
<div class="counter">我是王小四的大兒子</div>
</div>
</div>
如果上面的注釋沒看明白,您可以跟前面沒有問題的demo做下HTML結構對比,或許就會豁然開朗!
⑤ counters()
也是支持style
自定義遞增形式的。
counters(name, string, style)
與counter()
的style
參數使用一致,不贅述。
CSS計數就跟我們軍訓報數一樣的!現在,讓我們的靜靜地閉上眼睛,讓思緒飛到青蔥的大學,那個炎熱的夏日,那個寬廣的軍訓場地,你…想到了什么?——“隔壁班的那個妹子長得好水靈好可愛我好喜歡”。囧,還有呢?——“露着大腿的漂亮師姐從面前悠然走過,留下一陣芬芳,擄走我的心房”。……
成心找抽啊!就算色心滿滿,腦袋插滿刀子,也應該想到,帥氣的教官有木有!共苦的基友有木有!嘹亮的口號有木有!犀利的報數有木有!
說到報數,是否想起了教官的嘹亮口號:“生信4班,立正,稍息,開始1,2,3,4報數!”
其中有這么幾個關鍵點:
1. 班級命名。總不能六脈神劍一指,你,儂,汝來稱呼吧~有個稱呼,如生信4班,就知道誰的是誰了。
2. 報數規則。1,2,3,4遞增報數,還是1,2,1,2報數,讓班級的人知道。
3. 開始報數。不發口令,大眼瞪小眼,會亂了秩序。
巧的是,以上3個關鍵點正好對應CSS計數器的2個屬性和1個方法,依次是:
1. counter-reset
2. counter-increment
3. counter()/counters()
依次說來。
1. counter-reset
顧名思意,就是“計數器-重置”的意思。其實就是“班級命名”,主要作用就是給計數器起個名字。如果可能,順便告訴下從哪個數字開始計數。默認是0
, 注意,默認是0
而不是1
. 可能有同學回疑惑,尼瑪網上的各種例子默認顯示的第1個數字不都是1
嗎?那是因為受了counter-increment
普照的影響,后面會詳細講解。
OK, 這里,我們先看兩個簡單的counter-reset
的例子:
.xxx { counter-reset: small-apple; } /* 計數器名稱是'small-apple' */
.xxx { counter-reset: small-apple 2; } /* 計數器名稱是'small-apple', 並且默認起始值是2 */
聞名不如見面,您可以狠狠地點擊這里:counter-reset值為2簡單demo
counter-reset
的計數重置可以是負數,例如-2
。也可以寫成小數,例如2.99
,不過就是IE和FireFox都不識別,認為是不合法數值,直接無視,當作默認值0
來處理;不過Chrome不嫌貧嫉富,任何小數都是向下取整,如2.99
當成2
處理,於是王小二還是那個王小二。
到此為止?非也非也!counter-reset
還有一手,就是多個計數器同時命名。例如,王小二和王小三同時登台:
.xxx { counter-reset: wangxiaoer 2 wangxiaosan 3; }
直接空格分隔,譬如逗號什么的都不行。
聞名不如見面,您可以狠狠地點擊這里:兩個技術名稱並存demo
另外,counter-reset
還可以設置為none
和inherit
. 干掉重置以及繼承重置。你懂的,就不展開了。
2. counter-increment
顧名思意,就是“計數器-遞增”的意思。值為counter-reset
的1個或多個關鍵字。后面可以跟隨數字,表示每次計數的變化值。如果缺省,則使用默認變化值1
(方便起見,下面的都使用默認值做說明)。
CSS的計數器的計數是有一套規則的,我將之形象地稱為“普照規則”。具體來講就是:普照源(counter-reset)唯一,每普照(counter-increment)1次,普照源增加1次計數值。
於是,我們可以解釋上面提到的“默認值是0
”的問題。通常CSS計數器應用的時候,我們都會使用counter-increment
, 肯定要用這個,否則怎么遞增呢!而且一般都是1
次普照,正好+1
,第一個計數的值就是1
啦(0+1=1)!
下面,通過幾個例子,給大家形象地展示下普照規則。
① 您可以狠狠地點擊這里:王小二counter-increment普照成王小三demo
demo中,王小二的counter-reset
值是wangxiaoer 2
,但是,顯示的計數不是小2
而是小3
,王小二變成了王小三!
Demo相關核心代碼為:
.counter { counter-reset: wangxiaoer 2; counter-increment: wangxiaoer; } .counter:before { content: counter(wangxiaoer); }
<p class="counter"></p>
這里counter-increment
普照了p
標簽,counter-reset
值增加,默認遞增1
,於是計數從設置的初始值2
變成了3
,wangxiaoer
就是這里的計數器,自然偽元素content值counter(wangxiaoer)
就是3
.
② 當然,也可以普照自身,也就是counter-increment
直接設置在偽元素上:
.counter { counter-reset: wangxiaoer 2; } .counter:before { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p>
依然是1次普照,依舊全局的計數器+1
,所以,顯示的數值還是3
(demo略).
③ 趁熱打鐵。如果父元素和子元素都被counter-increment
普照1遍,結果會如何呢?
很簡單的,父元素1次普照,子元素1次普照,共兩次普照,counter-reset
設置的計數器值增加2次,計數起始值是2,於是現實的數字就是4
啦!
您可以狠狠地點擊這里:counter-increment父子連續普照demo
Demo相關核心代碼為:
.counter { counter-reset: wangxiaoer 2; counter-increment: wangxiaoer; } .counter:before { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p> // 顯示的是4
總而言之,無論位置在何方,只要有counter-increment
,對應的計數器的值就會變化,counter()
只是輸出而已!
④ 理解了“普照規則”,則以我們通常的計數器遞增效果也可以理解了。
考慮下面這兩個問題:
- 爸爸受到普照,且重置默認值
0
,爸爸有2個孩子。孩子自身都沒有普照。兩個孩子的計數值是? - 爸爸沒有普照,重置默認值
0
,爸爸有2個孩子。孩子自身都接受普照。兩個孩子的計數值是?
答案是:1,1和1,2!
哦?答案居然不一樣,有什么差別呢?
很簡單。什么爸爸,孩子你都不要關心。只要看被普照了幾次。情況1就爸爸被普照,因此,計數器增加1次,此時兩個孩子的counter
自然都是1
; 情況2,兩個孩子被普照,普照2次,第1個孩子普照之時,計數器+1,也就是1;第2個孩子普照之時再+1,於是就是2. 於是,兩個孩子的counter
輸出就是1,2
.
您可以狠狠地點擊這里:兄弟遞增規則演示demo
上demo對應上面的第2個問題,其結果截圖如下:
核心代碼如下:
.counter { counter-reset: wangxiaoer 2; } .counter:before, .counter:after { content: counter(wangxiaoer); counter-increment: wangxiaoer; }
<p class="counter"></p>
計數器的數值變化遵循HTML渲染順序,遇到一個increment
計數器就變化,什么時候counter
輸出就輸出此時的計數值。看懂了下圖,您自然就會全然明白“普照規則”了。
如果上圖看不明白,您可以狠狠地點擊這里查看HTML與CSS源代碼,感受下increment
即遞增的“普照規則”。
counter-increment其他設定
① counter-reset
可以一次命名兩個計數器名稱,counter-increment
自然有與之呼應的設定,也是名稱留空就可以了。
您可以狠狠地點擊這里:counter-increment多名稱同時應用demo
② 正如本節開始提到的,這變化的值不一定是1
,我們可以靈活設置。例如:
counter-increment: counter 2
那就是偶數偶數的增加。例如下面這個變身:
還可以是負數,例如:
counter-increment: counter -1
就有了遞減排序效果啦!
③ 值還可以是none
或者inherit
.
3. counter()/counters()
這是個方法,不是屬性。類似CSS3中才calc()
計算。這里作用很單純顯示計數。不過名稱、用法有多個:
① 目前為止,我們看到的是最簡單的用法:
counter(name) /* name就是counter-reset的名稱 */
② 那下面這個語法是什么意思呢?
counter(name, style)
這里的style
參數還有有些名堂的。其支持的關鍵字值就是list-style-type
支持的那些值。作用是,我們遞增遞減可以不一定是數字,還可以是英文字母,或者羅馬文等。
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
聞名不如見面。您可以狠狠地點擊這里:CSS計數器counter()方法style參數demo
結果見下截圖:
核心CSS代碼為:
content: counter(wangxiaoer, lower-roman); /* 以小寫羅馬數字格式表示當前計數器wangxiaoer的值 */
③ counter還支持級聯。也就是一個content
屬性值可以有多個counter()
方法。
聞名不如見面。您可以狠狠地點擊這里:多個counter級聯並存demo
核心CSS/HTML如下:
.counter { counter-reset: wangxiaoer 2 wangxiaosan 3; } .counter:before { content: counter(wangxiaoer) '\A' counter(wangxiaosan); white-space: pre; }
<p class="counter"></p>
上面CSS源代碼使用'\A'
使用inline
水平元素換行,此技術若有興趣,可參考之前的“使用CSS(Unicode字符)讓inline水平元素換行”一文。
④ 下面介紹下counters()
方法。看似值多了個字母s
, 但表意大變身。counters
幾乎可以說是嵌套計數的代名詞。
我們平時的序號,不可能就只是1,2,3,4,..
, 還會有諸如 1.1,1.2,1.3,...
等的子序號。得,前者就是counter()
干的事情,后者就是counters()
干的事情。
基本用法為:
counters(name, string); /* MDN上說,要想IE8兼容,這里逗號后面的空格要去掉,但是鄙人IE11的IE8模式看,無此問題 */
其中,string
參數為字符串(需要引號包圍的)(必須參數),表示子序號的連接字符串。例如1.1
的string
就是'.'
,1-1
就是'-'
.
看上去很簡單。但是,如果理解不是很深刻,日后在使用肯定會遇到麻煩——“咦?怎么沒有子序列,明明語法正確的啊?”首先,記住這一句話,“普照源是唯一的”,所以,如果你在只在body
標簽上設置counter-reset
,就算里面的子元素嵌套了祖宗十八代,還是不會有任何嵌套序號出現的!所以,要想實現嵌套,必須讓每一個列表容器擁有一個“普照源”,通過子輩對父輩的counter-reset
重置、配合counters()
方法才能實現計數嵌套效果。
聞名不如見面。您可以狠狠地點擊這里:CSS計數器內嵌demo
也會遇到這樣的麻煩——“咦,怎么子序列不按層級順序來啊,命名語法正確啊?” 還是要記住這一句話:“一個容器里的普照源(reset)是唯一的”,所以,如果你不小心把計數顯示和技術reset元素以兄弟元素形式放在一起(雖然HTML內容布局呈現是沒有異常的),就很可能會出現計數序號亂入的情況。
聞名不如見面。您可以狠狠地點擊這里:CSS計數器counters列表被reset亂入demo
會看到標紅的部分的序號顯示異常了!
為何會出現這個問題,我們看下HTML(主要是注釋):
<div class="reset">
<div class="counter">我是王小二</div>
<div class="reset"><-- 這里的reset與上面的counter是兄弟關系,而不是父子關系。雖然布局渲染上沒有差異。但是,一個容器的reset的唯一的,一旦子元素出現reset,會改變整個容器的嵌套關系,於是,后面的“王小三”、“王小四”其實已經進入了2級嵌套,因此顯示的是1-3和1-4 -->
...
</div>
<div class="counter">我是王小三</div>
<div class="counter">我是王小四</div>
<div class="reset">
<div class="counter">我是王小四的大兒子</div>
</div>
</div>
如果上面的注釋沒看明白,您可以跟前面沒有問題的demo做下HTML結構對比,或許就會豁然開朗!
⑤ counters()
也是支持style
自定義遞增形式的。
counters(name, string, style)
與counter()
的style
參數使用一致,不贅述。
四、CSS計數器與display:none挖挖挖
一個元素,如果設置了counter-increment
, 但是其display
的屬性值是none
或者含有hidden
屬性(針對支持瀏覽器),則此計數值是不會增加的。而visibility:hidden
以及其他聲明不會有此現象。
一個元素,如果設置了counter-increment
, 但是其display
的屬性值是none
或者含有hidden
屬性(針對支持瀏覽器),則此計數值是不會增加的。而visibility:hidden
以及其他聲明不會有此現象。
五、CSS計數器實際應用挖挖挖
相比傳統的ol
,ul
列表計數,CSS計數器的優勢就在於靈活與強大,不足就是IE6/IE7不支持。
普照規則第一條,普照源唯一。所以,我們可以在頭尾放兩個差距甚遠的列表,然后,這些列表自動顯示序號。而ol/ul
只能寫死start
實現,很不靈活,一旦列表有刪減,就嗝屁了。
由於計數器是偽元素控制顯示的。因此,我們幾乎可以應用各種CSS樣式,各種定位等。所以,基本上,只要有有序序號呈現的地方,就能使用CSS計數器。
例如,電商首頁的圖片slide廣告上的1,2,3,4,...
序號;

我們做分享時候使用的HTML5 web在線幻燈片就可以使用CSS計數器標注頁數等;以及一開始給小伙伴們做的果汁工具的3個選擇等。
我下筆之初本想搞幾個高保真的例子的,寫到這里發現,內容已經很多了。一篇技術文章,如果讀了2分鍾,發現才讀了一半,后面的內容就會閃電過,然后會有些莫名的評論之類。因此,文章不易過長。所以,這里就要收尾了!
相比傳統的ol
,ul
列表計數,CSS計數器的優勢就在於靈活與強大,不足就是IE6/IE7不支持。
普照規則第一條,普照源唯一。所以,我們可以在頭尾放兩個差距甚遠的列表,然后,這些列表自動顯示序號。而ol/ul
只能寫死start
實現,很不靈活,一旦列表有刪減,就嗝屁了。
由於計數器是偽元素控制顯示的。因此,我們幾乎可以應用各種CSS樣式,各種定位等。所以,基本上,只要有有序序號呈現的地方,就能使用CSS計數器。
例如,電商首頁的圖片slide廣告上的1,2,3,4,...
序號;
我們做分享時候使用的HTML5 web在線幻燈片就可以使用CSS計數器標注頁數等;以及一開始給小伙伴們做的果汁工具的3個選擇等。
我下筆之初本想搞幾個高保真的例子的,寫到這里發現,內容已經很多了。一篇技術文章,如果讀了2分鍾,發現才讀了一半,后面的內容就會閃電過,然后會有些莫名的評論之類。因此,文章不易過長。所以,這里就要收尾了!
六、最后的挖掘總結
CSS計數器的斗量果然很深啊。如果不靜心思考,會陷入很多想當然的誤區。如果不全面學習,也無法感受到CSS計數器的強大潛力所在。就我自己而言,着實挖到大寶貝了。不知在座的諸位的挖掘成果如何呢?
行文匆忙,疏漏難免,若有錯誤,歡迎指正;歡迎溝通歡迎交流,更歡迎在仔細閱讀本文后對一些技術觀點發起挑戰!
參考文章
- Automatic Numbering With CSS Counters
- http://www.w3.org/TR/CSS2/generate.html#scope
- counter-reset
- counter-increment
- Using CSS counters
本文為原創文章,會經常更新知識點以及修正一些錯誤,因此轉載請保留原出處,方便溯源,避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4303
(本篇完)