CSS 列表、標記和計數器

已發表: 2022-03-10
快速總結↬ CSS 中的樣式列表比你想像的要多。 在本文中,Rachel 首先查看 CSS 中的列表,然後介紹 CSS 列表規範中定義的一些有趣的特性——標記和計數器。

CSS 中的列表具有特定的屬性,這些屬性為我們提供了我們期望的標準列表樣式。 無序列表獲得一個列表項目符號,類型為disc ,並且有序列表被編號。 我對更詳細地探索列表的興趣來自於我為 MDN 記錄::marker偽元素所做的一些工作。 這個偽元素在 Firefox 68中發布,今天發布。 有了::marker偽元素,我們就可以開始用列表做一些有趣的事情了,在本文中,我將進行更多解釋。

解構列表

儘管我們在標記中經常使用列表,但您可能沒有過多考慮列表。 許多事情可以非常合乎邏輯地標記為列表。 雖然分步說明或排序元素可以自然地由有序列表<ol>描述,但設計中的許多事物都可以使用無序列表<ul>來描述。 例如,該元素的一個非常常見的用法是標記導航,因為它是網站上的目的地列表。 對於我們的探索,讓我們首先找出 CSS 中的列表到底是什麼。

與 CSS 中的許多東西一樣,列表具有應用到它們的一些初始值。 這些值使它們看起來像一個列表。 這些特殊值以列表項具有值為list-itemdisplay屬性的信息開頭。 這將創建一個帶有附加標記框的塊級框。 標記框是添加列表項目符號或編號的位置。

跳躍後更多! 繼續往下看↓

列表很早就在 CSS 中定義,我們今天使用的列表的大部分定義都來自 CSS2。 CSS2 規範對列表項的描述如下:

“具有display: list-item的元素會為元素的內容生成一個主要塊框,並且根據list-style-typelist-style-image的值,還可能還有一個標記框作為元素的視覺指示一個列表項。”

主塊框是元素的主框,包含所有子框,因為列表項可以包含其他標記。 然後相對於該主框放置標記框。 該規范繼續詳細說明任何背景顏色將僅在此主框後面,而不是標記後面。 此外,標記可以設置為一系列預定義值之一:

  • disc
  • circle
  • square
  • decimal
  • decimal-leading-zero
  • lower-roman
  • upper-roman
  • lower-greek
  • lower-latin
  • upper-latin
  • armenian
  • georgian
  • lower-alpha
  • upper-alpha
  • none
  • inherit

3 級顯示規範定義了display: list-item以及display屬性的其他可能值。 它引用了 CSS 2.1——就像許多來自 CSS2 的 CSS 屬性和值一樣——但將list-item關鍵字描述為“導致元素生成::marker偽元素”。

3 級規範還引入了使用display: inline list-item 。 這還沒有被瀏覽器實現。

在非列表項上創建標記框

display的其他值一樣,為任何 HTML 元素提供list-item的顯示類型是完全有效的(如果您希望在項目上生成::marker偽元素)。 這不會導致元素在語義上成為列表項,而是只會在視覺上顯示為列表項,因此能夠具有::marker 。 當我們在下面討論::marker偽元素時,您會發現在某些情況下給其他元素display: list-item可能很有用。

CSS Lists Level 3 Specification: ::marker和 Counters

display規範擴展並闡明了我們在 CSS2 中找到的列表的定義,但是,還有一個規範詳細定義了列表行為:CSS 列表規範級別 3。由於列表項的基本行為在display中定義,因此規範詳細說明了當某些東西具有display: list-item時生成的標記框以及在您創建有序列表時默認使用的計數器。 通過這些功能可以訪問一些潛在有用的功能。

::marker偽元素

::marker偽元素允許您將列表標記作為目標——與列表項的內容分開。 這在以前的 CSS 版本中是不可能的,因此,如果您更改ulli的顏色或字體大小,這也會改變標記的顏色和字體大小。 為了做一些看似簡單的事情,比如擁有與文本不同的顏色列表項目符號,將涉及將列表項的內容包裝在一個跨度中(或使用圖像作為標記)。

 ul { color: #00b7a8; } ul span { color #333; }

使用::marker偽元素,您可能想嘗試的最簡單的事情是使用與文本顏色不同的項目符號,這意味著您可以使用上面示例中的代碼代替:

 ul { color: #333; } ul ::marker { color: #00b7a8; }

您可能還想為有序列表上的編號使用不同的大小和font-family

 ol ::marker { font-size: 200%; color: #00b7a8; font-family: "Comic Sans MS", cursive, sans-serif; }

您可以使用我的 CodePen 示例在支持的瀏覽器中查看所有這些內容:

請參閱 Rachel Andrew 的鋼筆 [帶和不帶標記的彩色子彈](https://codepen.io/rachelandrew/penVJQyoR)。

請參閱 Rachel Andrew 的帶有和不帶標記的鋼筆彩色子彈。

您可以在非列表項上使用::marker偽元素。 在下面的代碼中,我設置了一個要display: list-item 。 這給了它一個項目符號,因此給它一個::marker框來定位。

我已將項目符號更改為使用表情符號:

 h1 { display: list-item; } h1::marker { content: ""; } 
標題左側有一個貓表情符號
在 Firefox 中,您可以看到用作標記的表情符號。

請參閱 Rachel Andrew 的鋼筆 [標題和標記](https://codepen.io/rachelandrew/pen/wLyyMG)。

請參閱 Rachel Andrew 的鋼筆標題和標記。

在上面的示例中,我在標記的規則中使用了生成的內容。 只有一小部分 CSS 屬性可用於::marker 。 這些包括字體屬性和顏色,但是,它們還包括content屬性,用於包含生成的內容。

content添加為::marker的允許屬性是最近的,但是,它包含在 Firefox 實現中。 包含意味著您可以執行諸如在::marker中包含文本字符串之類的操作。 當您將計數器的使用與::marker結合使用時,它還為標記的格式提供了額外的可能性。

瀏覽器支持和回退

對於不支持::marker偽元素的瀏覽器,回退是無論如何都會顯示的常規標記。 不幸的是,我們目前無法使用功能查詢來檢測對選擇器的支持,例如這個偽元素,儘管已經提出了一個關於將其添加到規範中的問題。 這意味著當你得到支持時,你不能 fork 你的代碼來做一件事,如果你沒有,你就不能做別的事情。 在大多數情況下,回退到常規標記將是一個合理的解決方案。

計數器

有序列表具有列表編號——這是通過 CSS 計數器實現的。 因此,CSS 列表規範也描述了這些計數器。 我們可以自己訪問和創建計數器,結合::marker偽元素可以為我們提供一些有用的功能。 這些計數器也可以用於常規(非::marker )生成的內容。

如果我有一個編號的步驟列表(並且我想寫出“步驟 1”、“步驟 2”等),我可以通過在我的標記中使用生成的內容並附加list-item計數器來做到這一點,這代表內置計數器:

 ::marker { content: "Step " counter(list-item) ": "; } 
在每個列表項之前包含步驟 1、步驟 2 等的有序列表
在 Firefox 中,您會看到以“Step”為前綴的計數器。

請參閱 Rachel Andrew 的鋼筆 [計數器和標記](https://codepen.io/rachelandrew/pen/BgRaoz)。

請參閱 Rachel Andrew 的鋼筆計數器和記號筆。

嵌套計數器

如果您有嵌套列表,對它們進行編號的常用方法是讓頂級項目為整數 (1),然後為子項目 (1.1, 1.2) 及其子項目 (1.1.1, 1.1.2),等等。 您可以通過使用計數器的更多功能來實現這一點。

當你嵌套 HTML 列表時,你最終會得到多個同名的計數器——相互嵌套。 可以使用counters()函數訪問計數器的嵌套。

在下面的代碼中,我使用counters()來格式化我的列表標記,如上所述。 counters()的第一個參數是要使用的計數器的名稱。 我正在使用內置的list-item計數器。 第二個參數是一個字符串——這是將在輸出計數器之間連接的內容(我使用的是. )。 最後,我在 counter 函數之外但在content的值內添加了一個: ,這樣我的計數器輸出將通過冒號與內容分開。

 ::marker { content: counters(list-item,'.') ':'; color: #00b7a8; font-weight: bold; }

這給了我圖像中的輸出。 如果您使用的瀏覽器支持::marker和計數器,那麼您可以在 CodePen 示例中看到它的工作原理——嘗試將字符串從. 到其他東西看看它是如何改變輸出的。

一組嵌套列表
在 Firefox 中,您將看到由點分隔的嵌套列表編號。

請參閱 Rachel Andrew 的 Pen [嵌套計數器](https://codepen.io/rachelandrew/pen/VJbwxL)。

請參閱 Rachel Andrew 的 Pen Nested 計數器。

counter()counters()有什麼區別?

我們在第一個示例中用於寫出我們的步驟的counter()函數僅使用最裡面的計數器。 因此,在您有一組嵌套列表的情況下,您將寫出與您當前所在級別相關的計數器。

counters()函數本質上寫出了整個分支,並讓您有機會在分支中的計數器之間連接一個字符串。 因此,如果您有一個計數器為2的列表項(它是嵌套在計數器為4的列表項中的列表的一部分),則該分支包含:

  • 4
  • 2

您可以使用以下命令在標記中將其輸出為4.2

 ::marker { content: counters(list-item,'.'); }

其他元素的計數器

計數器可以用於不是列表的東西——或者輸出一個標記——在這種情況下,元素需要有display: list-item或者輸出常規生成的內容。 計數器在書籍製作中被廣泛使用,以使章節和圖形編號數量更多。 沒有理由不在網絡上採取類似的方法,特別是對於較長的文章。

CSS 列表規範中定義的處理這些計數器的 CSS 屬性是:

  • counter-set
  • counter-reset
  • counter-increment

要了解這些在列表之外是如何工作的,我們可以看一個使用計數器對文檔中的標題進行編號的示例。

我需要做的第一件事是為 body 元素上的標題創建一個計數器——準備好使用。 我正在使用counter-reset屬性來執行此操作。 counter-resetcounter-set屬性非常相似。 如果指定名稱的計數器不存在,則counter-reset屬性將創建一個新的計數器,但如果該名稱的計數器確實存在,也會創建如上所述的嵌套計數器。 如果沒有該名稱的計數器,則counter-set屬性只會創建一個新的計數器。 為此,使用任一屬性都可以正常工作,但是, counter-set的瀏覽器支持不如counter-reset ,所以我採取了實用的路線:

 body { counter-reset: heading-counter; }

現在我有了一個計數器,然後我可以在標題選擇器上使用counter-increment屬性; 這應該在每次選擇器匹配時增加計數器。

 h2 { counter-increment: heading-counter; }

要查看該值,我需要將其輸出到文檔中。 我可以通過使用生成的內容並將其添加到標題before來做到這一點,如以下 CodePen 示例所示:

 h2::before { content: counter(heading-counter) ": "; color: #00b7a8; font-weight: bold; } 

請參閱 Rachel Andrew 的 Pen [標題和計數器](https://codepen.io/rachelandrew/pen/gNGjxq)。

請參閱 Rachel Andrew 的鋼筆標題和計數器。

或者,我可以將h2元素變成一個list-item ,然後使用::marker ,如下所示。 如前所述,使用::marker元素的瀏覽器支持有限。 在 Firefox 中,您應該看到用作標題標記的計數器,而其他瀏覽器將顯示默認項目符號。

 h2 { display: list-item; } h2::marker { content: counter(heading-counter) ": "; color: #00b7a8; font-weight: bold; } 

請參閱 Rachel Andrew 的 Pen [標題、標記和計數器](https://codepen.io/rachelandrew/pen/pXWZay)。

請參閱 Rachel Andrew 的鋼筆標題、標記和計數器。

表單元素上的計數器

您還可以使用 CSS Counters 實現一些交互性——您可能認為需要 JavaScript 來完成。

我有一個包含許多必填字段的表單。 可以在 CSS 中使用:required偽類選擇所需的狀態,並且可以通過:invalid偽類檢測字段尚未完成的事實。 這意味著我們可以檢查必填和無效的字段,並增加一個計數器。 然後將其作為生成的內容輸出。

請參閱 Rachel Andrew 的 Pen [Counting required form fields](https://codepen.io/rachelandrew/pen/vqpJdM)。

請參閱 Rachel Andrew 的 Pen Counting 必填表單字段。

這實際上有多大用處是值得商榷的——考慮到除了將其粘貼到生成的內容中之外,我們無法真正使用該值做任何事情。 還有人擔心某些屏幕閱讀器無法訪問生成的內容,因此任何不僅僅是裝飾性的使用都需要確保以其他方式訪問該信息。 閱讀“CSS 生成內容的輔助功能支持”和最新信息“CSS 內容屬性屏幕閱讀器兼容性”,了解有關輔助功能和生成內容的更多詳細信息。

但是,它表明計數器可以實現比簡單編號列表更有用的事情。 也許有一天,知識確實會派上用場,以解決您正在解決的問題。

了解更多

儘管我所描述的所有內容都可以在 CSS 列表規範中找到,但這篇文章與樣式列表相去甚遠。 您可以在下面的鏈接中找到有關所描述內容的更多信息。 如果您發現 CSS 計數器的有趣用途,或者可以想到可以使用::marker的東西,請在評論中添加註釋。

  • ::marker
  • counter-set
  • counter-reset
  • counter-increment
  • “使用 CSS 計數器”,MDN 網絡文檔
  • “使用 CSS 計數器和 CSS 網格進行計數”,CSS 技巧