CSS裡的Counter

stu_wei發表於2018-10-09

counter 美 [ˈkaʊntɚ] 計數器

簡述

counter和css裡的width、color一樣是一個屬性,但是單獨使用counter是沒有效果的,就像你買了一個滑鼠,如果沒有cpu、硬碟、記憶體條……的話,這個滑鼠好像並沒有什麼用。
counter的小夥伴是

  • ::before or ::after (不熟悉的同仁可以先看看css偽類)
  • counter-reset
  • counter-increment
  • counters

本文不贅述css偽類而把重點放在counter、counters、counter-reset、counter-increment這四個屬性上,並預設讀者熟悉css偽類的用法。

應用場景

一個例子

css計數器的應用,在於,需要類似有序列表一樣的功能,但是不想(或者不能)使用有序列表的時候。實際上css計數器的功能比有序列表的功能更強大一些。 比如下面圖片裡的例子
這是描述
我們明明可以用有序列表很簡單地做出來,1分鐘都不要。但是我們為什麼要用counter?實際上,如果僅僅做成上圖的效果,確實用有序列表就夠了。
但是實際開發中,如此“簡潔”的情況還是少見的,我們可能需要為購物車裡的商品列表新增序號,或者自己做了個todoList也需要序號,而且還可以定義這個序號的樣式。
這是描述
最開始,我想,直接把序號放在html裡不就行了?但是這樣做的缺點是如果購物車刪除了某個商品,那麼被刪除的商品的序號就沒了。比如我們刪除了上圖的“餅乾”,那麼“1巧克力”下面就是“3酸奶”,這是我們不想看到的。
這是描述
當然,在js裡維護index值也是可以的,但是可以先看看counter怎麼做。

.container{
    counter-reset: abc;
}
.item::before{
    counter-increment: abc;
    content: counter(abc);
}
<div class="container">
    <div class="item">巧克力</div>
    <div class="item">餅乾</div>
    <div class="item">酸奶</div>
</div>

碼者的理解是這樣的:

  • counter-reset是初始化一個變數(本例中的abc),變數的預設值是0,可以通過下面這種形式,把abc的初始值設定為100
	counter-reset: abc 100;

這是描述

  • counter-increment表示“使(某個變數)增加”,本例中表示“使abc增加”,預設情況下,增加1,可以通過下面這種形式增加10
	counter-increment: abc 10;

這是描述

  • counter表示“獲取某個變數的值”,注意counter獲取的值只能被用作content屬性的值,也就是隻能被用在偽類裡。另外,可以通過下面這種形式,得到羅馬數字的序號。第二個引數有很多可選值。
	content: counter(abc,upper-roman);

這是描述

  • content當然可以拼接字串,不過和js裡不太一樣(不需要加號)
	content: "第"counter(abc)"個 ";

在這裡插入圖片描述

執行順序

實際上,“執行順序”這個詞並不存在,是碼者為了方便自己理解,編的一個詞。counter雖然定義在css裡,但是,執行在html裡。(還是以最上面的程式碼為例)

<div class="container">  // 在container裡,初始化了一個變數abc
    <div class="item">餅乾</div> // 在item的::before裡,使abc增加,並通過counter函式,取出abc的值,作為content的值
    <div class="item">酸奶</div> // 同上
    <div class="item">巧克力</div> // 同上
</div>

更多例子

  • 更多例子一
    這是描述
.container{
    counter-reset: abc 100;
}
.item1::before{
    counter-increment: abc 2;
    content: counter(abc);
}
.item2::before{
    counter-increment: abc -2;
    content: counter(abc);
}
.item3{ //這裡沒有::before
    counter-increment: abc 10;
}
.item4::before{
    counter-increment: abc 20;
    content: counter(abc);
}

<div class="container">
    <div class="item1">巧克力</div>
    <div class="item2">餅乾</div>
    <div class="item3">酸奶</div>
    <div class="item4">牛奶</div>
</div>

注意,class==item3時,沒有before,如果加上before就會:
這是描述
這是因為,如果不設定content,則偽元素::before就不存在,不存在的話,裡面的關於counter的東西都不起作用。同樣,如果一個元素被 display: none 或者通過dom操作刪除,裡面的counter都會失效。

  • 更多例子二(維護兩個變數)
    這是描述
.container{
    counter-reset: a 0 b 100; // 類似c語言裡的int a=0, b=100
}
.item::before{
    counter-increment: a 1 b 5;
    content: counter(a)"-"counter(b);
}

<div class="container">
    <div class="item">巧克力</div>
    <div class="item">餅乾</div>
    <div class="item">酸奶</div>
</div>
  • 更多例子三(偽巢狀)
    這是描述
.shopping-cart{
    counter-reset: a;
}
.category::before{
    counter-reset: b;
    counter-increment: a;
    content: counter(a);
}
.item::before{
    counter-increment: b;
    content: counter(a)"-"counter(b);
}

<div class="shopping-cart">
    <div class="category">
	零食
	<div class="item">巧克力</div>
	<div class="item">餅乾</div>
	<div class="item">酸奶</div>
    </div>
    <div class="category">
	蔬菜
	<div class="item">白菜</div>
	<div class="item">生菜</div>
    </div>
</div>

巢狀

本文開始的地方說介紹四個css屬性,到這裡還剩下counters沒提到,請關注下篇。

內容預告

這是描述

.container{
    counter-reset: abc;
}
.item::before{
    counter-increment: abc;
    content: counters(abc, "-");
	
    margin: 10px;
}

<div class="container">
    <div class="item">
	第一章
	<div class="container">
	    <div class="item">第一節</div>
	    <div class="item">第二節</div>
	</div>
    </div>
    <div class="item">
	第二章
	<div class="container">
	    <div class="item">第一節</div>
	    <div class="item">第二節</div>
	</div>
    </div>
    <div class="item">
	第三章
	<div class="container">
       	    <div class="item">第一節</div>
	    <div class="item">第二節</div>
	</div>
    </div>
</div>

參考連結

有問題歡迎留言一起討論

相關文章